Skip to content

Commit 514e1fd

Browse files
Update is_resolved from resolved_packages
Apply updates for all npm lockfiles. Signed-off-by: Ayan Sinha Mahapatra <ayansmahapatra@gmail.com>
1 parent ccf346a commit 514e1fd

File tree

5 files changed

+82
-18
lines changed

5 files changed

+82
-18
lines changed

src/packagedcode/npm.py

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
from packagedcode.utils import normalize_vcs_url
2424
from packagedcode.utils import yield_dependencies_from_package_data
2525
from packagedcode.utils import yield_dependencies_from_package_resource
26+
from packagedcode.utils import update_dependencies_as_resolved
2627
import saneyaml
2728

2829
"""
@@ -420,8 +421,9 @@ def parse(cls, location, package_only=False):
420421
)
421422
resolved_package.dependencies = sub_deps
422423
dependency.resolved_package = resolved_package.to_dict()
423-
dependencies.append(dependency)
424+
dependencies.append(dependency.to_dict())
424425

426+
update_dependencies_as_resolved(dependencies=dependencies)
425427
root_package_data.dependencies = dependencies
426428

427429
yield root_package_data
@@ -551,8 +553,9 @@ def parse(cls, location, package_only=False):
551553
is_optional=False,
552554
is_runtime=True,
553555
)
554-
top_dependencies.append(dependency)
556+
top_dependencies.append(dependency.to_dict())
555557

558+
update_dependencies_as_resolved(dependencies=top_dependencies)
556559
package_data = dict(
557560
datasource_id=cls.datasource_id,
558561
type=cls.default_package_type,
@@ -714,8 +717,9 @@ def parse(cls, location, package_only=False):
714717
is_runtime=True,
715718
resolved_package=resolved_package_data.to_dict(),
716719
)
717-
dependencies.append(dep)
720+
dependencies.append(dep.to_dict())
718721

722+
update_dependencies_as_resolved(dependencies=dependencies)
719723
package_data = dict(
720724
datasource_id=cls.datasource_id,
721725
type=cls.default_package_type,
@@ -811,7 +815,11 @@ def parse(cls, location, package_only=False):
811815
)
812816
dependencies_by_purl[purl] = dependency_data
813817

814-
dependencies = list(dependencies_by_purl.values())
818+
dependencies = [
819+
dep.to_dict()
820+
for dep in list(dependencies_by_purl.values())
821+
]
822+
update_dependencies_as_resolved(dependencies=dependencies)
815823
root_package_data = dict(
816824
datasource_id=cls.datasource_id,
817825
type=cls.default_package_type,

src/packagedcode/utils.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
# See https://aboutcode.org for more information about nexB OSS projects.
88
#
99

10+
from packageurl import PackageURL
11+
1012
try:
1113
from license_expression import Licensing
1214
from license_expression import combine_expressions as le_combine_expressions
@@ -215,3 +217,57 @@ def yield_dependencies_from_package_resource(resource, package_uid=None):
215217
for pkg_data in resource.package_data:
216218
pkg_data = models.PackageData.from_dict(pkg_data)
217219
yield from yield_dependencies_from_package_data(pkg_data, resource.path, package_uid)
220+
221+
222+
def update_dependencies_as_resolved(dependencies):
223+
"""
224+
For a list of dependency mappings with their respective
225+
resolved packages, update in place the dependencies for those
226+
resolved packages as resolved (update `is_resolved` as True),
227+
if the requirement is also present as a resolved package.
228+
"""
229+
#TODO: Use vers to mark update `is_resolved` even in the case
230+
# of incomplete resolution/partially pinned dependencies
231+
232+
# These are only type, namespace and name (without version and qualifiers)
233+
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)
243+
244+
# No resolved packages are present for dependencies
245+
if not resolved_packages:
246+
return
247+
248+
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+
)
258+
259+
for dependency in dependencies:
260+
resolved_package = dependency.get("resolved_package")
261+
dependencies_from_resolved = []
262+
if resolved_package:
263+
dependencies_from_resolved = resolved_package.get("dependencies")
264+
265+
if not dependencies_from_resolved:
266+
continue
267+
268+
for dep in dependencies_from_resolved:
269+
dep_purl = dep.get("purl")
270+
if dep_purl in base_resolved_purls:
271+
dep["is_resolved"] = True
272+
273+

tests/packagedcode/data/npm/package-lock-v1/package-lock.json-expected

Lines changed: 5 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/packagedcode/data/npm/yarn-lock/v1-complex2/yarn.lock-expected

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -625,7 +625,7 @@
625625
"scope": "dependencies",
626626
"is_runtime": true,
627627
"is_optional": false,
628-
"is_resolved": false,
628+
"is_resolved": true,
629629
"resolved_package": {},
630630
"extra_data": {}
631631
}
@@ -707,7 +707,7 @@
707707
"scope": "dependencies",
708708
"is_runtime": true,
709709
"is_optional": false,
710-
"is_resolved": false,
710+
"is_resolved": true,
711711
"resolved_package": {},
712712
"extra_data": {}
713713
}
@@ -893,7 +893,7 @@
893893
"scope": "dependencies",
894894
"is_runtime": true,
895895
"is_optional": false,
896-
"is_resolved": false,
896+
"is_resolved": true,
897897
"resolved_package": {},
898898
"extra_data": {}
899899
},
@@ -903,7 +903,7 @@
903903
"scope": "dependencies",
904904
"is_runtime": true,
905905
"is_optional": false,
906-
"is_resolved": false,
906+
"is_resolved": true,
907907
"resolved_package": {},
908908
"extra_data": {}
909909
},
@@ -913,7 +913,7 @@
913913
"scope": "dependencies",
914914
"is_runtime": true,
915915
"is_optional": false,
916-
"is_resolved": false,
916+
"is_resolved": true,
917917
"resolved_package": {},
918918
"extra_data": {}
919919
}
@@ -975,7 +975,7 @@
975975
"scope": "dependencies",
976976
"is_runtime": true,
977977
"is_optional": false,
978-
"is_resolved": false,
978+
"is_resolved": true,
979979
"resolved_package": {},
980980
"extra_data": {}
981981
},
@@ -985,7 +985,7 @@
985985
"scope": "dependencies",
986986
"is_runtime": true,
987987
"is_optional": false,
988-
"is_resolved": false,
988+
"is_resolved": true,
989989
"resolved_package": {},
990990
"extra_data": {}
991991
},
@@ -995,7 +995,7 @@
995995
"scope": "dependencies",
996996
"is_runtime": true,
997997
"is_optional": false,
998-
"is_resolved": false,
998+
"is_resolved": true,
999999
"resolved_package": {},
10001000
"extra_data": {}
10011001
}

tests/packagedcode/data/npm/yarn-lock/v1/yarn.lock-expected

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -475,7 +475,7 @@
475475
"scope": "dependencies",
476476
"is_runtime": true,
477477
"is_optional": false,
478-
"is_resolved": false,
478+
"is_resolved": true,
479479
"resolved_package": {},
480480
"extra_data": {}
481481
}

0 commit comments

Comments
 (0)