Skip to content

Commit a29553e

Browse files
t3dotggclaude
andcommitted
build(setup): wait for the installer before marking a cancelled setup
Co-Authored-By: Claude Opus 5.5 <[email protected]>
1 parent d0ee415 commit a29553e

1 file changed

Lines changed: 18 additions & 5 deletions

File tree

‎scripts/setup-worktree.ts‎

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,17 @@ process.on("exit", (code) => {
2828
NodeFS.rmSync(runningMarker, { force: true });
2929
});
3030
// A cancelled setup must still leave a marker, or agents would wait forever.
31+
// During install, the signal goes on to the installer and setup exits when the
32+
// install output closes. Any child the shell leaves behind holds that output
33+
// open, so no marker appears while `vp i` can still write node_modules.
34+
let cancelSignal: NodeJS.Signals | undefined;
35+
let activeInstall: NodeChildProcess.ChildProcess | undefined;
3136
for (const signal of ["SIGINT", "SIGTERM", "SIGHUP"] as const) {
32-
process.on(signal, () => process.exit(1));
37+
process.on(signal, () => {
38+
cancelSignal = signal;
39+
if (activeInstall) activeInstall.kill(signal);
40+
else process.exit(1);
41+
});
3342
}
3443

3544
const projectRoot = process.env.T3CODE_PROJECT_ROOT;
@@ -48,6 +57,7 @@ const install = NodeChildProcess.spawn("vp i --frozen-lockfile -- --yes", {
4857
shell: true,
4958
stdio: ["ignore", "pipe", "pipe"],
5059
});
60+
activeInstall = install;
5161
let installOutput = "";
5262
for (const [source, target] of [
5363
[install.stdout, process.stdout],
@@ -60,9 +70,12 @@ for (const [source, target] of [
6070
});
6171
}
6272
const installStatus = await new Promise<number | null>((resolve) => install.on("close", resolve));
63-
if (installStatus !== 0) {
64-
failureDetail = installOutput.trimEnd().split("\n").slice(-30).join("\n");
65-
process.exit(installStatus ?? 1);
73+
activeInstall = undefined;
74+
if (installStatus !== 0 || cancelSignal) {
75+
failureDetail = cancelSignal
76+
? `Cancelled by ${cancelSignal}.`
77+
: installOutput.trimEnd().split("\n").slice(-30).join("\n");
78+
process.exit(installStatus || 1);
6679
}
6780

6881
// pnpm cannot clone or hardlink across filesystems, so a store on another
@@ -82,7 +95,7 @@ if (
8295
` worktree: ${worktree}`,
8396
"pnpm cannot hardlink or clone across filesystems, so it copied every package into node_modules.",
8497
"Fix: put the store on the worktree's filesystem, for example:",
85-
` pnpm config set store-dir ${NodePath.join(NodePath.dirname(worktree), ".pnpm-store")} --global`,
98+
` pnpm config set store-dir ${JSON.stringify(NodePath.join(NodePath.dirname(worktree), ".pnpm-store"))} --global`,
8699
"",
87100
"",
88101
].join("\n"),

0 commit comments

Comments
 (0)