diff --git a/docs/runtime/bunfig.md b/docs/runtime/bunfig.md index 9ec995161d..ca0a36f7eb 100644 --- a/docs/runtime/bunfig.md +++ b/docs/runtime/bunfig.md @@ -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 diff --git a/src/cli/run_command.zig b/src/cli/run_command.zig index c72159c96c..34873d6819 100644 --- a/src/cli/run_command.zig +++ b/src/cli/run_command.zig @@ -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) { diff --git a/test/cli/install/bun-run-bunfig.test.ts b/test/cli/install/bun-run-bunfig.test.ts index a5890fb92d..c3a90d514c 100644 --- a/test/cli/install/bun-run-bunfig.test.ts +++ b/test/cli/install/bun-run-bunfig.test.ts @@ -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(); + }); });