Files
bun.sh/test/cli/install/bun-run-bunfig.test.ts
Michael H 767e03ef24 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>
2025-10-08 12:13:06 -07:00

251 lines
6.4 KiB
TypeScript

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"];
const node = Bun.which("node")!;
const execPath = process.execPath;
describe.each(["--bun", "without --bun"])("%s", cmd2 => {
test("which node", async () => {
const bun = cmd2 === "--bun";
const bunFlag = bun ? ["--bun"] : [];
const bunfig = toTOMLString({
run: {
bun,
},
});
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", ...bunFlag, ...runCmd, "where-node"],
env: bunEnv,
stderr: "inherit",
stdout: "pipe",
stdin: "ignore",
cwd,
});
const nodeBin = result.stdout.toString().trim();
if (bun) {
if (isWindows) {
expect(realpathSync(nodeBin)).toContain("\\bun-node-");
} else {
expect(realpathSync(nodeBin)).toBe(realpathSync(execPath));
}
} else {
expect(realpathSync(nodeBin)).toBe(realpathSync(node));
}
expect(result.success).toBeTrue();
});
});
describe.each(["bun", "system", "default"])(`run.shell = "%s"`, shellStr => {
if (isWindows && shellStr === "system") return; // windows always uses the bun shell now
const shell = shellStr === "default" ? (isWindows ? "bun" : "system") : shellStr;
const command_not_found =
isWindows && shell === "system" ? "is not recognized as an internal or external command" : "command not found";
test.each(["true", "false"])('run.silent = "%s"', silentStr => {
const silent = silentStr === "true";
const bunfig = toTOMLString({
run: {
shell: shellStr === "default" ? undefined : shell,
silent,
},
});
const cwd = tempDirWithFiles(Bun.hash(bunfig).toString(36), {
"bunfig.toml": bunfig,
"package.json": JSON.stringify(
{
scripts: {
startScript: "echo 1",
},
},
null,
2,
),
});
const result = Bun.spawnSync({
cmd: [bunExe(), ...runCmd, "startScript"],
env: bunEnv,
stderr: "pipe",
stdout: "pipe",
stdin: "ignore",
cwd,
});
if (silent) {
expect(result.stderr.toString().trim()).toBe("");
} else {
expect(result.stderr.toString().trim()).toContain("$ echo 1");
}
expect(result.success).toBeTrue();
});
test("command not found", async () => {
const bunfig = toTOMLString({
run: {
shell,
},
});
const cwd = tempDirWithFiles("run.shell.system-" + Bun.hash(bunfig).toString(32), {
"bunfig.toml": bunfig,
"package.json": JSON.stringify(
{
scripts: {
start: "this-should-start-with-bun-in-the-error-message",
},
},
null,
2,
),
});
const result = Bun.spawnSync({
cmd: [bunExe(), "--silent", ...runCmd, "start"],
env: bunEnv,
stderr: "pipe",
stdout: "inherit",
stdin: "ignore",
cwd,
});
const err = result.stderr.toString().trim();
expect(err).toContain(command_not_found);
expect(err).toContain("this-should-start-with-bun-in-the-error-message");
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();
});
});