Skip to content

Commit 34056f9

Browse files
committed
test(session): fail git without rewriting PATH
Bun resolves execFileSync("git") from the startup PATH, so rewriting PATH neither wraps nor hides git. Count real rev-parse starts with GIT_TRACE2_EVENT, and point GIT_DIR at a missing directory to fail it.
1 parent eac8b3f commit 34056f9

1 file changed

Lines changed: 22 additions & 40 deletions

File tree

‎src/session/project-key.test.ts‎

Lines changed: 22 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { afterEach, beforeEach, expect, test } from "bun:test";
2-
import { chmod, mkdir, readFile, rm, writeFile } from "node:fs/promises";
2+
import { mkdir, readFile, rm, writeFile } from "node:fs/promises";
33
import { realpathSync } from "node:fs";
4-
import { delimiter, join } from "node:path";
4+
import { join } from "node:path";
55
import { tmpdir } from "node:os";
66
import { execFileSync } from "node:child_process";
77

@@ -27,10 +27,6 @@ afterEach(async () => {
2727
await rm(root, { recursive: true, force: true });
2828
});
2929

30-
function shQuote(value: string): string {
31-
return `'${value.replaceAll("'", "'\\''")}'`;
32-
}
33-
3430
async function commitReadme(dir: string): Promise<void> {
3531
await writeFile(join(dir, "README"), "x");
3632
execFileSync("git", ["add", "README"], { cwd: dir, stdio: "ignore" });
@@ -59,41 +55,26 @@ test("projectRootFor spawns git rev-parse once for the same cwd", async () => {
5955
initTemporaryGitRepo(root);
6056
await commitReadme(root);
6157

62-
const countFile = join(root, "rev-parse-spawns");
63-
await writeFile(countFile, "0\n");
64-
const realGit = execFileSync("/usr/bin/which", ["git"], {
65-
encoding: "utf8",
66-
}).trim();
67-
const bin = join(root, "git-bin");
68-
await mkdir(bin);
69-
const wrapper = join(bin, "git");
70-
const resolved = realpathSync(root);
71-
await writeFile(
72-
wrapper,
73-
`#!/bin/sh
74-
if [ "$1" = "rev-parse" ] && [ "$(pwd)" = ${shQuote(resolved)} ]; then
75-
n=$(cat ${shQuote(countFile)})
76-
echo $((n + 1)) > ${shQuote(countFile)}
77-
fi
78-
exec ${shQuote(realGit)} "$@"
79-
`,
80-
);
81-
await chmod(wrapper, 0o755);
82-
83-
const previousPath = process.env.PATH;
84-
process.env.PATH = `${bin}${delimiter}${previousPath ?? ""}`;
58+
const traceFile = join(root, "git-trace2-events");
59+
const previousTrace = process.env.GIT_TRACE2_EVENT;
60+
process.env.GIT_TRACE2_EVENT = traceFile;
8561
try {
8662
const first = projectRootFor(root);
8763
const second = projectRootFor(root);
8864
expect(second).toBe(first);
8965
expect(first).toBe(realpathSync(root));
90-
const spawns = Number((await readFile(countFile, "utf8")).trim());
66+
const spawns = (await readFile(traceFile, "utf8"))
67+
.split("\n")
68+
.filter(
69+
(line) =>
70+
line.includes('"event":"start"') && line.includes("rev-parse"),
71+
).length;
9172
expect(spawns).toBe(1);
9273
} finally {
93-
if (previousPath === undefined) {
94-
delete process.env.PATH;
74+
if (previousTrace === undefined) {
75+
delete process.env.GIT_TRACE2_EVENT;
9576
} else {
96-
process.env.PATH = previousPath;
77+
process.env.GIT_TRACE2_EVENT = previousTrace;
9778
}
9879
}
9980
});
@@ -116,18 +97,19 @@ test("projectRootFor retries a nested dir after git was unavailable", async () =
11697
const nested = join(root, "nested");
11798
await mkdir(nested);
11899
const parent = realpathSync(root);
119-
const emptyBin = join(root, "empty-bin");
120-
await mkdir(emptyBin);
100+
// Bun resolves execFileSync("git") from the startup PATH, so emptying PATH
101+
// does not hide git. A missing GIT_DIR is forwarded and makes rev-parse fail.
102+
const missingGitDir = join(root, "missing-git-dir");
121103

122-
const previousPath = process.env.PATH;
123-
process.env.PATH = emptyBin;
104+
const previousGitDir = process.env.GIT_DIR;
105+
process.env.GIT_DIR = missingGitDir;
124106
try {
125107
expect(projectRootFor(nested)).toBe(realpathSync(nested));
126108
} finally {
127-
if (previousPath === undefined) {
128-
delete process.env.PATH;
109+
if (previousGitDir === undefined) {
110+
delete process.env.GIT_DIR;
129111
} else {
130-
process.env.PATH = previousPath;
112+
process.env.GIT_DIR = previousGitDir;
131113
}
132114
}
133115
expect(projectRootFor(nested)).toBe(parent);

0 commit comments

Comments
 (0)