Files
gstack/test/helpers/emulate-bun-windows-eexist.ts
T
Lockyer 790c42505a fix(redact): tolerate EEXIST from recursive mkdir in install-prepush-hook on bun/Windows (#2635)
fs.mkdirSync(dir, { recursive: true }) is a no-op on an existing directory
in Node, but bun on Windows throws EEXIST - crashing hook install on any
repo whose .git/hooks already existed, leaving the repo unprotected.

Add lib/fs-utils.ts mkdirpSync: swallow EEXIST only when statSync confirms
the path is an existing directory; a regular file occupying the path, a
stat failure, or any other errno still rethrows. Use it in
installPrepushHook().

The regression test emulates the Windows bun fs semantics via a
bun --preload fixture, so the exact crash path runs (and fails on the old
code) on any platform, including CI Linux.

Absorbed from PR #2641 with authorship preserved.

Fixes #2635
2026-08-22 01:57:28 +00:00

21 lines
836 B
TypeScript

/**
* Bun --preload fixture that emulates bun-on-Windows fs.mkdirSync semantics
* (see #2635): a recursive mkdir on an already-existing directory throws
* EEXIST, where Node (and bun on Linux/macOS) treat it as a no-op success.
*
* Loaded into a child process with `bun --preload <this file> <script>`, it
* lets the #2635 regression test exercise the exact Windows crash path on any
* platform. The patch is deliberately transparent - it changes nothing except
* throwing EEXIST where Windows bun would.
*/
const fs = require("fs");
const orig = fs.mkdirSync;
fs.mkdirSync = (p: string, opts: any) => {
if (opts?.recursive && fs.existsSync(p) && fs.statSync(p).isDirectory()) {
const e = new Error(`EEXIST: file already exists, mkdir '${p}'`);
(e as any).code = "EEXIST";
throw e;
}
return orig(p, opts);
};