From 1d2f8c0a6cedb0c8864537e55465cba1b6ccded5 Mon Sep 17 00:00:00 2001 From: Jason Bedard Date: Fri, 16 Aug 2024 18:19:22 -0700 Subject: [PATCH] test: add @bazel/runfiles test --- .../npm_translate_lock_LTE4Nzc1MDcwNjU= | 3 +- .bazelignore | 1 + MODULE.bazel | 1 + WORKSPACE | 1 + e2e/runfiles/.bazelignore | 1 + e2e/runfiles/.npmrc | 4 + e2e/runfiles/BUILD.bazel | 23 ++++ e2e/runfiles/MODULE.bazel | 22 ++++ e2e/runfiles/WORKSPACE | 2 + e2e/runfiles/package.json | 10 ++ e2e/runfiles/pnpm-lock.yaml | 22 ++++ e2e/runfiles/pnpm-workspace.yaml | 2 + e2e/runfiles/test.js | 73 ++++++++++++ e2e/runfiles/test_fixture.md | 1 + examples/runfiles/BUILD.bazel | 23 ++++ examples/runfiles/package.json | 7 ++ examples/runfiles/test.js | 111 ++++++++++++++++++ examples/runfiles/test_fixture.md | 1 + pnpm-lock.yaml | 10 ++ 19 files changed, 317 insertions(+), 1 deletion(-) create mode 100644 e2e/runfiles/.bazelignore create mode 100644 e2e/runfiles/.npmrc create mode 100644 e2e/runfiles/BUILD.bazel create mode 100644 e2e/runfiles/MODULE.bazel create mode 100644 e2e/runfiles/WORKSPACE create mode 100644 e2e/runfiles/package.json create mode 100644 e2e/runfiles/pnpm-lock.yaml create mode 100644 e2e/runfiles/pnpm-workspace.yaml create mode 100644 e2e/runfiles/test.js create mode 100644 e2e/runfiles/test_fixture.md create mode 100644 examples/runfiles/BUILD.bazel create mode 100644 examples/runfiles/package.json create mode 100644 examples/runfiles/test.js create mode 100644 examples/runfiles/test_fixture.md diff --git a/.aspect/rules/external_repository_action_cache/npm_translate_lock_LTE4Nzc1MDcwNjU= b/.aspect/rules/external_repository_action_cache/npm_translate_lock_LTE4Nzc1MDcwNjU= index 998d52dca..18e903c41 100755 --- a/.aspect/rules/external_repository_action_cache/npm_translate_lock_LTE4Nzc1MDcwNjU= +++ b/.aspect/rules/external_repository_action_cache/npm_translate_lock_LTE4Nzc1MDcwNjU= @@ -15,6 +15,7 @@ examples/npm_package/packages/pkg_a/package.json=1006424040 examples/npm_package/packages/pkg_b/package.json=1041247977 examples/npm_package/packages/pkg_d/package.json=1110895851 examples/npm_package/packages/pkg_e/package.json=-2145239245 +examples/runfiles/package.json=-2022435552 examples/webpack_cli/package.json=1911342006 js/private/coverage/bundle/package.json=-1543718929 js/private/image/package.json=-1260474848 @@ -28,5 +29,5 @@ npm/private/test/vendored/is-odd/package.json=1041695223 npm/private/test/vendored/lodash-4.17.21.tgz=-1206623349 npm/private/test/vendored/semver-max/package.json=578664053 package.json=-275319675 -pnpm-lock.yaml=1584807079 +pnpm-lock.yaml=715709952 pnpm-workspace.yaml=-762451270 diff --git a/.bazelignore b/.bazelignore index 312414601..4627aa799 100644 --- a/.bazelignore +++ b/.bazelignore @@ -12,6 +12,7 @@ examples/npm_package/packages/pkg_b/node_modules/ examples/npm_package/packages/pkg_c/node_modules/ examples/npm_package/packages/pkg_d/node_modules/ examples/npm_package/packages/pkg_e/node_modules/ +examples/runfiles/node_modules examples/webpack_cli/node_modules/ js/private/coverage/bundle/node_modules js/private/image/node_modules diff --git a/MODULE.bazel b/MODULE.bazel index bf4aa9211..ff7a81633 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -140,6 +140,7 @@ npm.npm_translate_lock( "//examples/npm_package/packages/pkg_b:package.json", "//examples/npm_package/packages/pkg_d:package.json", "//examples/npm_package/packages/pkg_e:package.json", + "//examples/runfiles:package.json", "//examples/webpack_cli:package.json", "//js/private/coverage/bundle:package.json", "//js/private/image:package.json", diff --git a/WORKSPACE b/WORKSPACE index 7323ab697..d0d11dcd1 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -89,6 +89,7 @@ npm_translate_lock( "//examples/npm_package/packages/pkg_b:package.json", "//examples/npm_package/packages/pkg_d:package.json", "//examples/npm_package/packages/pkg_e:package.json", + "//examples/runfiles:package.json", "//examples/webpack_cli:package.json", "//js/private/coverage/bundle:package.json", "//js/private/image:package.json", diff --git a/e2e/runfiles/.bazelignore b/e2e/runfiles/.bazelignore new file mode 100644 index 000000000..3c3629e64 --- /dev/null +++ b/e2e/runfiles/.bazelignore @@ -0,0 +1 @@ +node_modules diff --git a/e2e/runfiles/.npmrc b/e2e/runfiles/.npmrc new file mode 100644 index 000000000..5de6efae1 --- /dev/null +++ b/e2e/runfiles/.npmrc @@ -0,0 +1,4 @@ +# Disabling pnpm [hoisting](https://pnpm.io/npmrc#hoist) by setting `hoist=false` is recommended on +# projects using rules_js so that pnpm outside of Bazel lays out a node_modules tree similar to what +# rules_js lays out under Bazel (without a hidden node_modules/.pnpm/node_modules) +hoist=false diff --git a/e2e/runfiles/BUILD.bazel b/e2e/runfiles/BUILD.bazel new file mode 100644 index 000000000..2fdd73914 --- /dev/null +++ b/e2e/runfiles/BUILD.bazel @@ -0,0 +1,23 @@ +load("@aspect_rules_js//js:defs.bzl", "js_test") +load("@npm//:defs.bzl", "npm_link_all_packages") + +npm_link_all_packages() + +js_test( + name = "runfiles", + data = [ + "test_fixture.md", + "test_fixture.md.generated_file_suffix", + ":node_modules/@bazel/runfiles", + ], + entry_point = "test.js", +) + +# Path of file must start similar to `test_fixture.md` in order to regression-test a +# scenario where the runfile resolution would accidentally resolve the path to +# `test_fixture.md` through a runfile manifest entry that starts similarly. +genrule( + name = "gen-data", + outs = ["test_fixture.md.generated_file_suffix"], + cmd = """echo "Generated" > $@""", +) diff --git a/e2e/runfiles/MODULE.bazel b/e2e/runfiles/MODULE.bazel new file mode 100644 index 000000000..d8f80cc43 --- /dev/null +++ b/e2e/runfiles/MODULE.bazel @@ -0,0 +1,22 @@ +module(name = "e2e_runfiles") + +bazel_dep(name = "aspect_rules_js", version = "0.0.0", dev_dependency = True) +local_path_override( + module_name = "aspect_rules_js", + path = "../..", +) + +bazel_dep(name = "aspect_bazel_lib", version = "2.7.7", dev_dependency = True) + +npm = use_extension( + "@aspect_rules_js//npm:extensions.bzl", + "npm", + dev_dependency = True, +) +npm.npm_translate_lock( + name = "npm", + npmrc = "//:.npmrc", + pnpm_lock = "//:pnpm-lock.yaml", + verify_node_modules_ignored = "//:.bazelignore", +) +use_repo(npm, "npm") diff --git a/e2e/runfiles/WORKSPACE b/e2e/runfiles/WORKSPACE new file mode 100644 index 000000000..3a956c2b7 --- /dev/null +++ b/e2e/runfiles/WORKSPACE @@ -0,0 +1,2 @@ +# The presence of this file causes WORKSPACE to be ignored when bzlmod is enabled. +# See https://docs.google.com/document/d/1JtXIVnXyFZ4bmbiBCr5gsTH4-opZAFf5DMMb-54kES0/edit#heading=h.y054fjub9max diff --git a/e2e/runfiles/package.json b/e2e/runfiles/package.json new file mode 100644 index 000000000..fd30bb85d --- /dev/null +++ b/e2e/runfiles/package.json @@ -0,0 +1,10 @@ +{ + "name": "@examples/runfiles", + "private": true, + "dependencies": { + "@bazel/runfiles": "file:./bazel_runfiles" + }, + "pnpm": { + "onlyBuiltDependencies": [] + } +} diff --git a/e2e/runfiles/pnpm-lock.yaml b/e2e/runfiles/pnpm-lock.yaml new file mode 100644 index 000000000..bb6a5068b --- /dev/null +++ b/e2e/runfiles/pnpm-lock.yaml @@ -0,0 +1,22 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + '@bazel/runfiles': + specifier: file:./bazel_runfiles + version: file:bazel_runfiles + +packages: + + '@bazel/runfiles@file:bazel_runfiles': + resolution: {directory: bazel_runfiles, type: directory} + +snapshots: + + '@bazel/runfiles@file:bazel_runfiles': {} diff --git a/e2e/runfiles/pnpm-workspace.yaml b/e2e/runfiles/pnpm-workspace.yaml new file mode 100644 index 000000000..2cce0eb74 --- /dev/null +++ b/e2e/runfiles/pnpm-workspace.yaml @@ -0,0 +1,2 @@ +packages: + - '.' diff --git a/e2e/runfiles/test.js b/e2e/runfiles/test.js new file mode 100644 index 000000000..e446bc7b7 --- /dev/null +++ b/e2e/runfiles/test.js @@ -0,0 +1,73 @@ +const { join, dirname } = require('path') +const { Runfiles } = require('@bazel/runfiles') + +function describe(name, fn) { + console.log(name) + fn() +} +function it(name, fn) { + console.log(` ${name}`) + fn() +} + +function assert(t, msg) { + if (!t) { + throw new Error(msg) + } +} + +const runfiles = new Runfiles(process.env) + +describe('runfile resolution', () => { + it('should properly resolve the files with the module(name)', () => { + const testFixturePath = runfiles.resolve('e2e_runfiles/test_fixture.md') + const expectedPath = join(__dirname, 'test_fixture.md') + + assert( + normalizePath(testFixturePath) == normalizePath(expectedPath), + `Expected the test fixture to be resolved next to the spec source file: ${testFixturePath} vs ${expectedPath}` + ) + }) + + it('should properly resolve with forward slashes', () => { + const testFixturePath = runfiles.resolve( + 'e2e_runfiles\\test_fixture.md' + ) + const expectedPath = join(__dirname, 'test_fixture.md') + + assert( + normalizePath(testFixturePath) == normalizePath(expectedPath), + `Expected the test fixture to be resolved next to the spec source file: ${testFixturePath} vs ${expectedPath}` + ) + }) + + it('should properly resolve with the __main__ module alias', () => { + const testFixturePath = runfiles.resolve('__main__/test_fixture.md') + const expectedPath = join(__dirname, 'test_fixture.md') + + assert( + normalizePath(testFixturePath) == normalizePath(expectedPath), + `Expected the test fixture to be resolved next to the spec source file: ${testFixturePath} vs ${expectedPath}` + ) + }) + + it('should properly resolve a runfile within a direct module dependency', () => { + const fsPatchPath = runfiles.resolve( + 'aspect_rules_js/js/private/node-patches/fs.cjs' + ) + + assert(!!fsPatchPath, `Expected to find fs patches`) + assert( + fsPatchPath.indexOf('/aspect_rules_js/') == -1, + `Expected to find fs patches in a resolved bzlmod directory` + ) + }) +}) + +/** + * Normalizes the delimiters within the specified path. This is useful for test assertions + * where paths might be computed using different path delimiters. + */ +function normalizePath(value) { + return value.replace(/\\/g, '/') +} diff --git a/e2e/runfiles/test_fixture.md b/e2e/runfiles/test_fixture.md new file mode 100644 index 000000000..cac8206df --- /dev/null +++ b/e2e/runfiles/test_fixture.md @@ -0,0 +1 @@ +This is a file part of the sources diff --git a/examples/runfiles/BUILD.bazel b/examples/runfiles/BUILD.bazel new file mode 100644 index 000000000..2fdd73914 --- /dev/null +++ b/examples/runfiles/BUILD.bazel @@ -0,0 +1,23 @@ +load("@aspect_rules_js//js:defs.bzl", "js_test") +load("@npm//:defs.bzl", "npm_link_all_packages") + +npm_link_all_packages() + +js_test( + name = "runfiles", + data = [ + "test_fixture.md", + "test_fixture.md.generated_file_suffix", + ":node_modules/@bazel/runfiles", + ], + entry_point = "test.js", +) + +# Path of file must start similar to `test_fixture.md` in order to regression-test a +# scenario where the runfile resolution would accidentally resolve the path to +# `test_fixture.md` through a runfile manifest entry that starts similarly. +genrule( + name = "gen-data", + outs = ["test_fixture.md.generated_file_suffix"], + cmd = """echo "Generated" > $@""", +) diff --git a/examples/runfiles/package.json b/examples/runfiles/package.json new file mode 100644 index 000000000..0625b9382 --- /dev/null +++ b/examples/runfiles/package.json @@ -0,0 +1,7 @@ +{ + "name": "@examples/runfiles", + "private": true, + "dependencies": { + "@bazel/runfiles": "^5.8.1" + } +} diff --git a/examples/runfiles/test.js b/examples/runfiles/test.js new file mode 100644 index 000000000..1a064d12b --- /dev/null +++ b/examples/runfiles/test.js @@ -0,0 +1,111 @@ +const { join, dirname } = require('path') +const { Runfiles } = require('@bazel/runfiles') + +function describe(name, fn) { + console.log(name) + fn() +} +function it(name, fn) { + console.log(` ${name}`) + fn() +} + +function assert(t, msg) { + if (!t) { + throw new Error(msg) + } +} + +const runfiles = new Runfiles(process.env) + +describe('runfile resolution', () => { + it('should properly resolve the files with the module(name)', () => { + const testFixturePath = runfiles.resolve( + 'aspect_rules_js/examples/runfiles/test_fixture.md' + ) + const expectedPath = join(__dirname, 'test_fixture.md') + + assert( + normalizePath(testFixturePath) == normalizePath(expectedPath), + `Expected the test fixture to be resolved next to the spec source file: ${testFixturePath} vs ${expectedPath}` + ) + }) + + it('should properly resolve with forward slashes', () => { + const testFixturePath = runfiles.resolve( + 'aspect_rules_js\\examples\\runfiles\\test_fixture.md' + ) + const expectedPath = join(__dirname, 'test_fixture.md') + + assert( + normalizePath(testFixturePath) == normalizePath(expectedPath), + `Expected the test fixture to be resolved next to the spec source file: ${testFixturePath} vs ${expectedPath}` + ) + }) + + it('should properly resolve with the __main__ module alias', () => { + const testFixturePath = runfiles.resolve( + '__main__/examples/runfiles/test_fixture.md' + ) + const expectedPath = join(__dirname, 'test_fixture.md') + + assert( + normalizePath(testFixturePath) == normalizePath(expectedPath), + `Expected the test fixture to be resolved next to the spec source file: ${testFixturePath} vs ${expectedPath}` + ) + }) + + it('should properly resolve a subdirectory of a runfile', () => { + const packagePath = runfiles.resolve('aspect_rules_js/examples') + // Alternate with trailing slash + const packagePath2 = runfiles.resolve('aspect_rules_js/examples/') + const expectedPath = dirname( + dirname( + runfiles.resolve( + 'aspect_rules_js/examples/runfiles/test_fixture.md.generated_file_suffix' + ) + ) + ) + + assert( + normalizePath(packagePath) == normalizePath(expectedPath), + `Expected to resolve a subdirectory of a runfile: ${packagePath} vs ${expectedPath}` + ) + assert( + normalizePath(packagePath2) == normalizePath(expectedPath), + `Expected to resolve a subdirectory of a runfile: ${packagePath2} vs ${expectedPath}` + ) + }) + + it('should properly resolve the workspace root of a runfile', () => { + const packagePath = runfiles.resolve('aspect_rules_js') + // Alternate with trailing slash + const packagePath2 = runfiles.resolve('aspect_rules_js/') + const expectedPath = dirname( + dirname( + dirname( + runfiles.resolve( + 'aspect_rules_js/examples/runfiles/test_fixture.md.generated_file_suffix' + ) + ) + ) + ) + + assert( + normalizePath(packagePath) == normalizePath(expectedPath), + `Expected to resolve the workspace root of a runfile: ${packagePath} vs ${expectedPath}` + ) + assert( + normalizePath(packagePath2) == normalizePath(expectedPath), + `Expected to resolve the workspace root of a runfile: ${packagePath2} vs ${expectedPath}` + ) + }) +}) + +/** + * Normalizes the delimiters within the specified path. This is useful for test assertions + * where paths might be computed using different path delimiters. + */ +function normalizePath(value) { + return value.replace(/\\/g, '/') +} diff --git a/examples/runfiles/test_fixture.md b/examples/runfiles/test_fixture.md new file mode 100644 index 000000000..cac8206df --- /dev/null +++ b/examples/runfiles/test_fixture.md @@ -0,0 +1 @@ +This is a file part of the sources diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d2f921e59..d3d8e61c5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -184,6 +184,12 @@ importers: specifier: workspace:* version: link:../pkg_d + examples/runfiles: + dependencies: + '@bazel/runfiles': + specifier: ^5.8.1 + version: 5.8.1 + examples/webpack_cli: dependencies: '@vanilla-extract/css': @@ -681,6 +687,10 @@ packages: to-fast-properties: 2.0.0 dev: true + /@bazel/runfiles@5.8.1: + resolution: {integrity: sha512-NDdfpdQ6rZlylgv++iMn5FkObC/QlBQvipinGLSOguTYpRywmieOyJ29XHvUilspwTFSILWpoE9CqMGkHXug1g==} + dev: false + /@bcoe/v8-coverage@0.2.3: resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} dev: false