ci: fix dependencies

This commit is contained in:
eric
2026-03-15 13:54:18 +01:00
parent 54109136ab
commit f975f12553
37 changed files with 522 additions and 148 deletions

View File

@@ -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.",
),
})

View File

@@ -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.",
),
})

View File

@@ -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,

View File

@@ -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.",
),
})

View File

@@ -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.",
),
})

View File

@@ -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);