Skip to content

Commit ba42621

Browse files
robobunClaude Botclaude
authored
fix(shell): handle ".", "", "./" in cwd() by using process.cwd() (#26461)
## Summary - Fix `$`...`.cwd(".")` causing ENOENT error with path ending in "undefined" - The same fix applies to `.cwd("")` and `.cwd("./")` - Falls back to `process.cwd()` when `defaultCwd` is undefined Closes #26460 ## Test plan - [x] Added regression test in `test/regression/issue/26460.test.ts` - [x] Verified test fails with `USE_SYSTEM_BUN=1` (reproduces the bug) - [x] Verified test passes with `bun bd test` (fix works) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Bot <claude-bot@bun.sh> Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
1 parent bd63fb9 commit ba42621

File tree

2 files changed

+105
-2
lines changed

2 files changed

+105
-2
lines changed

src/js/builtins/shell.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ export function createBunShellTemplateFunction(createShellInterpreter_, createPa
149149
cwd(newCwd?: string): this {
150150
this.#throwIfRunning();
151151
if (typeof newCwd === "undefined" || newCwd === "." || newCwd === "" || newCwd === "./") {
152-
newCwd = defaultCwd;
152+
newCwd = defaultCwd ?? process.cwd();
153153
}
154154
this.#args!.setCwd(newCwd);
155155
return this;
@@ -277,7 +277,7 @@ export function createBunShellTemplateFunction(createShellInterpreter_, createPa
277277
cwd(newCwd: string | undefined) {
278278
if (typeof newCwd === "undefined" || typeof newCwd === "string") {
279279
if (newCwd === "." || newCwd === "" || newCwd === "./") {
280-
newCwd = defaultCwd;
280+
newCwd = defaultCwd ?? process.cwd();
281281
}
282282

283283
this[cwdSymbol] = newCwd;
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
import { expect, test } from "bun:test";
2+
import { bunEnv, bunExe, tempDir } from "harness";
3+
4+
// Regression test for https://github.com/oven-sh/bun/issues/26460
5+
// Using $`...`.cwd(".") should work and use the current working directory
6+
7+
test("shell cwd('.') should use current working directory", async () => {
8+
using dir = tempDir("shell-cwd-dot", {
9+
"test.js": `
10+
import { $ } from "bun";
11+
const result = await $\`pwd\`.cwd(".").text();
12+
console.log(result.trim());
13+
`,
14+
});
15+
16+
await using proc = Bun.spawn({
17+
cmd: [bunExe(), "test.js"],
18+
env: bunEnv,
19+
cwd: String(dir),
20+
stdout: "pipe",
21+
stderr: "pipe",
22+
});
23+
24+
const [stdout, stderr, exitCode] = await Promise.all([proc.stdout.text(), proc.stderr.text(), proc.exited]);
25+
26+
expect(stderr).toBe("");
27+
expect(stdout.trim()).toBe(String(dir));
28+
expect(exitCode).toBe(0);
29+
});
30+
31+
test("shell cwd('') should use current working directory", async () => {
32+
using dir = tempDir("shell-cwd-empty", {
33+
"test.js": `
34+
import { $ } from "bun";
35+
const result = await $\`pwd\`.cwd("").text();
36+
console.log(result.trim());
37+
`,
38+
});
39+
40+
await using proc = Bun.spawn({
41+
cmd: [bunExe(), "test.js"],
42+
env: bunEnv,
43+
cwd: String(dir),
44+
stdout: "pipe",
45+
stderr: "pipe",
46+
});
47+
48+
const [stdout, stderr, exitCode] = await Promise.all([proc.stdout.text(), proc.stderr.text(), proc.exited]);
49+
50+
expect(stderr).toBe("");
51+
expect(stdout.trim()).toBe(String(dir));
52+
expect(exitCode).toBe(0);
53+
});
54+
55+
test("shell cwd('./') should use current working directory", async () => {
56+
using dir = tempDir("shell-cwd-dotslash", {
57+
"test.js": `
58+
import { $ } from "bun";
59+
const result = await $\`pwd\`.cwd("./").text();
60+
console.log(result.trim());
61+
`,
62+
});
63+
64+
await using proc = Bun.spawn({
65+
cmd: [bunExe(), "test.js"],
66+
env: bunEnv,
67+
cwd: String(dir),
68+
stdout: "pipe",
69+
stderr: "pipe",
70+
});
71+
72+
const [stdout, stderr, exitCode] = await Promise.all([proc.stdout.text(), proc.stderr.text(), proc.exited]);
73+
74+
expect(stderr).toBe("");
75+
expect(stdout.trim()).toBe(String(dir));
76+
expect(exitCode).toBe(0);
77+
});
78+
79+
test("Shell prototype cwd('.') should use current working directory", async () => {
80+
using dir = tempDir("shell-proto-cwd-dot", {
81+
"test.js": `
82+
import { $ } from "bun";
83+
const shell = new $.Shell();
84+
shell.cwd(".");
85+
const result = await shell\`pwd\`.text();
86+
console.log(result.trim());
87+
`,
88+
});
89+
90+
await using proc = Bun.spawn({
91+
cmd: [bunExe(), "test.js"],
92+
env: bunEnv,
93+
cwd: String(dir),
94+
stdout: "pipe",
95+
stderr: "pipe",
96+
});
97+
98+
const [stdout, stderr, exitCode] = await Promise.all([proc.stdout.text(), proc.stderr.text(), proc.exited]);
99+
100+
expect(stderr).toBe("");
101+
expect(stdout.trim()).toBe(String(dir));
102+
expect(exitCode).toBe(0);
103+
});

0 commit comments

Comments
 (0)