From af3b088fa18c9782887b215d36b9d4c72873011b Mon Sep 17 00:00:00 2001 From: Jason Bedard Date: Sun, 2 Jun 2024 16:36:55 -0700 Subject: [PATCH] fix(pnpm): pnpm9 transitive npm: dependenies --- e2e/pnpm_lockfiles/MODULE.bazel | 1 + e2e/pnpm_lockfiles/README.md | 6 +- e2e/pnpm_lockfiles/WORKSPACE | 4 + e2e/pnpm_lockfiles/cases/BUILD.bazel | 11 + .../cases/isaacs-cliui-v90.yaml | 194 ++++++++++++++++++ npm/private/utils.bzl | 28 ++- 6 files changed, 234 insertions(+), 10 deletions(-) create mode 100644 e2e/pnpm_lockfiles/cases/isaacs-cliui-v90.yaml diff --git a/e2e/pnpm_lockfiles/MODULE.bazel b/e2e/pnpm_lockfiles/MODULE.bazel index c42a61e107..4f0aea76d3 100644 --- a/e2e/pnpm_lockfiles/MODULE.bazel +++ b/e2e/pnpm_lockfiles/MODULE.bazel @@ -16,6 +16,7 @@ PNPM_LOCK_VERSIONS = [ PNPM_LOCK_TEST_CASES = [ "tarball-no-url-v54.yaml", "override-with-alias-url-v9.yaml", + "isaacs-cliui-v90.yaml", ] bazel_dep(name = "aspect_bazel_lib", version = "2.7.7") diff --git a/e2e/pnpm_lockfiles/README.md b/e2e/pnpm_lockfiles/README.md index d5b4c736fa..ae40b37097 100644 --- a/e2e/pnpm_lockfiles/README.md +++ b/e2e/pnpm_lockfiles/README.md @@ -2,8 +2,12 @@ See notes in lockfile-test.bzl for test cases of each package. -## pnpm lockfile edge cases +## pnpm lockfile edge cases (./cases/\*) Unique test cases hard to cover with normal pnpm workspaces + package.json. Each test case is a pnpm-lock.yaml with a unique filename, see cases/BUILD for how the test cases run on each of those lockfiles. + +- `isaacs-cliui-v*`: a transitive `npm:` dependency as an alias to use multiple versions of a single package, this is different then a direct `npm:` dependency +- `override-with-alias-url-v9` - a package overridden with a different package +- `tarball-no-url-v54` - a package with a tarball but not a full URL diff --git a/e2e/pnpm_lockfiles/WORKSPACE b/e2e/pnpm_lockfiles/WORKSPACE index 7fdb9e1b57..7d8d35c14b 100644 --- a/e2e/pnpm_lockfiles/WORKSPACE +++ b/e2e/pnpm_lockfiles/WORKSPACE @@ -15,6 +15,7 @@ PNPM_LOCK_VERSIONS = [ PNPM_LOCK_TEST_CASES = [ "tarball-no-url-v54.yaml", "override-with-alias-url-v9.yaml", + "isaacs-cliui-v90.yaml", ] load("@aspect_rules_js//js:repositories.bzl", "rules_js_dependencies") @@ -62,9 +63,12 @@ npm_repositories_v90() for lockfile in PNPM_LOCK_TEST_CASES ] +load("@isaacs-cliui-v90//:repositories.bzl", npm_repositories_isaacs_cliui_v90 = "npm_repositories") load("@override-with-alias-url-v9//:repositories.bzl", npm_repositories_override_with_alias_v90 = "npm_repositories") load("@tarball-no-url-v54//:repositories.bzl", npm_repositories_tarball_no_url_v54 = "npm_repositories") npm_repositories_tarball_no_url_v54() npm_repositories_override_with_alias_v90() + +npm_repositories_isaacs_cliui_v90() diff --git a/e2e/pnpm_lockfiles/cases/BUILD.bazel b/e2e/pnpm_lockfiles/cases/BUILD.bazel index fa2bf3511a..4823d19b62 100644 --- a/e2e/pnpm_lockfiles/cases/BUILD.bazel +++ b/e2e/pnpm_lockfiles/cases/BUILD.bazel @@ -1,4 +1,5 @@ load("@bazel_skylib//rules:build_test.bzl", "build_test") +load("@isaacs-cliui-v90//:defs.bzl", isaacs_cliui_v90_link_all = "npm_link_all_packages") load("@override-with-alias-url-v9//:defs.bzl", override_with_alias_link_all = "npm_link_all_packages") load("@tarball-no-url-v54//:defs.bzl", tarball_no_url_link_all = "npm_link_all_packages") @@ -23,3 +24,13 @@ build_test( ":override-with-alias-url-v9_modules/lodash.pick", ], ) + +isaacs_cliui_v90_link_all(name = "isaacs_cliui_v90-modules") + +build_test( + name = "isaacs_cliui", + targets = [ + ":isaacs_cliui_v90-modules", + ":isaacs_cliui_v90-modules/@isaacs/cliui", + ], +) diff --git a/e2e/pnpm_lockfiles/cases/isaacs-cliui-v90.yaml b/e2e/pnpm_lockfiles/cases/isaacs-cliui-v90.yaml new file mode 100644 index 0000000000..85f8abc0ef --- /dev/null +++ b/e2e/pnpm_lockfiles/cases/isaacs-cliui-v90.yaml @@ -0,0 +1,194 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + .: + dependencies: + '@isaacs/cliui': + specifier: 8.0.2 + version: 8.0.2 + +packages: + '@isaacs/cliui@8.0.2': + resolution: + { + integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==, + } + engines: { node: '>=12' } + + ansi-regex@5.0.1: + resolution: + { + integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==, + } + engines: { node: '>=8' } + + ansi-regex@6.0.1: + resolution: + { + integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==, + } + engines: { node: '>=12' } + + ansi-styles@4.3.0: + resolution: + { + integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==, + } + engines: { node: '>=8' } + + ansi-styles@6.2.1: + resolution: + { + integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==, + } + engines: { node: '>=12' } + + color-convert@2.0.1: + resolution: + { + integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==, + } + engines: { node: '>=7.0.0' } + + color-name@1.1.4: + resolution: + { + integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==, + } + + eastasianwidth@0.2.0: + resolution: + { + integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==, + } + + emoji-regex@8.0.0: + resolution: + { + integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==, + } + + emoji-regex@9.2.2: + resolution: + { + integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==, + } + + is-fullwidth-code-point@3.0.0: + resolution: + { + integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==, + } + engines: { node: '>=8' } + + string-width@4.2.3: + resolution: + { + integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==, + } + engines: { node: '>=8' } + + string-width@5.1.2: + resolution: + { + integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==, + } + engines: { node: '>=12' } + + strip-ansi@6.0.1: + resolution: + { + integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==, + } + engines: { node: '>=8' } + + strip-ansi@7.1.0: + resolution: + { + integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==, + } + engines: { node: '>=12' } + + wrap-ansi@7.0.0: + resolution: + { + integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==, + } + engines: { node: '>=10' } + + wrap-ansi@8.1.0: + resolution: + { + integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==, + } + engines: { node: '>=12' } + +snapshots: + '@isaacs/cliui@8.0.2': + dependencies: + string-width: 5.1.2 + string-width-cjs: string-width@4.2.3 + strip-ansi: 7.1.0 + strip-ansi-cjs: strip-ansi@6.0.1 + wrap-ansi: 8.1.0 + wrap-ansi-cjs: wrap-ansi@7.0.0 + + ansi-regex@5.0.1: {} + + ansi-regex@6.0.1: {} + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + ansi-styles@6.2.1: {} + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.4: {} + + eastasianwidth@0.2.0: {} + + emoji-regex@8.0.0: {} + + emoji-regex@9.2.2: {} + + is-fullwidth-code-point@3.0.0: {} + + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + string-width@5.1.2: + dependencies: + eastasianwidth: 0.2.0 + emoji-regex: 9.2.2 + strip-ansi: 7.1.0 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-ansi@7.1.0: + dependencies: + ansi-regex: 6.0.1 + + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrap-ansi@8.1.0: + dependencies: + ansi-styles: 6.2.1 + string-width: 5.1.2 + strip-ansi: 7.1.0 diff --git a/npm/private/utils.bzl b/npm/private/utils.bzl index 7b881fb688..de25299f18 100644 --- a/npm/private/utils.bzl +++ b/npm/private/utils.bzl @@ -154,7 +154,7 @@ def _convert_pnpm_v5_version_peer_dep(version): def _convert_pnpm_v5_package_dependency_version(name, version): # an alias to an alternate package if version.startswith("/"): - alias, version = version[1:].rsplit("@", 1) + alias, version = version[1:].rsplit("/", 1) return "npm:{}@{}".format(alias, version) # Removing the default registry+name from the version string @@ -396,16 +396,20 @@ def _convert_v6_packages(packages): return result -def _convert_pnpm_v9_package_dependency_version(name, version): +def _convert_pnpm_v9_package_dependency_version(snapshots, name, version): + # Detect when an alias is just a direct reference to another snapshot + if version in snapshots: + return "npm:{}".format(version) + # Convert peer dependency data to rules_js ~v5 format version = _convert_pnpm_v6_v9_version_peer_dep(version) return version -def _convert_pnpm_v9_package_dependency_map(deps): +def _convert_pnpm_v9_package_dependency_map(snapshots, deps): result = {} for name, version in deps.items(): - result[name] = _convert_pnpm_v9_package_dependency_version(name, version) + result[name] = _convert_pnpm_v9_package_dependency_version(snapshots, name, version) return result def _convert_pnpm_v9_importer_dependency_map(deps): @@ -459,11 +463,17 @@ def _convert_v9_packages(packages, snapshots): # peerDependencies which *might* be resolved # # snapshots: + # pkg@http://a/url + # ... + # # '@scoped/name@2.0.0(peer@2.0.2)' # dependencies: - # a-dep@1.2.3 - # peer@2.0.2 - # b-dep@3.2.1(peer-b@4.5.6) + # a-dep: 1.2.3 + # peer: 2.0.2 + # b-dep: 3.2.1(peer-b@4.5.6) + # alias: actual@1.2.3 + # l: file:../path/to/dir + # x: https://a/url/v1.2.3.tar.gz result = {} @@ -497,8 +507,8 @@ def _convert_v9_packages(packages, snapshots): name = name, version = version, friendly_version = friendly_version, - dependencies = _convert_pnpm_v9_package_dependency_map(package_snapshot.get("dependencies", {})), - optional_dependencies = _convert_pnpm_v9_package_dependency_map(package_snapshot.get("optionalDependencies", {})), + dependencies = _convert_pnpm_v9_package_dependency_map(snapshots, package_snapshot.get("dependencies", {})), + optional_dependencies = _convert_pnpm_v9_package_dependency_map(snapshots, package_snapshot.get("optionalDependencies", {})), peer_dependencies = package_data.get("peerDependencies", {}), dev = None, # TODO(pnpm9): must inspect importers.*.devDependencies? has_bin = package_data.get("hasBin", False),