Skip to content

Commit f74a89b

Browse files
Address feedback and comments
Signed-off-by: Ayan Sinha Mahapatra <ayansmahapatra@gmail.com>
1 parent ce8e0d1 commit f74a89b

File tree

3 files changed

+59
-36
lines changed

3 files changed

+59
-36
lines changed

src/packagedcode/models.py

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -374,10 +374,11 @@ class DependentPackage(ModelMixin):
374374
is_direct = Boolean(
375375
default=True,
376376
label='is direct flag',
377-
help='True if this dependency version requirement is '
378-
'a direct dependency relation between two packages '
379-
'as opposed to a transitive dependency relation, '
380-
'which are present in lockfiles/dependency list.')
377+
help='True if this is a direct, first-level dependency, '
378+
'defined in the manifest of a package. False if this '
379+
'is an indirect, transitive dependency resolved from '
380+
'first level dependencies.'
381+
)
381382

382383
resolved_package = Mapping(
383384
label='resolved package data',
@@ -692,18 +693,20 @@ class PackageData(IdentifiablePackageData):
692693

693694
is_private = Boolean(
694695
default=False,
695-
label='is resolved flag',
696-
help='True if the associated package for this package manifest '
697-
'is never meant to be published to the corresponding package '
698-
'repository, and is a private package.'
696+
label='is private flag',
697+
help='True if this is a private package, either not meant to be '
698+
'published on a repository, and/or a local package without a '
699+
'name and version used primarily to track dependencies and '
700+
'other information, and build this package, for instance with '
701+
'JavaScript and PHP applications.'
699702
)
700703

701704
is_virtual = Boolean(
702705
default=False,
703706
label='is virtual flag',
704-
help='True if this package or any of its files are not present in '
705-
'the codebase, but this package was created from a resolved '
706-
'package, typically present in a lockfile.'
707+
help='True if this package is created only from a manifest or lockfile, '
708+
'and not from its actual packaged code. The files of this package '
709+
'are not present in the codebase.'
707710
)
708711

709712
extra_data = Mapping(

src/packagedcode/npm.py

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
from packagedcode.utils import yield_dependencies_from_package_data
2626
from packagedcode.utils import yield_dependencies_from_package_resource
2727
from packagedcode.utils import update_dependencies_as_resolved
28+
from packagedcode.utils import is_path_pattern
29+
from packagedcode.utils import is_simple_path_pattern
2830
import saneyaml
2931

3032
"""
@@ -299,8 +301,7 @@ def get_workspace_members(cls, workspaces, codebase, workspace_root_path):
299301
for workspace_path in workspaces:
300302

301303
# Case 1: A definite path, instead of a pattern (only one package.json)
302-
if '*' not in workspace_path:
303-
304+
if is_path_pattern(workspace_path):
304305
workspace_dir_path = os.path.join(workspace_root_path, workspace_path)
305306
workspace_member_path = os.path.join(workspace_dir_path, 'package.json')
306307
workspace_member = codebase.get_resource(path=workspace_member_path)
@@ -310,8 +311,8 @@ def get_workspace_members(cls, workspaces, codebase, workspace_root_path):
310311
# Case 2: we have glob path which is a directory, relative to the workspace root
311312
# Here we have only one * at the last (This is an optimization, this is a very
312313
# commonly encountered subcase of case 3)
313-
elif '*' == workspace_path[-1] and '*' not in workspace_path.replace('*', ''):
314-
workspace_pattern_prefix = workspace_path.replace('*', '')
314+
elif is_simple_path_pattern(workspace_path):
315+
workspace_pattern_prefix = workspace_path.rstrip('*')
315316
workspace_dir_path = os.path.join(workspace_root_path, workspace_pattern_prefix)
316317
workspace_search_dir = codebase.get_resource(path=workspace_dir_path)
317318
if not workspace_search_dir:
@@ -785,7 +786,8 @@ def parse(cls, location, package_only=False):
785786
version=version,
786787
)
787788

788-
# TODO: what type of checksum is this?
789+
# TODO: what type of checksum is this? ... this is a complex one
790+
# See https://github.com/yarnpkg/berry/blob/f1edfae49d1bab7679ce3061e2749113dc3b80e8/packages/yarnpkg-core/sources/tgzUtils.ts
789791
checksum = details.get('checksum')
790792
dependencies = details.get('dependencies') or {}
791793
peer_dependencies = details.get('peerDependencies') or {}
@@ -826,12 +828,16 @@ def parse(cls, location, package_only=False):
826828
is_virtual=True,
827829
)
828830
resolved_package = models.PackageData.from_data(resolved_package_mapping)
831+
832+
# These are top level dependencies which do not have a
833+
# scope defined there, so we are assigning the default
834+
# scope, this would be merged with the dependency having
835+
# correct scope value when resolved
829836
dependency = models.DependentPackage(
830837
purl=str(purl),
831838
extracted_requirement=version,
832839
is_resolved=True,
833840
resolved_package=resolved_package.to_dict(),
834-
# FIXME: these are NOT correct
835841
scope='dependencies',
836842
is_optional=False,
837843
is_runtime=True,
@@ -1008,7 +1014,8 @@ def parse(cls, location, package_only=False):
10081014
if not dep_purl in dependencies_by_purl:
10091015
dependencies_by_purl[dep_purl] = dep.to_dict()
10101016
else:
1011-
# We have duplicate dependencies because of aliases
1017+
# FIXME: We have duplicate dependencies because of aliases
1018+
# should we do something?
10121019
pass
10131020

10141021
dependencies = list(dependencies_by_purl.values())

src/packagedcode/utils.py

Lines changed: 31 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -231,30 +231,22 @@ def update_dependencies_as_resolved(dependencies):
231231

232232
# These are only type, namespace and name (without version and qualifiers)
233233
base_resolved_purls = []
234-
base_purl_fields = ["type", "namespace", "name"]
235-
try:
236-
resolved_packages = [
237-
dep.get("resolved_package")
238-
for dep in dependencies
239-
if dep.get("resolved_package")
240-
]
241-
except AttributeError:
242-
raise Exception(dependencies)
234+
resolved_packages = [
235+
dep.get("resolved_package")
236+
for dep in dependencies
237+
if dep.get("resolved_package")
238+
]
243239

244240
# No resolved packages are present for dependencies
245241
if not resolved_packages:
246242
return
247243

248244
for pkg in resolved_packages:
249-
purl_mapping = PackageURL.from_string(purl=pkg.get("purl")).to_dict()
250-
base_purl_mapping = {
251-
purl_field: purl_value
252-
for purl_field, purl_value in purl_mapping.items()
253-
if purl_field in base_purl_fields
254-
}
255-
base_resolved_purls.append(
256-
PackageURL(**base_purl_mapping).to_string()
257-
)
245+
purl=pkg.get("purl")
246+
if purl:
247+
base_resolved_purls.append(
248+
get_base_purl(purl=purl)
249+
)
258250

259251
for dependency in dependencies:
260252
resolved_package = dependency.get("resolved_package")
@@ -271,3 +263,24 @@ def update_dependencies_as_resolved(dependencies):
271263
dep["is_resolved"] = True
272264

273265

266+
def get_base_purl(purl):
267+
"""
268+
Get a base purl with only the type, name and namespace from
269+
a given purl.
270+
"""
271+
base_purl_fields = ["type", "namespace", "name"]
272+
purl_mapping = PackageURL.from_string(purl=purl).to_dict()
273+
base_purl_mapping = {
274+
purl_field: purl_value
275+
for purl_field, purl_value in purl_mapping.items()
276+
if purl_field in base_purl_fields
277+
}
278+
return PackageURL(**base_purl_mapping).to_string()
279+
280+
281+
def is_path_pattern(path):
282+
return '*' not in path
283+
284+
285+
def is_simple_path_pattern(path):
286+
return path.endswith('*') and path.count('*') == 1

0 commit comments

Comments
 (0)