Skip to content

Commit

Permalink
add support for package-lock.json
Browse files Browse the repository at this point in the history
  • Loading branch information
VarshaUN committed Jan 15, 2025
1 parent 71453ba commit ff330fc
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 25 deletions.
51 changes: 40 additions & 11 deletions src/packagedcode/npm.py
Original file line number Diff line number Diff line change
Expand Up @@ -566,17 +566,6 @@ def _parse(cls, json_data, package_only=False):
('dist', dist_mapper),
]

hidden_lockfile = json_data.get('hiddenLockfile', False)
dependencies = json_data.get('dependencies', {})
for dep_name, dep_data in dependencies.items():
if 'version' not in dep_data:
if dep_data.get('bundled'): dep_data['type'] = 'bundled'
if 'registry' in dep_data: dep_data['type'] = 'registry'
if 'git' in dep_data: dep_data['type'] = 'git'
if 'http' in dep_data: dep_data['type'] = 'http'
if 'tarball' in dep_data: dep_data['type'] = 'tarball'
if 'link' in dep_data: dep_data['type'] = 'link'

extra_data = {}
extra_data_fields = ['workspaces', 'engines', 'packageManager']
for extra_data_field in extra_data_fields:
Expand Down Expand Up @@ -815,6 +804,46 @@ class NpmPackageLockJsonHandler(BaseNpmLockHandler):
description = 'npm package-lock.json lockfile'
documentation_url = 'https://docs.npmjs.com/cli/v8/configuring-npm/package-lock-json'

def parse(self, location):
""" Parse the package-lock.json file and handle various sources. """
with open(location) as f:
lockfile_data = json.load(f)

packages = lockfile_data.get('packages',{})
for pkg_path, pkg_data in packages.items():
self.handle_package_data(pkg_path, pkg_data)

def handle_package_data(self, pkg_path, pkg_data):
""" Handle package data, including different dependency sources."""
version = pkg_data.get('version')
if not version:
return
if version.startswith('http'):
self.handle_http_source(pkg_path, pkg_data)
elif version.startswith('git'):
self.handle_git_source(pkg_path, pkg_data)
else:
self.handle_registry_source(pkg_path, pkg_data)

def handle_http_source(self, pkg_path, pkg_data):
""" Handle HTTP tarball sources. """
logging.info(f'Handling HTTP source for {pkg_path}')

def handle_git_source(self, pkg_path, pkg_data):
""" Handle git sources. """
logging.info(f'Handling git source for {pkg_path}')

def handle_registry_source(self, pkg_path, pkg_data):
""" Handle registry sources. """
logging.info(f'Handling registry source for {pkg_path}')

logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)
if not logger.hasHandlers():
handler = logging.StreamHandler()
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)
logger.addHandler(handler)

class NpmShrinkwrapJsonHandler(BaseNpmLockHandler):
datasource_id = 'npm_shrinkwrap_json'
Expand Down
30 changes: 16 additions & 14 deletions tests/packagedcode/test_npm.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
from scancode_config import REGEN_TEST_FIXTURES
from scancode.cli_test_utils import run_scan_click
from scancode.cli_test_utils import check_json_scan

from packagedcode import NpmPackageLockJsonHandler

class TestNpm(PackageTester):
test_data_dir = os.path.join(os.path.dirname(__file__), 'data')
Expand Down Expand Up @@ -367,26 +367,28 @@ def test_npm_yarn_with_package_json_resolve_dependencies(self):
expected_file, result_file, remove_uuid=True, regen=REGEN_TEST_FIXTURES
)

@pytest.fixture
def handler():
return NpmPackageLockJsonHandler()

def test_npm_package_lock_json_parse(handler):
test_file = 'npm/package-lock-v1/package-lock.json'
expected_file = 'npm/package-lock-v1/package-lock.json-expected'
with open(test_file) as f:
sample_data = json.load(f)
handler.parse(test_file)
with open(expected_file) as f:
expected_data = json.load(f)
assert handler.packages == expected_data


def test_npm_yarn_lock_v1_parse_alias(self):
test_file = self.get_test_loc('npm/yarn-lock/v1-alias/yarn.lock')
expected_loc = self.get_test_loc(
'npm/yarn-lock/v1-alias/yarn.lock-expected')
packages = npm.YarnLockV1Handler.parse(test_file)
self.check_packages_data(packages, expected_loc, regen=REGEN_TEST_FIXTURES)

def test_parse_hidden_lockfile(self):
test_file = self.get_test_loc('npm/package-lock-latest/package-lock.json')
expected_loc = self.get_test_loc('npm/package-lock-latest/package-lock.json-expected')
packages = npm.NpmPackageLockJsonHandler.parse(test_file)
self.check_packages_data(packages, expected_loc, regen=REGEN_TEST_FIXTURES)

def test_parse_non_versions(self):
test_file = self.get_test_loc('npm/package-lock-latest/package-lock.json')
expected_loc = self.get_test_loc('npm/package-lock-latest/package-lock.json-expected')
packages = npm.NpmPackageLockJsonHandler.parse(test_file)
self.check_packages_data(packages, expected_loc, regen=REGEN_TEST_FIXTURES)


def test_is_datafile_pnpm_shrinkwrap_yaml(self):
test_file = self.get_test_loc('npm/pnpm/shrinkwrap/v3/vuepack/shrinkwrap.yaml')
assert npm.PnpmShrinkwrapYamlHandler.is_datafile(test_file)
Expand Down

0 comments on commit ff330fc

Please sign in to comment.