Skip to content

Commit f966c8f

Browse files
Add support for pnpm-lock.yaml v9
See https://github.com/pnpm/spec/blob/master/lockfile/9.0.md Signed-off-by: Ayan Sinha Mahapatra <ayansmahapatra@gmail.com>
1 parent cb7dbfe commit f966c8f

File tree

9 files changed

+3521
-7
lines changed

9 files changed

+3521
-7
lines changed

src/packagedcode/npm.py

Lines changed: 56 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1156,6 +1156,10 @@ def parse(cls, location, package_only=False):
11561156
yield models.PackageData.from_data(package_data, package_only)
11571157

11581158

1159+
class UnknownPnpmLockFormat(Exception):
1160+
pass
1161+
1162+
11591163
class BasePnpmLockHandler(BaseNpmHandler):
11601164

11611165
@classmethod
@@ -1182,31 +1186,62 @@ def parse(cls, location, package_only=False):
11821186
}
11831187
major_v, minor_v = lockfile_version.split(".")
11841188

1185-
resolved_packages = lock_data.get("packages", [])
1189+
resolved_packages = lock_data.get("packages", {})
1190+
dependency_relations = lock_data.get("snapshots", {})
1191+
dependency_relations_by_purl = {}
1192+
if dependency_relations:
1193+
for purl_fields, relations in dependency_relations.items():
1194+
clean_purl_fields = purl_fields.split("(")[0]
1195+
sections = clean_purl_fields.split("/")
1196+
namespace = None
1197+
if len(sections) == 2:
1198+
namespace, name_version = sections
1199+
elif len(sections) == 1:
1200+
name_version, = sections
1201+
name, version = name_version.split("@")
1202+
1203+
purl = PackageURL(
1204+
type=cls.default_package_type,
1205+
name=name,
1206+
namespace=namespace,
1207+
version=version,
1208+
).to_string()
1209+
dependency_relations_by_purl[purl] = relations
1210+
11861211
dependencies_by_purl = {}
11871212

11881213
for purl_fields, data in resolved_packages.items():
11891214
if major_v == "6":
11901215
clean_purl_fields = purl_fields.split("(")[0]
11911216
elif major_v == "5" or is_shrinkwrap:
11921217
clean_purl_fields = purl_fields.split("_")[0]
1193-
else:
1218+
elif major_v == "9":
11941219
clean_purl_fields = purl_fields
1195-
raise Exception(lockfile_version, purl_fields)
1220+
else:
1221+
message = f"Unknown pnpm lockfile format: {lockfile_version}"
1222+
raise UnknownPnpmLockFormat(message, purl_fields)
11961223

11971224
sections = clean_purl_fields.split("/")
1198-
name_version= None
1225+
name_version = None
1226+
namespace = None
11991227
if major_v == "6":
12001228
if len(sections) == 2:
1201-
namespace = None
12021229
_, name_version = sections
12031230
elif len(sections) == 3:
12041231
_, namespace, name_version = sections
1232+
elif len(sections) == 1:
1233+
name_version, = sections
1234+
1235+
name, version = name_version.split("@")
1236+
elif major_v == "9":
1237+
if len(sections) == 2:
1238+
namespace, name_version = sections
1239+
elif len(sections) == 1:
1240+
name_version, = sections
12051241

12061242
name, version = name_version.split("@")
12071243
elif major_v == "5" or is_shrinkwrap:
12081244
if len(sections) == 3:
1209-
namespace = None
12101245
_, name, version = sections
12111246
elif len(sections) == 4:
12121247
_, namespace, name, version = sections
@@ -1224,7 +1259,21 @@ def parse(cls, location, package_only=False):
12241259

12251260
dependencies = data.get('dependencies') or {}
12261261
optional_dependencies = data.get('optionalDependencies') or {}
1227-
transitive_peer_dependencies = data.get('transitivePeerDependencies') or {}
1262+
transitive_peer_dependencies = data.get('transitivePeerDependencies') or []
1263+
1264+
if purl in dependency_relations_by_purl:
1265+
dependency_relations = dependency_relations_by_purl.get(purl)
1266+
if dependency_relations:
1267+
deps = dependency_relations.get('dependencies')
1268+
if deps:
1269+
dependencies.update(deps)
1270+
optional_deps = dependency_relations.get('optionalDependencies')
1271+
if optional_deps:
1272+
optional_dependencies.update(optional_deps)
1273+
transitive_peer_deps = dependency_relations.get('transitivePeerDependencies')
1274+
if transitive_peer_deps:
1275+
transitive_peer_dependencies.extend(transitive_peer_deps)
1276+
12281277
peer_dependencies = data.get('peerDependencies') or {}
12291278
peer_dependencies_meta = data.get('peerDependenciesMeta') or {}
12301279

0 commit comments

Comments
 (0)