load local bunfig.toml for bun run earlier (for run.bun option) (#16664)

Alternative to #15596 where it now only impacts `bun run` for the same
cwd dir. This does not effect `bunx` ([even though according to code it
should load
it](7830e15650/src/cli.zig (L2597-L2628))),
and isnt as fancy as `bun install` where it ensures to check the bunfig
in `package.json` dir.

This shouldn't have any performance issues because its already loading
the file, but now its loading earlier so it can use `run.bun` option.


Fixes #11445, (as well as fixes #15484, fixes #15483, fixes #17064)

---------

Co-authored-by: pfg <pfg@pfg.pw>
This commit is contained in:
Michael H
2025-10-09 06:13:06 +11:00
committed by GitHub
parent 93910f34da
commit 767e03ef24
3 changed files with 121 additions and 10 deletions

View File

@@ -651,7 +651,7 @@ editor = "code"
The `bun run` command can be configured under the `[run]` section. These apply to the `bun run` command and the `bun` command when running a file or executable or script.
Currently, `bunfig.toml` isn't always automatically loaded for `bun run` in a local project (it does check for a global `bunfig.toml`), so you might still need to pass `-c` or `-c=bunfig.toml` to use these settings.
Currently, `bunfig.toml` is only automatically loaded for `bun run` in a local project (it doesn't check for a global `.bunfig.toml`).
### `run.shell` - use the system shell or Bun's shell

View File

@@ -1320,10 +1320,6 @@ pub const RunCommand = struct {
};
}
if (!ctx.debug.loaded_bunfig) {
bun.cli.Arguments.loadConfigPath(ctx.allocator, true, "bunfig.toml", ctx, .RunCommand) catch {};
}
_ = _bootAndHandleError(ctx, absolute_script_path.?, null);
return true;
}
@@ -1368,11 +1364,14 @@ pub const RunCommand = struct {
}
}
if (!ctx.debug.loaded_bunfig) {
bun.cli.Arguments.loadConfigPath(ctx.allocator, true, "bunfig.toml", ctx, .RunCommand) catch {};
}
// try fast run (check if the file exists and is not a folder, then run it)
if (try_fast_run and maybeOpenWithBunJS(ctx)) return true;
// setup
const force_using_bun = ctx.debug.run_in_bun;
var ORIGINAL_PATH: string = "";
var this_transpiler: transpiler.Transpiler = undefined;
@@ -1380,10 +1379,6 @@ pub const RunCommand = struct {
try configurePathForRun(ctx, root_dir_info, &this_transpiler, &ORIGINAL_PATH, root_dir_info.abs_path, force_using_bun);
this_transpiler.env.map.put("npm_command", "run-script") catch unreachable;
if (!ctx.debug.loaded_bunfig) {
bun.cli.Arguments.loadConfigPath(ctx.allocator, true, "bunfig.toml", ctx, .RunCommand) catch {};
}
// check for empty command
if (target_name.len == 0) {

View File

@@ -1,6 +1,7 @@
import { describe, expect, test } from "bun:test";
import { realpathSync } from "fs";
import { bunEnv, bunExe, isWindows, tempDirWithFiles, toTOMLString } from "harness";
import { join as pathJoin } from "node:path";
describe.each(["bun run", "bun"])(`%s`, cmd => {
const runCmd = cmd === "bun" ? ["-c=bunfig.toml", "run"] : ["-c=bunfig.toml"];
@@ -131,4 +132,119 @@ describe.each(["bun run", "bun"])(`%s`, cmd => {
expect(result.success).toBeFalse();
});
});
test("autoload local bunfig.toml (same cwd)", async () => {
const runCmd = cmd === "bun" ? ["run"] : [];
const bunfig = toTOMLString({
run: {
bun: true,
},
});
const cwd = tempDirWithFiles("run.where.node", {
"bunfig.toml": bunfig,
"package.json": JSON.stringify(
{
scripts: {
"where-node": `which node`,
},
},
null,
2,
),
});
const result = Bun.spawnSync({
cmd: [bunExe(), "--silent", ...runCmd, "where-node"],
env: bunEnv,
stderr: "inherit",
stdout: "pipe",
stdin: "ignore",
cwd,
});
const nodeBin = result.stdout.toString().trim();
if (isWindows) {
expect(realpathSync(nodeBin)).toContain("\\bun-node-");
} else {
expect(realpathSync(nodeBin)).toBe(realpathSync(execPath));
}
});
test("NOT autoload local bunfig.toml (sub cwd)", async () => {
const runCmd = cmd === "bun" ? ["run"] : [];
const bunfig = toTOMLString({
run: {
bun: true,
},
});
const cwd = tempDirWithFiles("run.where.node", {
"bunfig.toml": bunfig,
"package.json": JSON.stringify(
{
scripts: {
"where-node": `which node`,
},
},
null,
2,
),
"subdir/a.txt": "a",
});
const result = Bun.spawnSync({
cmd: [bunExe(), "--silent", ...runCmd, "where-node"],
env: bunEnv,
stderr: "inherit",
stdout: "pipe",
stdin: "ignore",
cwd: pathJoin(cwd, "./subdir"),
});
const nodeBin = result.stdout.toString().trim();
expect(realpathSync(nodeBin)).toBe(realpathSync(node));
expect(result.success).toBeTrue();
});
test("NOT autoload home bunfig.toml", async () => {
const runCmd = cmd === "bun" ? ["run"] : [];
const bunfig = toTOMLString({
run: {
bun: true,
},
});
const cwd = tempDirWithFiles("run.where.node", {
"my-home/.bunfig.toml": bunfig,
"package.json": JSON.stringify(
{
scripts: {
"where-node": `which node`,
},
},
null,
2,
),
});
const result = Bun.spawnSync({
cmd: [bunExe(), "--silent", ...runCmd, "where-node"],
env: {
...bunEnv,
HOME: pathJoin(cwd, "./my-home"),
},
stderr: "inherit",
stdout: "pipe",
stdin: "ignore",
cwd,
});
const nodeBin = result.stdout.toString().trim();
expect(realpathSync(nodeBin)).toBe(realpathSync(node));
expect(result.success).toBeTrue();
});
});