From 688009a1206a5b184b032f3ee820f06c5cd1383f Mon Sep 17 00:00:00 2001 From: mele Date: Thu, 26 Sep 2024 14:19:12 +1000 Subject: [PATCH 1/3] Match v6 lockfile behaviour in v9 around injected deps - Adds `.git` to `.bazelignore` (editors see `.git` when inspecting test logs otherwise) - Fixed typo `file` -> `find` in `npm/private/npm_translate_lock_generate.bzl` - Documented params for `_new_package_info` in `npm/private/pnpm.bzl` - Documented and tested `_convert_pnpm_v6_v9_version_peer_dep` in `npm/private/pnpm.bzl` - `.strip` over `.(r|l)strip` in `npm/private/pnpm.bzl` - Added tests for v6 and v9 lockfiles covering current behaviour around injected deps (unsupported feature that is non-fatal when used in v6 and now v9) - Remove inlined JSON in favour of Starlark + `json.encode` in `npm/private/test/parse_pnpm_lock_tests.bzl` - Added test suite target for `//npm/private/test:test_parse_pnpm_lock` --- .bazelignore | 1 + npm/private/npm_translate_lock_generate.bzl | 2 +- npm/private/pnpm.bzl | 65 ++- npm/private/test/parse_pnpm_lock_tests.bzl | 440 ++++++++++++++++---- 4 files changed, 403 insertions(+), 105 deletions(-) diff --git a/.bazelignore b/.bazelignore index 312414601..42184d191 100644 --- a/.bazelignore +++ b/.bazelignore @@ -22,3 +22,4 @@ node_modules/ npm/private/test/node_modules/ npm/private/test/npm_package/node_modules/ npm/private/test/npm_package_publish/node_modules +.git diff --git a/npm/private/npm_translate_lock_generate.bzl b/npm/private/npm_translate_lock_generate.bzl index b85445ae1..49ea7f74e 100644 --- a/npm/private/npm_translate_lock_generate.bzl +++ b/npm/private/npm_translate_lock_generate.bzl @@ -166,7 +166,7 @@ sh_binary( dep_path = helpers.link_package(root_package, dep_version[len("file:"):]) dep_key = "{}+{}".format(dep_package, dep_version) if not dep_key in fp_links.keys(): - msg = "Expected to file: referenced package {} in first-party links".format(dep_key) + msg = "Expected to find: referenced package {} in first-party links".format(dep_key) fail(msg) fp_links[dep_key]["link_packages"][link_package] = [] elif dep_version.startswith("link:"): diff --git a/npm/private/pnpm.bzl b/npm/private/pnpm.bzl index 86f352619..84e6f91d2 100644 --- a/npm/private/pnpm.bzl +++ b/npm/private/pnpm.bzl @@ -28,11 +28,33 @@ def _new_import_info(dependencies, dev_dependencies, optional_dependencies): "optional_dependencies": optional_dependencies, } -# Metadata about a package. -# -# Metadata may come from different locations depending on the lockfile, this struct should -# have data normalized across lockfiles. def _new_package_info(id, name, dependencies, optional_dependencies, dev, has_bin, optional, requires_build, version, friendly_version, resolution): + """ + Metadata about a package. + + Metadata may come from different locations depending on the lockfile, this struct should + have data normalized across lockfiles. + + Args: + id: The package id, if present. + TODO Remove. Used for to resolve path of local packages, however `resolution` is a better source of truth. + name: The package name. + dependencies: A map of package dependencies. + optional_dependencies: A map of optional package dependencies. + dev: True if the package is a dev dependency, None otherwise. + has_bin: True if the package has a bin field. + optional: True if the package is an optional dependency. + Determines if package should be omitted `no_optional = True` specified. + requires_build: True if the package requires a build. + NOTE: With pnpm v9, this cannot be known ahead of time. + version: The resolved package version. + e.g. `file:packages/a`, `1.2.3`, `1.2.3_at_scope_peer_2.0.2`. + friendly_version: The package version, normalized for users. Used to target patches, etc. + e.g. `file:packages/a`, `1.2.3`. + resolution: The package resolution. + e.g. { integrity: "..." } + e.g. { type: "directory", directory: "packages/a" } + """ return { "id": id, "name": name, @@ -218,20 +240,21 @@ def _convert_pnpm_v6_v9_version_peer_dep(version): # with rules_js. # # Examples: - # 1.2.3 - # 1.2.3(@scope/peer@2.0.2)(@scope/peer@4.5.6) - # 4.5.6(patch_hash=o3deharooos255qt5xdujc3cuq) + # 1.2.3 -> 1.2.3 + # 1.2.3(@scope/peer@2.0.2) -> 1.2.3_at_scope_peer_2.0.2 + # 1.2.3(@scope/peer@2.0.2)(@scope/peer@4.5.6) -> 1.2.3_2001974805 + # 4.5.6(patch_hash=o3deharooos255qt5xdujc3cuq) -> 4.5.6_o3deharooos255qt5xdujc3cuq if version[-1] == ")": # Drop the patch_hash= not present in v5 so (patch_hash=123) -> (123) like v5 version = version.replace("(patch_hash=", "(") - # There is a peer dep if the string ends with ")" + # There is a peer dep (or patch) if the string ends with ")" peer_dep_index = version.find("(") peer_dep = version[peer_dep_index:] if len(peer_dep) > 32: # Prevent long paths. The pnpm lockfile v6 no longer hashes long sequences of # peer deps so we must hash here to prevent extremely long file paths that lead to - # "File name too long) build failures. + # "File name too long" build failures. peer_dep = utils.hash(peer_dep) else: peer_dep = peer_dep.replace("(@", "(_at_").replace(")(", "_").replace("@", "_").replace("/", "_") @@ -485,8 +508,18 @@ def _convert_v9_packages(packages, snapshots): # package_data can have the resolved "version" for things like https:// deps friendly_version = package_data["version"] if "version" in package_data else static_key[version_index + 1:] + package_id = package_snapshot.get("id", None) + # match v6 lockfile behaviour with id + if package_id != None and "file:" in package_id: + # Remove package name from id + package_id = package_id[len(name) + 1:] + # ensure local packages always have an id, so that peer dependencies don't cause issues + if package_id == None and "file:" in package_key: + resolution = package_data.get("resolution") + package_id = "file:" + resolution["directory"] + package_info = _new_package_info( - id = package_data.get("id", None), # TODO: does v9 have "id"? + id = package_id, name = name, version = version, friendly_version = friendly_version, @@ -499,6 +532,11 @@ def _convert_v9_packages(packages, snapshots): resolution = package_data.get("resolution"), ) + # Match v6 lockfile behaviour with local dependency keys + if "file:" in package_key: + # Remove package name from key + package_key = package_key[len(name) + 1:] + if package_key in result: msg = "ERROR: duplicate package: {}\n\t{}\n\t{}".format(package_key, result[package_key], package_info) fail(msg) @@ -540,10 +578,8 @@ def _parse_lockfile(parsed, err): # Lockfile version may be a float such as 5.4 or a string such as '6.0' lockfile_version = str(parsed["lockfileVersion"]) - lockfile_version = lockfile_version.lstrip("'") - lockfile_version = lockfile_version.rstrip("'") - lockfile_version = lockfile_version.lstrip("\"") - lockfile_version = lockfile_version.rstrip("\"") + lockfile_version = lockfile_version.strip("'") + lockfile_version = lockfile_version.strip("\"") lockfile_version = float(lockfile_version) _assert_lockfile_version(lockfile_version) @@ -603,4 +639,5 @@ pnpm = struct( # Exported only to be tested pnpm_test = struct( strip_v5_peer_dep_or_patched_version = _strip_v5_peer_dep_or_patched_version, + convert_pnpm_v6_v9_version_peer_dep = _convert_pnpm_v6_v9_version_peer_dep, ) diff --git a/npm/private/test/parse_pnpm_lock_tests.bzl b/npm/private/test/parse_pnpm_lock_tests.bzl index a24bab5b7..afd366476 100644 --- a/npm/private/test/parse_pnpm_lock_tests.bzl +++ b/npm/private/test/parse_pnpm_lock_tests.bzl @@ -46,34 +46,92 @@ expected_packages = { }, } +expected_imports_injected = { + ".": { + "dependencies": {}, + "dev_dependencies": {}, + "optional_dependencies": {}, + }, + "packages/a": { + "dependencies": { + "b": "file:packages/b_typescript_5.6.2", + }, + "dev_dependencies": {}, + "optional_dependencies": {}, + }, + "packages/b": { + "dependencies": { + "typescript": "5.6.2", + }, + "dev_dependencies": {}, + "optional_dependencies": {}, + }, +} +expected_packages_injected = { + "file:packages/b_typescript_5.6.2": { + "id": "file:packages/b", + "name": "b", + "dependencies": { + "typescript": "5.6.2", + }, + "optional_dependencies": {}, + "dev": False, + "has_bin": False, + "optional": False, + "requires_build": False, + "version": "file:packages/b_typescript_5.6.2", + "friendly_version": "file:packages/b_typescript_5.6.2", + "resolution": { + "directory": "packages/b", + "type": "directory", + }, + }, + "typescript@5.6.2": { + "id": None, + "name": "typescript", + "dependencies": {}, + "optional_dependencies": {}, + "dev": False, + "has_bin": True, + "optional": False, + "requires_build": False, + "version": "5.6.2", + "friendly_version": "5.6.2", + "resolution": { + "integrity": "sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw==", + }, + }, +} + +# Example: https://github.com/pnpm/pnpm/blob/0672517f694da62dff7c33b9e723fbfb036eaefa/pnpm-lock.yaml def _parse_lockfile_v5_test_impl(ctx): env = unittest.begin(ctx) - parsed_json = pnpm.parse_pnpm_lock_json("""\ -{ - "lockfileVersion": 5.4, - "specifiers": { - "@aspect-test/a": "5.0.0" - }, - "dependencies": { - "@aspect-test/a": "5.0.0" - }, - "packages": { - "/@aspect-test/a/5.0.0": { - "resolution": { - "integrity": "sha512-t/lwpVXG/jmxTotGEsmjwuihC2Lvz/Iqt63o78SI3O5XallxtFp5j2WM2M6HwkFiii9I42KdlAF8B3plZMz0Fw==" - }, - "hasBin": true, - "dependencies": { - "@aspect-test/b": "5.0.0", - "@aspect-test/c": "1.0.0", - "@aspect-test/d": "2.0.0_@aspect-test+c@1.0.0" - }, - "dev": false - } - } -} -""") + parsed_json = pnpm.parse_pnpm_lock_json(json.encode({ + "lockfileVersion": 5.4, + "specifiers": { + "@aspect-test/a": "5.0.0", + }, + "dependencies": { + "@aspect-test/a": "5.0.0", + }, + "packages": { + "/@aspect-test/a/5.0.0": { + "resolution": { + "integrity": "sha512-t/lwpVXG/jmxTotGEsmjwuihC2Lvz/Iqt63o78SI3O5XallxtFp5j2WM2M6HwkFiii9I42KdlAF8B3plZMz0Fw==", + }, + "hasBin": True, + "dependencies": { + # TODO Test data defect, all listed dependencies must have a definition + "@aspect-test/b": "5.0.0", + "@aspect-test/c": "1.0.0", + # Package has 1 peer dependency (`@aspect-test/c`), in v5 packages with more than 1 use a hash instead + "@aspect-test/d": "2.0.0_@aspect-test+c@1.0.0", + }, + "dev": False, + }, + }, + })) expected = ( expected_importers, @@ -90,31 +148,32 @@ def _parse_lockfile_v5_test_impl(ctx): def _parse_lockfile_v6_test_impl(ctx): env = unittest.begin(ctx) - parsed_json = pnpm.parse_pnpm_lock_json("""\ -{ - "lockfileVersion": "6.0", - "dependencies": { - "@aspect-test/a": { - "specifier": "5.0.0", - "version": "5.0.0" - } - }, - "packages": { - "/@aspect-test/a@5.0.0": { - "resolution": { - "integrity": "sha512-t/lwpVXG/jmxTotGEsmjwuihC2Lvz/Iqt63o78SI3O5XallxtFp5j2WM2M6HwkFiii9I42KdlAF8B3plZMz0Fw==" - }, - "hasBin": true, - "dependencies": { - "@aspect-test/b": "5.0.0", - "@aspect-test/c": "1.0.0", - "@aspect-test/d": "2.0.0(@aspect-test/c@1.0.0)" - }, - "dev": false - } - } -} -""") + parsed_json = pnpm.parse_pnpm_lock_json(json.encode({ + "lockfileVersion": "6.0", + "dependencies": { + "@aspect-test/a": { + "specifier": "5.0.0", + "version": "5.0.0", + } + }, + "packages": { + "/@aspect-test/a@5.0.0": { + "resolution": { + "integrity": "sha512-t/lwpVXG/jmxTotGEsmjwuihC2Lvz/Iqt63o78SI3O5XallxtFp5j2WM2M6HwkFiii9I42KdlAF8B3plZMz0Fw==", + }, + "hasBin": True, + "dependencies": { + # TODO Test data defect, all listed dependencies must have a definition + "@aspect-test/b": "5.0.0", + "@aspect-test/c": "1.0.0", + # Package has 1 peer dependency (`@aspect-test/c`), packages with several peer dependencies may be given a hash (to satisfy Windows path length limits) + # `npm_translate_lock` will likewise replace the peer dependency component with a hash if too long. + "@aspect-test/d": "2.0.0(@aspect-test/c@1.0.0)", + }, + "dev": False + }, + }, + })) expected = ( expected_importers, @@ -128,51 +187,127 @@ def _parse_lockfile_v6_test_impl(ctx): return unittest.end(env) -def _parse_lockfile_v9_test_impl(ctx): +def _parse_lockfile_v6_local_injected_test_impl(ctx): env = unittest.begin(ctx) - parsed_json = pnpm.parse_pnpm_lock_json("""\ -{ - "lockfileVersion": "9.0", - "settings": { - "autoInstallPeers": true, - "excludeLinksFromLockfile": false - }, - "importers": { - ".": { - "dependencies": { - "@aspect-test/a": { - "specifier": "5.0.0", - "version": "5.0.0" + parsed_json = pnpm.parse_pnpm_lock_json(json.encode({ + "lockfileVersion": "6.0", + "settings": { + "autoInstallPeers": True, + "excludeLinksFromLockfile": False + }, + "importers": { + ".": {}, + "packages/a": { + "dependencies": { + "b": { + "specifier": "workspace:*", + "version": "file:packages/b(typescript@5.6.2)" + } + }, + "dependenciesMeta": { + "b": { + "injected": True + } + } + }, + "packages/b": { + "dependencies": { + "typescript": { + "specifier": "^5.6.2", + "version": "5.6.2" + } + } + } + }, + "packages": { + "/typescript@5.6.2": { + "resolution": { + "integrity": "sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw==" + }, + "engines": { + "node": ">=14.17" + }, + "hasBin": True, + "dev": False + }, + "file:packages/b(typescript@5.6.2)": { + "resolution": { + "directory": "packages/b", + "type": "directory" + }, + "id": "file:packages/b", + "name": "b", + "peerDependencies": { + "typescript": "^5.6.2" + }, + "dependencies": { + "typescript": "5.6.2" + }, + "dev": False + } } - } - } - }, - "packages": { - "@aspect-test/a@5.0.0": { - "resolution": { - "integrity": "sha512-t/lwpVXG/jmxTotGEsmjwuihC2Lvz/Iqt63o78SI3O5XallxtFp5j2WM2M6HwkFiii9I42KdlAF8B3plZMz0Fw==" - }, - "hasBin": true - } - }, - "snapshots": { - "@aspect-test/a@5.0.0": { - "dependencies": { - "@aspect-test/b": "5.0.0", - "@aspect-test/c": "1.0.0", - "@aspect-test/d": "2.0.0(@aspect-test/c@1.0.0)" - } - } - } -} -""") + })) + + expected = ( + expected_imports_injected, + expected_packages_injected, + {}, + 6.0, + None + ) + + asserts.equals(env, expected, parsed_json) + + return unittest.end(env) + +def _parse_lockfile_v9_test_impl(ctx): + env = unittest.begin(ctx) + + parsed_json = pnpm.parse_pnpm_lock_json(json.encode({ + "lockfileVersion": "9.0", + "settings": { + "autoInstallPeers": True, + "excludeLinksFromLockfile": False, + }, + "importers": { + ".": { + "dependencies": { + "@aspect-test/a": { + "specifier": "5.0.0", + "version": "5.0.0", + }, + }, + }, + }, + "packages": { + "@aspect-test/a@5.0.0": { + "resolution": { + "integrity": "sha512-t/lwpVXG/jmxTotGEsmjwuihC2Lvz/Iqt63o78SI3O5XallxtFp5j2WM2M6HwkFiii9I42KdlAF8B3plZMz0Fw==", + }, + "hasBin": True, + }, + }, + "snapshots": { + "@aspect-test/a@5.0.0": { + "dependencies": { + # TODO Test data defect, all listed dependencies must have a definition + "@aspect-test/b": "5.0.0", + "@aspect-test/c": "1.0.0", + # Package has 1 peer dependency (`@aspect-test/c`), packages with several peer dependencies may be given a hash (to satisfy Windows path length limits) + # `npm_translate_lock` will likewise replace the peer dependency component with a hash if too long. + "@aspect-test/d": "2.0.0(@aspect-test/c@1.0.0)", + }, + }, + }, + })) # NOTE: unknown properties in >=v9 v9_expected_packages = dict(expected_packages) - v9_expected_packages["@aspect-test/a@5.0.0"] = dict(v9_expected_packages["@aspect-test/a@5.0.0"]) - v9_expected_packages["@aspect-test/a@5.0.0"]["dev"] = None - v9_expected_packages["@aspect-test/a@5.0.0"]["requires_build"] = None + for pkg_name in v9_expected_packages.keys(): + v9_expected_packages[pkg_name] = dict(v9_expected_packages[pkg_name]) + v9_expected_packages[pkg_name]["dev"] = None + v9_expected_packages[pkg_name]["requires_build"] = None expected = ( expected_importers, @@ -186,6 +321,94 @@ def _parse_lockfile_v9_test_impl(ctx): return unittest.end(env) +def _parse_lockfile_v9_injected_local_test_impl(ctx): + env = unittest.begin(ctx) + + parsed_json = pnpm.parse_pnpm_lock_json(json.encode({ + "lockfileVersion": "9.0", + "settings": { + "autoInstallPeers": True, + "excludeLinksFromLockfile": False, + }, + "importers": { + ".": {}, + "packages/a": { + "dependencies": { + "b": { + "specifier": "workspace:*", + "version": "file:packages/b(typescript@5.6.2)", + }, + }, + "dependenciesMeta": { + "b": { + "injected": True, + }, + }, + }, + "packages/b": { + "dependencies": { + "typescript": { + "specifier": "^5.6.2", + "version": "5.6.2", + }, + }, + }, + }, + "packages": { + "b@file:packages/b": { + "resolution": { + "directory": "packages/b", + "type": "directory", + }, + "name": "b", + "peerDependencies": { + "typescript": "^5.6.2", + }, + }, + "typescript@5.6.2": { + "resolution": { + "integrity": "sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw==", + }, + "engines": { + "node": ">=14.17", + }, + "hasBin": True, + }, + }, + "snapshots": { + "b@file:packages/b(typescript@5.6.2)": { + "id": "b@file:packages/b", + "dependencies": { + "typescript": "5.6.2", + } + }, + "typescript@5.6.2": {}, + }, + })) + + # NOTE: unknown properties in >=v9 + v9_expected_packages = dict(expected_packages_injected) + for pkg_name in v9_expected_packages.keys(): + v9_expected_packages[pkg_name] = dict(v9_expected_packages[pkg_name]) + v9_expected_packages[pkg_name]["dev"] = None + v9_expected_packages[pkg_name]["requires_build"] = None + if pkg_name == "file:packages/b_typescript_5.6.2": + # This is incorrect in v6, but correct in v9 + # v6 is used as reference so we override for v9 here + v9_expected_packages[pkg_name]["friendly_version"] = "file:packages/b" + + expected = ( + expected_imports_injected, + v9_expected_packages, + {}, + 9.0, + None + ) + + asserts.equals(env, expected, parsed_json) + + return unittest.end(env) + # buildifier: disable=function-docstring def _test_strip_peer_dep_or_patched_version(ctx): env = unittest.begin(ctx) @@ -198,6 +421,30 @@ def _test_strip_peer_dep_or_patched_version(ctx): asserts.equals(env, "21.1.0", pnpm_test.strip_v5_peer_dep_or_patched_version("21.1.0")) return unittest.end(env) +def _test_convert_pnpm_v6_v9_version_peer_dep(ctx): + env = unittest.begin(ctx) + asserts.equals( + env, + "1.2.3", + pnpm_test.convert_pnpm_v6_v9_version_peer_dep("1.2.3"), + ) + asserts.equals( + env, + "1.2.3_at_scope_peer_2.0.2", + pnpm_test.convert_pnpm_v6_v9_version_peer_dep("1.2.3(@scope/peer@2.0.2)"), + ) + asserts.equals( + env, + "1.2.3_2001974805", + pnpm_test.convert_pnpm_v6_v9_version_peer_dep("1.2.3(@scope/peer@2.0.2)(@scope/peer@4.5.6)"), + ) + asserts.equals( + env, + "4.5.6_o3deharooos255qt5xdujc3cuq", + pnpm_test.convert_pnpm_v6_v9_version_peer_dep("4.5.6(patch_hash=o3deharooos255qt5xdujc3cuq)"), + ) + return unittest.end(env) + # buildifier: disable=function-docstring def _test_version_supported(ctx): env = unittest.begin(ctx) @@ -224,6 +471,9 @@ c_test = unittest.make(_parse_lockfile_v6_test_impl, attrs = {}) d_test = unittest.make(_parse_lockfile_v9_test_impl, attrs = {}) e_test = unittest.make(_test_version_supported, attrs = {}) f_test = unittest.make(_test_strip_peer_dep_or_patched_version, attrs = {}) +g_test = unittest.make(_test_convert_pnpm_v6_v9_version_peer_dep, attrs = {}) +h_test = unittest.make(_parse_lockfile_v6_local_injected_test_impl, attrs = {}) +j_test = unittest.make(_parse_lockfile_v9_injected_local_test_impl, attrs = {}) TESTS = [ a_test, @@ -232,8 +482,18 @@ TESTS = [ d_test, e_test, f_test, + g_test, + h_test, + j_test, ] def parse_pnpm_lock_tests(name): + tests = [] for index, test_rule in enumerate(TESTS): - test_rule(name = "{}_test_{}".format(name, index)) + test_name = "{}_test_{}".format(name, index) + test_rule(name = test_name) + tests.append(":" + test_name) + native.test_suite( + name = name, + tests = tests, + ) From f2c65d012a0041750ecf2eb266c3efe2879848b4 Mon Sep 17 00:00:00 2001 From: mele Date: Thu, 26 Sep 2024 14:49:08 +1000 Subject: [PATCH 2/3] Make buildifier happy --- npm/private/pnpm.bzl | 2 + npm/private/test/parse_pnpm_lock_tests.bzl | 48 +++++++++++----------- 2 files changed, 26 insertions(+), 24 deletions(-) diff --git a/npm/private/pnpm.bzl b/npm/private/pnpm.bzl index 84e6f91d2..b04ae0291 100644 --- a/npm/private/pnpm.bzl +++ b/npm/private/pnpm.bzl @@ -509,10 +509,12 @@ def _convert_v9_packages(packages, snapshots): friendly_version = package_data["version"] if "version" in package_data else static_key[version_index + 1:] package_id = package_snapshot.get("id", None) + # match v6 lockfile behaviour with id if package_id != None and "file:" in package_id: # Remove package name from id package_id = package_id[len(name) + 1:] + # ensure local packages always have an id, so that peer dependencies don't cause issues if package_id == None and "file:" in package_key: resolution = package_data.get("resolution") diff --git a/npm/private/test/parse_pnpm_lock_tests.bzl b/npm/private/test/parse_pnpm_lock_tests.bzl index afd366476..a9a32f4d5 100644 --- a/npm/private/test/parse_pnpm_lock_tests.bzl +++ b/npm/private/test/parse_pnpm_lock_tests.bzl @@ -154,7 +154,7 @@ def _parse_lockfile_v6_test_impl(ctx): "@aspect-test/a": { "specifier": "5.0.0", "version": "5.0.0", - } + }, }, "packages": { "/@aspect-test/a@5.0.0": { @@ -170,7 +170,7 @@ def _parse_lockfile_v6_test_impl(ctx): # `npm_translate_lock` will likewise replace the peer dependency component with a hash if too long. "@aspect-test/d": "2.0.0(@aspect-test/c@1.0.0)", }, - "dev": False + "dev": False, }, }, })) @@ -194,7 +194,7 @@ def _parse_lockfile_v6_local_injected_test_impl(ctx): "lockfileVersion": "6.0", "settings": { "autoInstallPeers": True, - "excludeLinksFromLockfile": False + "excludeLinksFromLockfile": False, }, "importers": { ".": {}, @@ -202,51 +202,51 @@ def _parse_lockfile_v6_local_injected_test_impl(ctx): "dependencies": { "b": { "specifier": "workspace:*", - "version": "file:packages/b(typescript@5.6.2)" - } + "version": "file:packages/b(typescript@5.6.2)", + }, }, "dependenciesMeta": { "b": { - "injected": True - } - } + "injected": True, + }, + }, }, "packages/b": { "dependencies": { "typescript": { "specifier": "^5.6.2", - "version": "5.6.2" - } - } - } + "version": "5.6.2", + }, + }, + }, }, "packages": { "/typescript@5.6.2": { "resolution": { - "integrity": "sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw==" + "integrity": "sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw==", }, "engines": { - "node": ">=14.17" + "node": ">=14.17", }, "hasBin": True, - "dev": False + "dev": False, }, "file:packages/b(typescript@5.6.2)": { "resolution": { "directory": "packages/b", - "type": "directory" + "type": "directory", }, "id": "file:packages/b", "name": "b", "peerDependencies": { - "typescript": "^5.6.2" + "typescript": "^5.6.2", }, "dependencies": { - "typescript": "5.6.2" + "typescript": "5.6.2", }, - "dev": False - } - } + "dev": False, + }, + }, })) expected = ( @@ -254,7 +254,7 @@ def _parse_lockfile_v6_local_injected_test_impl(ctx): expected_packages_injected, {}, 6.0, - None + None, ) asserts.equals(env, expected, parsed_json) @@ -380,7 +380,7 @@ def _parse_lockfile_v9_injected_local_test_impl(ctx): "id": "b@file:packages/b", "dependencies": { "typescript": "5.6.2", - } + }, }, "typescript@5.6.2": {}, }, @@ -402,7 +402,7 @@ def _parse_lockfile_v9_injected_local_test_impl(ctx): v9_expected_packages, {}, 9.0, - None + None, ) asserts.equals(env, expected, parsed_json) From 6e8f369ea955e5e342021167d2ac32254f1008d7 Mon Sep 17 00:00:00 2001 From: mele Date: Thu, 26 Sep 2024 15:02:16 +1000 Subject: [PATCH 3/3] buildifier lint --- npm/private/test/parse_pnpm_lock_tests.bzl | 1 + 1 file changed, 1 insertion(+) diff --git a/npm/private/test/parse_pnpm_lock_tests.bzl b/npm/private/test/parse_pnpm_lock_tests.bzl index a9a32f4d5..5e07ed845 100644 --- a/npm/private/test/parse_pnpm_lock_tests.bzl +++ b/npm/private/test/parse_pnpm_lock_tests.bzl @@ -487,6 +487,7 @@ TESTS = [ j_test, ] +# buildifier: disable=function-docstring def parse_pnpm_lock_tests(name): tests = [] for index, test_rule in enumerate(TESTS):