From f975f1255328768b0e2019458b30408b978ceb4e Mon Sep 17 00:00:00 2001 From: eric Date: Sun, 15 Mar 2026 13:54:18 +0100 Subject: [PATCH] ci: fix dependencies --- .github/workflows/ci.yml | 43 ++++++++++- README.md | 11 +-- docs/rules.md | 16 ++-- flake.nix | 4 + internal/bun_binary.bzl | 2 +- internal/bun_dev.bzl | 2 +- internal/bun_script.bzl | 9 ++- internal/bun_test.bzl | 2 +- internal/js_run_devserver.bzl | 2 +- internal/runtime_launcher.js | 74 +++++++++++++++++-- tests/binary_test/BUILD.bazel | 4 +- tests/binary_test/path_probe.ts | 13 ++++ tests/binary_test/run_binary.sh | 7 +- tests/binary_test/run_env_binary.sh | 7 +- tests/binary_test/run_flag_binary.sh | 7 +- tests/binary_test/run_parent_env_binary.sh | 7 +- tests/binary_test/run_path_binary.sh | 11 +-- tests/binary_test/verify_data_shape.sh | 60 ++++++++++++++- tests/bun_test_test/BUILD.bazel | 2 +- tests/bun_test_test/failing_suite_shape.sh | 58 ++++++++++++++- tests/ci_test/BUILD.bazel | 4 +- tests/ci_test/phase8_ci_matrix_shape_test.sh | 58 ++++++++++++++- tests/ci_test/phase8_ci_targets_test.sh | 58 ++++++++++++++- .../examples_basic_run_e2e_test.sh | 7 +- .../examples_vite_monorepo_e2e_test.sh | 7 +- tests/js_compat_test/run_binary.sh | 7 +- tests/js_compat_test/run_devserver.sh | 7 +- tests/script_test/run_env_script.sh | 7 +- .../run_paraglide_monorepo_builds.sh | 7 +- tests/script_test/run_script.sh | 7 +- tests/script_test/run_vite_app.sh | 7 +- tests/script_test/run_vite_monorepo_apps.sh | 7 +- tests/script_test/run_workspace_parallel.sh | 7 +- tests/script_test/run_workspace_script.sh | 7 +- tests/toolchain_test/BUILD.bazel | 14 ++-- .../toolchain_resolution_matrix.sh | 58 ++++++++++++++- tests/toolchain_test/toolchain_version.sh | 60 ++++++++++++++- 37 files changed, 522 insertions(+), 148 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2bcd3e6..703bba6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -35,9 +35,48 @@ jobs: external-cache: true disk-cache: ci-${{ matrix.phase8_target }} cache-save: ${{ github.event_name != 'pull_request' }} + - name: Install Nix + if: runner.os != 'Windows' + uses: cachix/install-nix-action@v31 + with: + extra_nix_config: | + experimental-features = nix-command flakes + - name: Restore and save Nix store cache + if: runner.os != 'Windows' + uses: nix-community/cache-nix-action@v7 + with: + primary-key: nix-${{ runner.os }}-${{ hashFiles('**/*.nix', '**/flake.lock') }} + restore-prefixes-first-match: nix-${{ runner.os }}- + - name: Install flake dependencies + if: runner.os != 'Windows' + run: nix develop --accept-flake-config -c true + - name: Set up Python + if: runner.os == 'Windows' + uses: actions/setup-python@v5 + with: + python-version: "3.12" + - name: Provide python3 shim + if: runner.os == 'Windows' + shell: bash + run: | + mkdir -p "$RUNNER_TEMP/bin" + cat >"$RUNNER_TEMP/bin/python3" <<'EOF' + #!/usr/bin/env bash + exec python "$@" + EOF + chmod +x "$RUNNER_TEMP/bin/python3" + echo "$RUNNER_TEMP/bin" >> "$GITHUB_PATH" - name: Run tests (${{ matrix.phase8_target }}) + if: runner.os != 'Windows' shell: bash run: | echo "Phase 8 target: ${{ matrix.phase8_target }}" - targets="$(./tests/ci_test/phase8_ci_targets.sh "${{ matrix.phase8_target }}")" - bazel test --test_output=errors ${targets} + mapfile -t targets < <(./tests/ci_test/phase8_ci_targets.sh "${{ matrix.phase8_target }}") + nix develop --accept-flake-config -c bazel test --test_output=errors "${targets[@]}" + - name: Run tests (${{ matrix.phase8_target }}) + if: runner.os == 'Windows' + shell: bash + run: | + echo "Phase 8 target: ${{ matrix.phase8_target }}" + mapfile -t targets < <(./tests/ci_test/phase8_ci_targets.sh "${{ matrix.phase8_target }}") + bazel test --test_output=errors "${targets[@]}" diff --git a/README.md b/README.md index 1e6274f..6fd86c3 100644 --- a/README.md +++ b/README.md @@ -66,7 +66,7 @@ Strict defaults are enabled by default: - `bun_install` skips lifecycle scripts unless `ignore_scripts = False` - `bun_build`, `bun_bundle`, `bun_compile`, and `bun_test` require `install_mode = "disable"` -- Runtime launchers do not inherit the host `PATH` unless `inherit_host_path = True` +- Runtime launchers stage hermetic `bun`, `bunx`, and `node` commands on `PATH` and do not inherit the host `PATH` unless `inherit_host_path = True` To refresh generated rule docs: @@ -218,10 +218,11 @@ bun_script( ) ``` -When `node_modules` is provided, executables from `node_modules/.bin` are added -to the runtime `PATH`. The host `PATH` is not inherited unless -`inherit_host_path = True`. This label typically comes from `bun_install`, -which still produces a standard `node_modules/` directory. +Launcher-based runtime rules stage hermetic `bun`, `bunx`, and `node` +commands on `PATH`. When `node_modules` is provided, executables from +`node_modules/.bin` are also added to the runtime `PATH`. The host `PATH` is +not inherited unless `inherit_host_path = True`. This label typically comes +from `bun_install`, which still produces a standard `node_modules/` directory. ### `bun_build` and `bun_compile` diff --git a/docs/rules.md b/docs/rules.md index dd0f774..b88b26b 100644 --- a/docs/rules.md +++ b/docs/rules.md @@ -12,7 +12,7 @@ Public API surface for Bun Bazel rules. Strict defaults: - `bun_build`, `bun_bundle`, `bun_compile`, and `bun_test` require `install_mode = "disable"` -- Runtime launchers do not inherit the host `PATH` unless `inherit_host_path = True` +- Runtime launchers stage hermetic `bun`, `bunx`, and `node` commands on `PATH` and do not inherit the host `PATH` unless `inherit_host_path = True` @@ -41,7 +41,7 @@ Use this rule for non-test scripts and CLIs that should run via `bazel run`. | entry_point | Path to the main JS/TS file to execute. | Label | required | | | env_files | Additional environment files loaded with `--env-file`. | List of labels | optional | `[]` | | install_mode | Whether Bun may auto-install missing packages at runtime. Non-`disable` values are runtime opt-ins and are not hermetic. | String | optional | `"disable"` | -| inherit_host_path | If true, appends the host PATH after staged `node_modules/.bin` entries at runtime. | Boolean | optional | `False` | +| inherit_host_path | If true, appends the host PATH after the staged Bun runtime tool bin and `node_modules/.bin` entries at runtime. | Boolean | optional | `False` | | no_env_file | If true, disables Bun's automatic `.env` loading. | Boolean | optional | `False` | | node_modules | Optional label providing package files from a `node_modules` tree, typically produced by `bun_install`, in runfiles. | Label | optional | `None` | | preload | Modules to preload with `--preload` before running the entry point. | List of labels | optional | `[]` | @@ -265,7 +265,7 @@ watch/HMR plus optional full restarts on selected file changes. | entry_point | Path to the main JS/TS file to execute in dev mode. | Label | required | | | env_files | Additional environment files loaded with `--env-file`. | List of labels | optional | `[]` | | install_mode | Whether Bun may auto-install missing packages in dev mode. This is a local workflow helper, not a hermetic execution surface. | String | optional | `"disable"` | -| inherit_host_path | If true, appends the host PATH after staged `node_modules/.bin` entries at runtime. | Boolean | optional | `False` | +| inherit_host_path | If true, appends the host PATH after the staged Bun runtime tool bin and `node_modules/.bin` entries at runtime. | Boolean | optional | `False` | | no_clear_screen | If true, disables terminal clearing on Bun reloads. | Boolean | optional | `False` | | no_env_file | If true, disables Bun's automatic `.env` loading. | Boolean | optional | `False` | | node_modules | Optional label providing package files from a `node_modules` tree, typically produced by `bun_install`, in runfiles. | Label | optional | `None` | @@ -295,7 +295,7 @@ Use this rule to expose existing package scripts such as `dev`, `build`, or `check` via `bazel run` without adding wrapper shell scripts. This is a good fit for Vite-style workflows, where scripts like `vite dev` or `vite build` are declared in `package.json` and expect to run from the package directory with -`node_modules/.bin` available on `PATH`. +the staged Bun runtime tool bin and `node_modules/.bin` available on `PATH`. **ATTRIBUTES** @@ -309,10 +309,10 @@ declared in `package.json` and expect to run from the package directory with | execution_mode | How Bun should execute matching workspace scripts. | String | optional | `"single"` | | filters | Workspace package filters passed via repeated `--filter` flags. | List of strings | optional | `[]` | | install_mode | Whether Bun may auto-install missing packages while running the script. This is a local workflow helper, not a hermetic execution surface. | String | optional | `"disable"` | -| inherit_host_path | If true, appends the host PATH after staged `node_modules/.bin` entries at runtime. | Boolean | optional | `False` | +| inherit_host_path | If true, appends the host PATH after the staged Bun runtime tool bin and `node_modules/.bin` entries at runtime. | Boolean | optional | `False` | | no_env_file | If true, disables Bun's automatic `.env` loading. | Boolean | optional | `False` | | no_exit_on_error | If true, Bun keeps running other workspace scripts when one fails. | Boolean | optional | `False` | -| node_modules | Optional label providing package files from a `node_modules` tree, typically produced by `bun_install`, in runfiles. Executables from `node_modules/.bin` are added to `PATH`, which is useful for scripts such as `vite`. | Label | optional | `None` | +| node_modules | Optional label providing package files from a `node_modules` tree, typically produced by `bun_install`, in runfiles. The staged Bun runtime tool bin and executables from `node_modules/.bin` are added to `PATH`, which is useful for scripts such as `vite`. | Label | optional | `None` | | package_json | Label of the `package.json` file containing the named script. | Label | required | | | preload | Modules to preload with `--preload` before running the script. | List of labels | optional | `[]` | | run_flags | Additional raw flags forwarded to `bun run` before the script name. | List of strings | optional | `[]` | @@ -356,7 +356,7 @@ Supports Bazel test filtering (`--test_filter`) and coverage integration. | coverage_reporters | Repeated Bun coverage reporters such as `text` or `lcov`. | List of strings | optional | `[]` | | env_files | Additional environment files loaded with `--env-file`. | List of labels | optional | `[]` | | install_mode | Whether Bun may auto-install missing packages while testing. Hermetic tests require `\"disable\"`, and other values are rejected. | String | optional | `"disable"` | -| inherit_host_path | If true, appends the host PATH after staged `node_modules/.bin` entries at runtime. | Boolean | optional | `False` | +| inherit_host_path | If true, appends the host PATH after the staged Bun runtime tool bin and `node_modules/.bin` entries at runtime. | Boolean | optional | `False` | | max_concurrency | Optional maximum number of concurrent tests. | Integer | optional | `0` | | no_env_file | If true, disables Bun's automatic `.env` loading. | Boolean | optional | `False` | | node_modules | Optional label providing package files from a `node_modules` tree, typically produced by `bun_install`, in runfiles. | Label | optional | `None` | @@ -427,7 +427,7 @@ the provided tool with any default arguments. | package_dir_hint | Optional package-relative directory hint when package_json is not supplied. | String | optional | `"."` | | package_json | Optional package.json used to resolve the package working directory. | Label | optional | `None` | | tool | Executable target to launch as the dev server. | Label | required | | -| inherit_host_path | If true, appends the host PATH after staged `node_modules/.bin` entries at runtime. | Boolean | optional | `False` | +| inherit_host_path | If true, appends the host PATH after the staged Bun runtime tool bin and `node_modules/.bin` entries at runtime. | Boolean | optional | `False` | | working_dir | Working directory at runtime: Bazel runfiles workspace root or the resolved package directory. | String | optional | `"workspace"` | diff --git a/flake.nix b/flake.nix index 59b3764..f7961b9 100644 --- a/flake.nix +++ b/flake.nix @@ -118,6 +118,8 @@ shell.packages = [ pkgs.bazel-buildtools + pkgs.curl + pkgs.python3 self.packages.${system}.release ]; @@ -128,6 +130,8 @@ runtimeInputs = [ bazel9 pkgs.bun + pkgs.curl + pkgs.python3 ]; }; }; diff --git a/internal/bun_binary.bzl b/internal/bun_binary.bzl index 24951dd..c96f404 100644 --- a/internal/bun_binary.bzl +++ b/internal/bun_binary.bzl @@ -114,7 +114,7 @@ _BUN_BINARY_ATTRS.update({ ), "inherit_host_path": attr.bool( default = False, - doc = "If true, appends the host PATH after staged node_modules/.bin entries at runtime.", + doc = "If true, appends the host PATH after the staged Bun runtime tool bin and node_modules/.bin entries at runtime.", ), }) diff --git a/internal/bun_dev.bzl b/internal/bun_dev.bzl index 10ffbd6..079136a 100644 --- a/internal/bun_dev.bzl +++ b/internal/bun_dev.bzl @@ -122,7 +122,7 @@ _BUN_DEV_ATTRS.update({ ), "inherit_host_path": attr.bool( default = False, - doc = "If true, appends the host PATH after staged node_modules/.bin entries at runtime.", + doc = "If true, appends the host PATH after the staged Bun runtime tool bin and node_modules/.bin entries at runtime.", ), }) diff --git a/internal/bun_script.bzl b/internal/bun_script.bzl index fce857f..00ab2bb 100644 --- a/internal/bun_script.bzl +++ b/internal/bun_script.bzl @@ -83,7 +83,7 @@ _BUN_SCRIPT_ATTRS.update({ doc = "Label of the `package.json` file containing the named script.", ), "node_modules": attr.label( - doc = "Optional label providing package files from a `node_modules` tree, typically produced by `bun_install`, in runfiles. Executables from `node_modules/.bin` are added to `PATH`, which is useful for scripts such as `vite`.", + doc = "Optional label providing package files from a `node_modules` tree, typically produced by `bun_install`, in runfiles. The staged Bun runtime tool bin and executables from `node_modules/.bin` are added to `PATH`, which is useful for scripts such as `vite`.", ), "data": attr.label_list( allow_files = True, @@ -148,7 +148,7 @@ _BUN_SCRIPT_ATTRS.update({ ), "inherit_host_path": attr.bool( default = False, - doc = "If true, appends the host PATH after staged node_modules/.bin entries at runtime.", + doc = "If true, appends the host PATH after the staged Bun runtime tool bin and node_modules/.bin entries at runtime.", ), }) @@ -159,8 +159,9 @@ bun_script = rule( Use this rule to expose existing package scripts such as `dev`, `build`, or `check` via `bazel run` without adding wrapper shell scripts. This is a good fit for Vite-style workflows, where scripts like `vite dev` or `vite build` are -declared in `package.json` and expect to run from the package directory. This -is a local workflow helper rather than a hermetic build rule. +declared in `package.json` and expect to run from the package directory with +the staged Bun runtime tool bin and `node_modules/.bin` on `PATH`. This is a +local workflow helper rather than a hermetic build rule. """, attrs = _BUN_SCRIPT_ATTRS, executable = True, diff --git a/internal/bun_test.bzl b/internal/bun_test.bzl index 2e8cfd0..cd7f8ad 100644 --- a/internal/bun_test.bzl +++ b/internal/bun_test.bzl @@ -180,7 +180,7 @@ _BUN_TEST_ATTRS.update({ ), "inherit_host_path": attr.bool( default = False, - doc = "If true, appends the host PATH after staged node_modules/.bin entries at runtime.", + doc = "If true, appends the host PATH after the staged Bun runtime tool bin and node_modules/.bin entries at runtime.", ), }) diff --git a/internal/js_run_devserver.bzl b/internal/js_run_devserver.bzl index 9028bc2..3c9fb31 100644 --- a/internal/js_run_devserver.bzl +++ b/internal/js_run_devserver.bzl @@ -92,7 +92,7 @@ _JS_RUN_DEVSERVER_ATTRS.update({ ), "inherit_host_path": attr.bool( default = False, - doc = "If true, appends the host PATH after staged node_modules/.bin entries at runtime.", + doc = "If true, appends the host PATH after the staged Bun runtime tool bin and node_modules/.bin entries at runtime.", ), }) diff --git a/internal/runtime_launcher.js b/internal/runtime_launcher.js index d5bcdae..15b341b 100644 --- a/internal/runtime_launcher.js +++ b/internal/runtime_launcher.js @@ -489,6 +489,31 @@ function materializeTreeContents(sourceRoot, destinationRoot) { } } +function stageRuntimeToolAlias(sourcePath, destinationPath, preferLinks) { + removePath(destinationPath); + ensureDir(dirname(destinationPath)); + if (preferLinks && !IS_WINDOWS) { + symlinkSync(sourcePath, destinationPath); + return; + } + copyPath(sourcePath, destinationPath); +} + +function stageRuntimeToolBin(runtimeWorkspace, bunPath, preferLinks) { + const runtimeToolBin = join(runtimeWorkspace, ".rules_bun", "bin"); + ensureDir(runtimeToolBin); + + const bunName = IS_WINDOWS ? "bun.exe" : "bun"; + const stagedBunPath = join(runtimeToolBin, bunName); + materializePath(realpathSync(bunPath), stagedBunPath, preferLinks); + + for (const aliasName of IS_WINDOWS ? ["bunx.exe", "node.exe"] : ["bunx", "node"]) { + stageRuntimeToolAlias(stagedBunPath, join(runtimeToolBin, aliasName), preferLinks); + } + + return runtimeToolBin; +} + function stageWorkspaceView(sourceRoot, destinationRoot, packageRelDir) { ensureDir(destinationRoot); const skippedEntry = firstPathComponent(packageRelDir); @@ -765,9 +790,19 @@ function mirrorInstallRepoWorkspaceNodeModules( } } -function buildRuntimePath(runtimeWorkspace, runtimePackageDir, runtimeInstallRoot, inheritHostPath) { +function buildRuntimePath( + runtimeToolBin, + runtimeWorkspace, + runtimePackageDir, + runtimeInstallRoot, + inheritHostPath, +) { const entries = []; + if (existsSync(runtimeToolBin) && statSync(runtimeToolBin).isDirectory()) { + entries.push(runtimeToolBin); + } + const installBin = join(runtimeInstallRoot, "node_modules", ".bin"); const packageBin = join(runtimePackageDir, "node_modules", ".bin"); const workspaceBin = join(runtimeWorkspace, "node_modules", ".bin"); @@ -915,9 +950,16 @@ function createRuntime(spec, runfiles) { materializePath(runtimeInstallNodeModules, runtimePackageNodeModules, preferLinks); } + const runtimeToolBin = stageRuntimeToolBin( + runtimeWorkspace, + runfiles.rlocation(spec.bun_short_path), + preferLinks, + ); + const env = { ...process.env }; const pathKey = pathEnvKey(env); const runtimePath = buildRuntimePath( + runtimeToolBin, runtimeWorkspace, runtimePackageDir, runtimeInstallRoot, @@ -992,12 +1034,31 @@ function composeBunArgs(spec, runfiles, runtime) { return args; } +function isWindowsBatchFile(command) { + return IS_WINDOWS && /\.(cmd|bat)$/i.test(String(command || "")); +} + +function quoteForWindowsShell(command) { + return `"${String(command).replace(/"/g, '""')}"`; +} + +function spawnChild(command, args, options) { + const spawnOptions = { + ...options, + stdio: "inherit", + }; + if (isWindowsBatchFile(command)) { + return spawn(quoteForWindowsShell(command), args, { + ...spawnOptions, + shell: true, + }); + } + return spawn(command, args, spawnOptions); +} + function spawnProcess(command, args, options) { return new Promise((resolvePromise, rejectPromise) => { - const child = spawn(command, args, { - ...options, - stdio: "inherit", - }); + const child = spawnChild(command, args, options); child.once("error", rejectPromise); child.once("exit", (code, signal) => { resolvePromise({ child, code, signal }); @@ -1077,10 +1138,9 @@ async function runDevMode(spec, runfiles, userArgs) { currentRuntime = createRuntime(spec, runfiles); const bunPath = runfiles.rlocation(spec.bun_short_path); const bunArgs = [...composeBunArgs(spec, runfiles, currentRuntime), watchFlag, ...passthroughArgs]; - child = spawn(bunPath, bunArgs, { + child = spawnChild(bunPath, bunArgs, { cwd: currentRuntime.runtimeExecDir, env: currentRuntime.env, - stdio: "inherit", }); exitPromise = new Promise((resolvePromise, rejectPromise) => { child.once("error", rejectPromise); diff --git a/tests/binary_test/BUILD.bazel b/tests/binary_test/BUILD.bazel index ca408cf..65fd462 100644 --- a/tests/binary_test/BUILD.bazel +++ b/tests/binary_test/BUILD.bazel @@ -44,8 +44,8 @@ sh_test( size = "small", srcs = ["verify_data_shape.sh"], args = [ - "$(location //internal:bun_binary.bzl)", - "$(location //tests/binary_test:BUILD.bazel)", + "$(rlocationpath //internal:bun_binary.bzl)", + "$(rlocationpath //tests/binary_test:BUILD.bazel)", ], data = [ "//internal:bun_binary.bzl", diff --git a/tests/binary_test/path_probe.ts b/tests/binary_test/path_probe.ts index 2eef2cb..acc495b 100644 --- a/tests/binary_test/path_probe.ts +++ b/tests/binary_test/path_probe.ts @@ -1,5 +1,18 @@ +import { spawnSync } from "node:child_process"; + const pathValue = process.env.PATH ?? ""; +function commandSucceeds(command: string, args: string[]): boolean { + const result = spawnSync(command, args, { + encoding: "utf8", + env: process.env, + }); + return result.status === 0; +} + console.log(JSON.stringify({ hasHostSentinel: pathValue.includes("rules_bun_host_path_sentinel"), + canRunBun: commandSucceeds("bun", ["-e", "process.exit(0)"]), + canRunBunx: commandSucceeds("bunx", ["--version"]), + canRunNode: commandSucceeds("node", ["-e", "process.exit(0)"]), })); diff --git a/tests/binary_test/run_binary.sh b/tests/binary_test/run_binary.sh index 715af61..cb8e3a1 100755 --- a/tests/binary_test/run_binary.sh +++ b/tests/binary_test/run_binary.sh @@ -8,12 +8,7 @@ run_launcher() { local launcher="$1" shift if [[ ${launcher} == *.cmd ]]; then - local command - printf -v command '"%s"' "${launcher}" - for arg in "$@"; do - printf -v command '%s "%s"' "${command}" "${arg}" - done - cmd.exe /c "${command}" | tr -d '\r' + cmd.exe /c call "${launcher}" "$@" | tr -d '\r' return 0 fi "${launcher}" "$@" diff --git a/tests/binary_test/run_env_binary.sh b/tests/binary_test/run_env_binary.sh index ef26595..959c166 100755 --- a/tests/binary_test/run_env_binary.sh +++ b/tests/binary_test/run_env_binary.sh @@ -7,12 +7,7 @@ run_launcher() { local launcher="$1" shift if [[ ${launcher} == *.cmd ]]; then - local command - printf -v command '"%s"' "${launcher}" - for arg in "$@"; do - printf -v command '%s "%s"' "${command}" "${arg}" - done - cmd.exe /c "${command}" | tr -d '\r' + cmd.exe /c call "${launcher}" "$@" | tr -d '\r' return 0 fi "${launcher}" "$@" diff --git a/tests/binary_test/run_flag_binary.sh b/tests/binary_test/run_flag_binary.sh index 1333a30..bc92489 100755 --- a/tests/binary_test/run_flag_binary.sh +++ b/tests/binary_test/run_flag_binary.sh @@ -7,12 +7,7 @@ run_launcher() { local launcher="$1" shift if [[ ${launcher} == *.cmd ]]; then - local command - printf -v command '"%s"' "${launcher}" - for arg in "$@"; do - printf -v command '%s "%s"' "${command}" "${arg}" - done - cmd.exe /c "${command}" | tr -d '\r' + cmd.exe /c call "${launcher}" "$@" | tr -d '\r' return 0 fi "${launcher}" "$@" diff --git a/tests/binary_test/run_parent_env_binary.sh b/tests/binary_test/run_parent_env_binary.sh index d829511..dad9c24 100755 --- a/tests/binary_test/run_parent_env_binary.sh +++ b/tests/binary_test/run_parent_env_binary.sh @@ -7,12 +7,7 @@ run_launcher() { local launcher="$1" shift if [[ ${launcher} == *.cmd ]]; then - local command - printf -v command '"%s"' "${launcher}" - for arg in "$@"; do - printf -v command '%s "%s"' "${command}" "${arg}" - done - cmd.exe /c "${command}" | tr -d '\r' + cmd.exe /c call "${launcher}" "$@" | tr -d '\r' return 0 fi "${launcher}" "$@" diff --git a/tests/binary_test/run_path_binary.sh b/tests/binary_test/run_path_binary.sh index ef7b265..23320f7 100755 --- a/tests/binary_test/run_path_binary.sh +++ b/tests/binary_test/run_path_binary.sh @@ -8,12 +8,7 @@ run_launcher() { local launcher="$1" shift if [[ ${launcher} == *.cmd ]]; then - local command - printf -v command '"%s"' "${launcher}" - for arg in "$@"; do - printf -v command '%s "%s"' "${command}" "${arg}" - done - env PATH="rules_bun_host_path_sentinel:${PATH:-}" cmd.exe /c "${command}" | tr -d '\r' + env PATH="rules_bun_host_path_sentinel:${PATH:-}" cmd.exe /c call "${launcher}" "$@" | tr -d '\r' return 0 fi env PATH="rules_bun_host_path_sentinel:${PATH:-}" "${launcher}" "$@" @@ -22,12 +17,12 @@ run_launcher() { default_output="$(run_launcher "${default_binary}")" inherit_output="$(run_launcher "${inherit_binary}")" -if [[ ${default_output} != '{"hasHostSentinel":false}' ]]; then +if [[ ${default_output} != '{"hasHostSentinel":false,"canRunBun":true,"canRunBunx":true,"canRunNode":true}' ]]; then echo "Expected default launcher to hide host PATH, got: ${default_output}" >&2 exit 1 fi -if [[ ${inherit_output} != '{"hasHostSentinel":true}' ]]; then +if [[ ${inherit_output} != '{"hasHostSentinel":true,"canRunBun":true,"canRunBunx":true,"canRunNode":true}' ]]; then echo "Expected inherit_host_path launcher to preserve host PATH, got: ${inherit_output}" >&2 exit 1 fi diff --git a/tests/binary_test/verify_data_shape.sh b/tests/binary_test/verify_data_shape.sh index 74d5a5a..f206340 100755 --- a/tests/binary_test/verify_data_shape.sh +++ b/tests/binary_test/verify_data_shape.sh @@ -1,8 +1,64 @@ #!/usr/bin/env bash set -euo pipefail -rule_file="$1" -build_file="$2" +if [[ -z ${RUNFILES_DIR:-} && -n ${TEST_SRCDIR:-} && -d ${TEST_SRCDIR} ]]; then + RUNFILES_DIR="${TEST_SRCDIR}" +fi +if [[ -z ${RUNFILES_DIR:-} && -z ${RUNFILES_MANIFEST_FILE:-} ]]; then + if [[ -d "$0.runfiles" ]]; then + RUNFILES_DIR="$0.runfiles" + elif [[ -f "$0.runfiles_manifest" ]]; then + RUNFILES_MANIFEST_FILE="$0.runfiles_manifest" + elif [[ -f "$0.exe.runfiles_manifest" ]]; then + RUNFILES_MANIFEST_FILE="$0.exe.runfiles_manifest" + fi +fi + +resolve_runfile() { + local path="${1:-}" + local candidate + local resolved + + if [[ -z ${path} ]]; then + echo "Error: missing runfile path" >&2 + exit 1 + fi + if [[ ${path} == /* || ${path} =~ ^[A-Za-z]:[\\/] ]]; then + printf '%s\n' "${path}" + return 0 + fi + if [[ -e ${path} ]]; then + printf '%s\n' "${path}" + return 0 + fi + + for candidate in \ + "${path}" \ + "${TEST_WORKSPACE:-}/${path}" \ + "_main/${path}"; do + [[ -z ${candidate} ]] && continue + if [[ -n ${RUNFILES_DIR:-} && -e "${RUNFILES_DIR}/${candidate}" ]]; then + printf '%s\n' "${RUNFILES_DIR}/${candidate}" + return 0 + fi + if [[ -n ${RUNFILES_MANIFEST_FILE:-} ]]; then + resolved="$( + awk -v key="${candidate}" 'index($0, key " ") == 1 { print substr($0, length(key) + 2); exit }' \ + "${RUNFILES_MANIFEST_FILE}" + )" + if [[ -n ${resolved} ]]; then + printf '%s\n' "${resolved}" + return 0 + fi + fi + done + + echo "Error: unable to resolve runfile: ${path}" >&2 + exit 1 +} + +rule_file="$(resolve_runfile "${1:-}")" +build_file="$(resolve_runfile "${2:-}")" grep -Eq 'extra_files = ctx\.files\.data \+ ctx\.files\.preload \+ ctx\.files\.env_files \+ \[bun_bin\]' "${rule_file}" grep -Eq 'name = "hello_js_with_data_bin"' "${build_file}" diff --git a/tests/bun_test_test/BUILD.bazel b/tests/bun_test_test/BUILD.bazel index 02be55e..2cb291e 100644 --- a/tests/bun_test_test/BUILD.bazel +++ b/tests/bun_test_test/BUILD.bazel @@ -60,7 +60,7 @@ sh_test( name = "bun_test_failing_suite_test", size = "small", srcs = ["failing_suite_shape.sh"], - args = ["$(location //tests/bun_test_test:BUILD.bazel)"], + args = ["$(rlocationpath //tests/bun_test_test:BUILD.bazel)"], data = ["//tests/bun_test_test:BUILD.bazel"], ) diff --git a/tests/bun_test_test/failing_suite_shape.sh b/tests/bun_test_test/failing_suite_shape.sh index d494e74..fa13bd4 100755 --- a/tests/bun_test_test/failing_suite_shape.sh +++ b/tests/bun_test_test/failing_suite_shape.sh @@ -1,7 +1,63 @@ #!/usr/bin/env bash set -euo pipefail -build_file="$1" +if [[ -z ${RUNFILES_DIR:-} && -n ${TEST_SRCDIR:-} && -d ${TEST_SRCDIR} ]]; then + RUNFILES_DIR="${TEST_SRCDIR}" +fi +if [[ -z ${RUNFILES_DIR:-} && -z ${RUNFILES_MANIFEST_FILE:-} ]]; then + if [[ -d "$0.runfiles" ]]; then + RUNFILES_DIR="$0.runfiles" + elif [[ -f "$0.runfiles_manifest" ]]; then + RUNFILES_MANIFEST_FILE="$0.runfiles_manifest" + elif [[ -f "$0.exe.runfiles_manifest" ]]; then + RUNFILES_MANIFEST_FILE="$0.exe.runfiles_manifest" + fi +fi + +resolve_runfile() { + local path="${1:-}" + local candidate + local resolved + + if [[ -z ${path} ]]; then + echo "Error: missing runfile path" >&2 + exit 1 + fi + if [[ ${path} == /* || ${path} =~ ^[A-Za-z]:[\\/] ]]; then + printf '%s\n' "${path}" + return 0 + fi + if [[ -e ${path} ]]; then + printf '%s\n' "${path}" + return 0 + fi + + for candidate in \ + "${path}" \ + "${TEST_WORKSPACE:-}/${path}" \ + "_main/${path}"; do + [[ -z ${candidate} ]] && continue + if [[ -n ${RUNFILES_DIR:-} && -e "${RUNFILES_DIR}/${candidate}" ]]; then + printf '%s\n' "${RUNFILES_DIR}/${candidate}" + return 0 + fi + if [[ -n ${RUNFILES_MANIFEST_FILE:-} ]]; then + resolved="$( + awk -v key="${candidate}" 'index($0, key " ") == 1 { print substr($0, length(key) + 2); exit }' \ + "${RUNFILES_MANIFEST_FILE}" + )" + if [[ -n ${resolved} ]]; then + printf '%s\n' "${resolved}" + return 0 + fi + fi + done + + echo "Error: unable to resolve runfile: ${path}" >&2 + exit 1 +} + +build_file="$(resolve_runfile "${1:-}")" grep -Eq 'name = "failing_suite"' "${build_file}" if grep -Eq 'tags = \["manual"\]' "${build_file}"; then diff --git a/tests/ci_test/BUILD.bazel b/tests/ci_test/BUILD.bazel index aabc41d..566b13b 100644 --- a/tests/ci_test/BUILD.bazel +++ b/tests/ci_test/BUILD.bazel @@ -4,7 +4,7 @@ sh_test( name = "phase8_ci_matrix_shape_test", size = "small", srcs = ["phase8_ci_matrix_shape_test.sh"], - args = ["$(location //.github/workflows:ci.yml)"], + args = ["$(rlocationpath //.github/workflows:ci.yml)"], data = ["//.github/workflows:ci.yml"], ) @@ -12,7 +12,7 @@ sh_test( name = "phase8_ci_targets_test", size = "small", srcs = ["phase8_ci_targets_test.sh"], - args = ["$(location :phase8_ci_targets.sh)"], + args = ["$(rlocationpath :phase8_ci_targets.sh)"], data = [":phase8_ci_targets.sh"], ) diff --git a/tests/ci_test/phase8_ci_matrix_shape_test.sh b/tests/ci_test/phase8_ci_matrix_shape_test.sh index 02333c2..2e679de 100755 --- a/tests/ci_test/phase8_ci_matrix_shape_test.sh +++ b/tests/ci_test/phase8_ci_matrix_shape_test.sh @@ -1,7 +1,63 @@ #!/usr/bin/env bash set -euo pipefail -workflow_file="$1" +if [[ -z ${RUNFILES_DIR:-} && -n ${TEST_SRCDIR:-} && -d ${TEST_SRCDIR} ]]; then + RUNFILES_DIR="${TEST_SRCDIR}" +fi +if [[ -z ${RUNFILES_DIR:-} && -z ${RUNFILES_MANIFEST_FILE:-} ]]; then + if [[ -d "$0.runfiles" ]]; then + RUNFILES_DIR="$0.runfiles" + elif [[ -f "$0.runfiles_manifest" ]]; then + RUNFILES_MANIFEST_FILE="$0.runfiles_manifest" + elif [[ -f "$0.exe.runfiles_manifest" ]]; then + RUNFILES_MANIFEST_FILE="$0.exe.runfiles_manifest" + fi +fi + +resolve_runfile() { + local path="${1:-}" + local candidate + local resolved + + if [[ -z ${path} ]]; then + echo "Error: missing runfile path" >&2 + exit 1 + fi + if [[ ${path} == /* || ${path} =~ ^[A-Za-z]:[\\/] ]]; then + printf '%s\n' "${path}" + return 0 + fi + if [[ -e ${path} ]]; then + printf '%s\n' "${path}" + return 0 + fi + + for candidate in \ + "${path}" \ + "${TEST_WORKSPACE:-}/${path}" \ + "_main/${path}"; do + [[ -z ${candidate} ]] && continue + if [[ -n ${RUNFILES_DIR:-} && -e "${RUNFILES_DIR}/${candidate}" ]]; then + printf '%s\n' "${RUNFILES_DIR}/${candidate}" + return 0 + fi + if [[ -n ${RUNFILES_MANIFEST_FILE:-} ]]; then + resolved="$( + awk -v key="${candidate}" 'index($0, key " ") == 1 { print substr($0, length(key) + 2); exit }' \ + "${RUNFILES_MANIFEST_FILE}" + )" + if [[ -n ${resolved} ]]; then + printf '%s\n' "${resolved}" + return 0 + fi + fi + done + + echo "Error: unable to resolve runfile: ${path}" >&2 + exit 1 +} + +workflow_file="$(resolve_runfile "${1:-}")" if [ -z "${workflow_file}" ]; then echo "Error: workflow file path required as first argument" >&2 exit 1 diff --git a/tests/ci_test/phase8_ci_targets_test.sh b/tests/ci_test/phase8_ci_targets_test.sh index 9be6cfe..119b8f3 100755 --- a/tests/ci_test/phase8_ci_targets_test.sh +++ b/tests/ci_test/phase8_ci_targets_test.sh @@ -1,7 +1,63 @@ #!/usr/bin/env bash set -euo pipefail -resolver="${1:-}" +if [[ -z ${RUNFILES_DIR:-} && -n ${TEST_SRCDIR:-} && -d ${TEST_SRCDIR} ]]; then + RUNFILES_DIR="${TEST_SRCDIR}" +fi +if [[ -z ${RUNFILES_DIR:-} && -z ${RUNFILES_MANIFEST_FILE:-} ]]; then + if [[ -d "$0.runfiles" ]]; then + RUNFILES_DIR="$0.runfiles" + elif [[ -f "$0.runfiles_manifest" ]]; then + RUNFILES_MANIFEST_FILE="$0.runfiles_manifest" + elif [[ -f "$0.exe.runfiles_manifest" ]]; then + RUNFILES_MANIFEST_FILE="$0.exe.runfiles_manifest" + fi +fi + +resolve_runfile() { + local path="${1:-}" + local candidate + local resolved + + if [[ -z ${path} ]]; then + echo "Error: missing runfile path" >&2 + exit 1 + fi + if [[ ${path} == /* || ${path} =~ ^[A-Za-z]:[\\/] ]]; then + printf '%s\n' "${path}" + return 0 + fi + if [[ -e ${path} ]]; then + printf '%s\n' "${path}" + return 0 + fi + + for candidate in \ + "${path}" \ + "${TEST_WORKSPACE:-}/${path}" \ + "_main/${path}"; do + [[ -z ${candidate} ]] && continue + if [[ -n ${RUNFILES_DIR:-} && -e "${RUNFILES_DIR}/${candidate}" ]]; then + printf '%s\n' "${RUNFILES_DIR}/${candidate}" + return 0 + fi + if [[ -n ${RUNFILES_MANIFEST_FILE:-} ]]; then + resolved="$( + awk -v key="${candidate}" 'index($0, key " ") == 1 { print substr($0, length(key) + 2); exit }' \ + "${RUNFILES_MANIFEST_FILE}" + )" + if [[ -n ${resolved} ]]; then + printf '%s\n' "${resolved}" + return 0 + fi + fi + done + + echo "Error: unable to resolve runfile: ${path}" >&2 + exit 1 +} + +resolver="$(resolve_runfile "${1:-}")" if [[ -z ${resolver} ]]; then echo "Error: resolver path required as first argument" >&2 exit 1 diff --git a/tests/integration_test/examples_basic_run_e2e_test.sh b/tests/integration_test/examples_basic_run_e2e_test.sh index 8b86842..30447a4 100755 --- a/tests/integration_test/examples_basic_run_e2e_test.sh +++ b/tests/integration_test/examples_basic_run_e2e_test.sh @@ -19,12 +19,7 @@ start_launcher() { local log_target="$2" shift 2 if [[ ${launcher} == *.cmd ]]; then - local command - printf -v command '"%s"' "${launcher}" - for arg in "$@"; do - printf -v command '%s "%s"' "${command}" "${arg}" - done - cmd.exe /c "${command}" >"${log_target}" 2>&1 & + cmd.exe /c call "${launcher}" "$@" >"${log_target}" 2>&1 & else "${launcher}" "$@" >"${log_target}" 2>&1 & fi diff --git a/tests/integration_test/examples_vite_monorepo_e2e_test.sh b/tests/integration_test/examples_vite_monorepo_e2e_test.sh index d555515..d4affcb 100755 --- a/tests/integration_test/examples_vite_monorepo_e2e_test.sh +++ b/tests/integration_test/examples_vite_monorepo_e2e_test.sh @@ -22,12 +22,7 @@ start_launcher() { local log_target="$2" shift 2 if [[ ${launcher} == *.cmd ]]; then - local command - printf -v command '"%s"' "${launcher}" - for arg in "$@"; do - printf -v command '%s "%s"' "${command}" "${arg}" - done - cmd.exe /c "${command}" >"${log_target}" 2>&1 & + cmd.exe /c call "${launcher}" "$@" >"${log_target}" 2>&1 & else "${launcher}" "$@" >"${log_target}" 2>&1 & fi diff --git a/tests/js_compat_test/run_binary.sh b/tests/js_compat_test/run_binary.sh index 8385dc0..b56e5ed 100755 --- a/tests/js_compat_test/run_binary.sh +++ b/tests/js_compat_test/run_binary.sh @@ -7,12 +7,7 @@ run_launcher() { local launcher="$1" shift if [[ ${launcher} == *.cmd ]]; then - local command - printf -v command '"%s"' "${launcher}" - for arg in "$@"; do - printf -v command '%s "%s"' "${command}" "${arg}" - done - cmd.exe /c "${command}" | tr -d '\r' + cmd.exe /c call "${launcher}" "$@" | tr -d '\r' return 0 fi "${launcher}" "$@" diff --git a/tests/js_compat_test/run_devserver.sh b/tests/js_compat_test/run_devserver.sh index 21babc9..f49d455 100755 --- a/tests/js_compat_test/run_devserver.sh +++ b/tests/js_compat_test/run_devserver.sh @@ -7,12 +7,7 @@ run_launcher() { local launcher="$1" shift if [[ ${launcher} == *.cmd ]]; then - local command - printf -v command '"%s"' "${launcher}" - for arg in "$@"; do - printf -v command '%s "%s"' "${command}" "${arg}" - done - cmd.exe /c "${command}" | tr -d '\r' + cmd.exe /c call "${launcher}" "$@" | tr -d '\r' return 0 fi "${launcher}" "$@" diff --git a/tests/script_test/run_env_script.sh b/tests/script_test/run_env_script.sh index dfa6743..bdf8130 100755 --- a/tests/script_test/run_env_script.sh +++ b/tests/script_test/run_env_script.sh @@ -7,12 +7,7 @@ run_launcher() { local launcher="$1" shift if [[ ${launcher} == *.cmd ]]; then - local command - printf -v command '"%s"' "${launcher}" - for arg in "$@"; do - printf -v command '%s "%s"' "${command}" "${arg}" - done - cmd.exe /c "${command}" | tr -d '\r' + cmd.exe /c call "${launcher}" "$@" | tr -d '\r' return 0 fi "${launcher}" "$@" diff --git a/tests/script_test/run_paraglide_monorepo_builds.sh b/tests/script_test/run_paraglide_monorepo_builds.sh index 96c4f99..ad6cece 100755 --- a/tests/script_test/run_paraglide_monorepo_builds.sh +++ b/tests/script_test/run_paraglide_monorepo_builds.sh @@ -14,12 +14,7 @@ run_launcher() { local launcher="$1" shift if [[ ${launcher} == *.cmd ]]; then - local command - printf -v command '"%s"' "${launcher}" - for arg in "$@"; do - printf -v command '%s "%s"' "${command}" "${arg}" - done - cmd.exe /c "${command}" | tr -d '\r' + cmd.exe /c call "${launcher}" "$@" | tr -d '\r' return 0 fi "${launcher}" "$@" diff --git a/tests/script_test/run_script.sh b/tests/script_test/run_script.sh index 715af61..cb8e3a1 100755 --- a/tests/script_test/run_script.sh +++ b/tests/script_test/run_script.sh @@ -8,12 +8,7 @@ run_launcher() { local launcher="$1" shift if [[ ${launcher} == *.cmd ]]; then - local command - printf -v command '"%s"' "${launcher}" - for arg in "$@"; do - printf -v command '%s "%s"' "${command}" "${arg}" - done - cmd.exe /c "${command}" | tr -d '\r' + cmd.exe /c call "${launcher}" "$@" | tr -d '\r' return 0 fi "${launcher}" "$@" diff --git a/tests/script_test/run_vite_app.sh b/tests/script_test/run_vite_app.sh index 4419c68..7162413 100755 --- a/tests/script_test/run_vite_app.sh +++ b/tests/script_test/run_vite_app.sh @@ -19,12 +19,7 @@ start_launcher() { local log_target="$2" shift 2 if [[ ${launcher} == *.cmd ]]; then - local command - printf -v command '"%s"' "${launcher}" - for arg in "$@"; do - printf -v command '%s "%s"' "${command}" "${arg}" - done - cmd.exe /c "${command}" >"${log_target}" 2>&1 & + cmd.exe /c call "${launcher}" "$@" >"${log_target}" 2>&1 & else "${launcher}" "$@" >"${log_target}" 2>&1 & fi diff --git a/tests/script_test/run_vite_monorepo_apps.sh b/tests/script_test/run_vite_monorepo_apps.sh index d555515..d4affcb 100755 --- a/tests/script_test/run_vite_monorepo_apps.sh +++ b/tests/script_test/run_vite_monorepo_apps.sh @@ -22,12 +22,7 @@ start_launcher() { local log_target="$2" shift 2 if [[ ${launcher} == *.cmd ]]; then - local command - printf -v command '"%s"' "${launcher}" - for arg in "$@"; do - printf -v command '%s "%s"' "${command}" "${arg}" - done - cmd.exe /c "${command}" >"${log_target}" 2>&1 & + cmd.exe /c call "${launcher}" "$@" >"${log_target}" 2>&1 & else "${launcher}" "$@" >"${log_target}" 2>&1 & fi diff --git a/tests/script_test/run_workspace_parallel.sh b/tests/script_test/run_workspace_parallel.sh index 3ce3261..b9179fd 100755 --- a/tests/script_test/run_workspace_parallel.sh +++ b/tests/script_test/run_workspace_parallel.sh @@ -7,12 +7,7 @@ run_launcher() { local launcher="$1" shift if [[ ${launcher} == *.cmd ]]; then - local command - printf -v command '"%s"' "${launcher}" - for arg in "$@"; do - printf -v command '%s "%s"' "${command}" "${arg}" - done - cmd.exe /c "${command}" | tr -d '\r' + cmd.exe /c call "${launcher}" "$@" | tr -d '\r' return 0 fi "${launcher}" "$@" diff --git a/tests/script_test/run_workspace_script.sh b/tests/script_test/run_workspace_script.sh index bc9da51..9b62341 100755 --- a/tests/script_test/run_workspace_script.sh +++ b/tests/script_test/run_workspace_script.sh @@ -7,12 +7,7 @@ run_launcher() { local launcher="$1" shift if [[ ${launcher} == *.cmd ]]; then - local command - printf -v command '"%s"' "${launcher}" - for arg in "$@"; do - printf -v command '%s "%s"' "${command}" "${arg}" - done - cmd.exe /c "${command}" | tr -d '\r' + cmd.exe /c call "${launcher}" "$@" | tr -d '\r' return 0 fi "${launcher}" "$@" diff --git a/tests/toolchain_test/BUILD.bazel b/tests/toolchain_test/BUILD.bazel index 9c7a684..2768c4b 100644 --- a/tests/toolchain_test/BUILD.bazel +++ b/tests/toolchain_test/BUILD.bazel @@ -45,12 +45,12 @@ sh_test( size = "small", srcs = ["toolchain_version.sh"], args = select({ - ":linux_x86_64": ["$(location @bun_linux_x64//:bun)"], - ":linux_aarch64": ["$(location @bun_linux_aarch64//:bun)"], - ":darwin_x86_64": ["$(location @bun_darwin_x64//:bun)"], - ":darwin_aarch64": ["$(location @bun_darwin_aarch64//:bun)"], - ":windows_x86_64": ["$(location @bun_windows_x64//:bun)"], - "//conditions:default": ["$(location @bun_linux_x64//:bun)"], + ":linux_x86_64": ["$(rlocationpath @bun_linux_x64//:bun)"], + ":linux_aarch64": ["$(rlocationpath @bun_linux_aarch64//:bun)"], + ":darwin_x86_64": ["$(rlocationpath @bun_darwin_x64//:bun)"], + ":darwin_aarch64": ["$(rlocationpath @bun_darwin_aarch64//:bun)"], + ":windows_x86_64": ["$(rlocationpath @bun_windows_x64//:bun)"], + "//conditions:default": ["$(rlocationpath @bun_linux_x64//:bun)"], }), data = select({ ":linux_x86_64": ["@bun_linux_x64//:bun"], @@ -66,6 +66,6 @@ sh_test( name = "toolchain_resolution_matrix_test", size = "small", srcs = ["toolchain_resolution_matrix.sh"], - args = ["$(location //tests/toolchain_test:BUILD.bazel)"], + args = ["$(rlocationpath //tests/toolchain_test:BUILD.bazel)"], data = ["//tests/toolchain_test:BUILD.bazel"], ) diff --git a/tests/toolchain_test/toolchain_resolution_matrix.sh b/tests/toolchain_test/toolchain_resolution_matrix.sh index 3ec8da9..577ab80 100755 --- a/tests/toolchain_test/toolchain_resolution_matrix.sh +++ b/tests/toolchain_test/toolchain_resolution_matrix.sh @@ -1,7 +1,63 @@ #!/usr/bin/env bash set -euo pipefail -build_file="$1" +if [[ -z ${RUNFILES_DIR:-} && -n ${TEST_SRCDIR:-} && -d ${TEST_SRCDIR} ]]; then + RUNFILES_DIR="${TEST_SRCDIR}" +fi +if [[ -z ${RUNFILES_DIR:-} && -z ${RUNFILES_MANIFEST_FILE:-} ]]; then + if [[ -d "$0.runfiles" ]]; then + RUNFILES_DIR="$0.runfiles" + elif [[ -f "$0.runfiles_manifest" ]]; then + RUNFILES_MANIFEST_FILE="$0.runfiles_manifest" + elif [[ -f "$0.exe.runfiles_manifest" ]]; then + RUNFILES_MANIFEST_FILE="$0.exe.runfiles_manifest" + fi +fi + +resolve_runfile() { + local path="${1:-}" + local candidate + local resolved + + if [[ -z ${path} ]]; then + echo "Error: missing runfile path" >&2 + exit 1 + fi + if [[ ${path} == /* || ${path} =~ ^[A-Za-z]:[\\/] ]]; then + printf '%s\n' "${path}" + return 0 + fi + if [[ -e ${path} ]]; then + printf '%s\n' "${path}" + return 0 + fi + + for candidate in \ + "${path}" \ + "${TEST_WORKSPACE:-}/${path}" \ + "_main/${path}"; do + [[ -z ${candidate} ]] && continue + if [[ -n ${RUNFILES_DIR:-} && -e "${RUNFILES_DIR}/${candidate}" ]]; then + printf '%s\n' "${RUNFILES_DIR}/${candidate}" + return 0 + fi + if [[ -n ${RUNFILES_MANIFEST_FILE:-} ]]; then + resolved="$( + awk -v key="${candidate}" 'index($0, key " ") == 1 { print substr($0, length(key) + 2); exit }' \ + "${RUNFILES_MANIFEST_FILE}" + )" + if [[ -n ${resolved} ]]; then + printf '%s\n' "${resolved}" + return 0 + fi + fi + done + + echo "Error: unable to resolve runfile: ${path}" >&2 + exit 1 +} + +build_file="$(resolve_runfile "${1:-}")" grep -Eq 'name = "linux_x86_64"' "${build_file}" grep -Eq 'name = "linux_aarch64"' "${build_file}" diff --git a/tests/toolchain_test/toolchain_version.sh b/tests/toolchain_test/toolchain_version.sh index 73e1387..4b0be73 100755 --- a/tests/toolchain_test/toolchain_version.sh +++ b/tests/toolchain_test/toolchain_version.sh @@ -1,8 +1,64 @@ #!/usr/bin/env bash set -euo pipefail -bun_path="$1" -version="$(${bun_path} --version)" +if [[ -z ${RUNFILES_DIR:-} && -n ${TEST_SRCDIR:-} && -d ${TEST_SRCDIR} ]]; then + RUNFILES_DIR="${TEST_SRCDIR}" +fi +if [[ -z ${RUNFILES_DIR:-} && -z ${RUNFILES_MANIFEST_FILE:-} ]]; then + if [[ -d "$0.runfiles" ]]; then + RUNFILES_DIR="$0.runfiles" + elif [[ -f "$0.runfiles_manifest" ]]; then + RUNFILES_MANIFEST_FILE="$0.runfiles_manifest" + elif [[ -f "$0.exe.runfiles_manifest" ]]; then + RUNFILES_MANIFEST_FILE="$0.exe.runfiles_manifest" + fi +fi + +resolve_runfile() { + local path="${1:-}" + local candidate + local resolved + + if [[ -z ${path} ]]; then + echo "Error: missing runfile path" >&2 + exit 1 + fi + if [[ ${path} == /* || ${path} =~ ^[A-Za-z]:[\\/] ]]; then + printf '%s\n' "${path}" + return 0 + fi + if [[ -e ${path} ]]; then + printf '%s\n' "${path}" + return 0 + fi + + for candidate in \ + "${path}" \ + "${TEST_WORKSPACE:-}/${path}" \ + "_main/${path}"; do + [[ -z ${candidate} ]] && continue + if [[ -n ${RUNFILES_DIR:-} && -e "${RUNFILES_DIR}/${candidate}" ]]; then + printf '%s\n' "${RUNFILES_DIR}/${candidate}" + return 0 + fi + if [[ -n ${RUNFILES_MANIFEST_FILE:-} ]]; then + resolved="$( + awk -v key="${candidate}" 'index($0, key " ") == 1 { print substr($0, length(key) + 2); exit }' \ + "${RUNFILES_MANIFEST_FILE}" + )" + if [[ -n ${resolved} ]]; then + printf '%s\n' "${resolved}" + return 0 + fi + fi + done + + echo "Error: unable to resolve runfile: ${path}" >&2 + exit 1 +} + +bun_path="$(resolve_runfile "${1:-}")" +version="$("${bun_path}" --version)" if [[ ! ${version} =~ ^[0-9]+\.[0-9]+\.[0-9]+ ]]; then echo "Unexpected bun version output: ${version}" >&2