fix: wrap bunx with cmd shim on Windows#47751
Conversation
Greptile SummaryThis PR fixes Windows spawn failures for
Confidence Score: 4/5
Prompt To Fix All With AIThis is a comment left during a code review.
Path: src/process/exec.windows.test.ts
Line: 115-137
Comment:
**Inline assertions duplicate the existing helper**
The new test reinvents the same assertion pattern already present in `expectCmdWrappedInvocation` (lines 53-64), with the only difference being the command string (`"bunx.cmd --version"` vs the hardcoded `"pnpm.cmd --version"`). The helper is not reusable today because its inner check is hardcoded. Consider accepting the expected command substring as a parameter so both tests (and any future ones) can share the helper instead of copying the four `expect` lines each time:
```ts
function expectCmdWrappedInvocation(params: {
captured: SpawnCall | ExecCall | undefined;
expectedComSpec: string;
expectedCmdSubstring: string; // e.g. "pnpm.cmd --version" or "bunx.cmd --version"
}) {
if (!params.captured) {
throw new Error("expected command wrapper to be called");
}
expect(params.captured[0]).toBe(params.expectedComSpec);
expect(params.captured[1].slice(0, 3)).toEqual(["/d", "/s", "/c"]);
expect(params.captured[1][3]).toContain(params.expectedCmdSubstring);
expect(params.captured[2].windowsVerbatimArguments).toBe(true);
}
```
How can I resolve this? If you propose a fix, please make it concise.
---
This is a comment left during a code review.
Path: src/process/exec.windows.test.ts
Line: 137
Comment:
**Missing `runExec` coverage for `bunx`**
A parallel test exists for `pnpm` via `runExec` (the second test in the suite, lines 91-113) that exercises the `execFile` code path. The new test only covers `runCommandWithTimeout` (the `spawn` path). Because the `resolveCommand` call appears independently in both `runExec` and `runCommandWithTimeout`, adding a corresponding `runExec("bunx", ...)` test would give the same regression coverage as the existing pnpm pair, and keep the pattern symmetric.
How can I resolve this? If you propose a fix, please make it concise.Last reviewed commit: e3741ad |
| it("wraps bunx via cmd.exe in runCommandWithTimeout on Windows", async () => { | ||
| const platformSpy = vi.spyOn(process, "platform", "get").mockReturnValue("win32"); | ||
| const expectedComSpec = process.env.ComSpec ?? "cmd.exe"; | ||
|
|
||
| spawnMock.mockImplementation( | ||
| (_command: string, _args: string[], _options: Record<string, unknown>) => createMockChild(), | ||
| ); | ||
|
|
||
| try { | ||
| const result = await runCommandWithTimeout(["bunx", "--version"], { timeoutMs: 1000 }); | ||
| expect(result.code).toBe(0); | ||
| const captured = spawnMock.mock.calls[0] as SpawnCall | undefined; | ||
| if (!captured) { | ||
| throw new Error("expected command wrapper to be called"); | ||
| } | ||
| expect(captured[0]).toBe(expectedComSpec); | ||
| expect(captured[1].slice(0, 3)).toEqual(["/d", "/s", "/c"]); | ||
| expect(captured[1][3]).toContain("bunx.cmd --version"); | ||
| expect(captured[2].windowsVerbatimArguments).toBe(true); | ||
| } finally { | ||
| platformSpy.mockRestore(); | ||
| } | ||
| }); |
There was a problem hiding this comment.
Inline assertions duplicate the existing helper
The new test reinvents the same assertion pattern already present in expectCmdWrappedInvocation (lines 53-64), with the only difference being the command string ("bunx.cmd --version" vs the hardcoded "pnpm.cmd --version"). The helper is not reusable today because its inner check is hardcoded. Consider accepting the expected command substring as a parameter so both tests (and any future ones) can share the helper instead of copying the four expect lines each time:
function expectCmdWrappedInvocation(params: {
captured: SpawnCall | ExecCall | undefined;
expectedComSpec: string;
expectedCmdSubstring: string; // e.g. "pnpm.cmd --version" or "bunx.cmd --version"
}) {
if (!params.captured) {
throw new Error("expected command wrapper to be called");
}
expect(params.captured[0]).toBe(params.expectedComSpec);
expect(params.captured[1].slice(0, 3)).toEqual(["/d", "/s", "/c"]);
expect(params.captured[1][3]).toContain(params.expectedCmdSubstring);
expect(params.captured[2].windowsVerbatimArguments).toBe(true);
}Prompt To Fix With AI
This is a comment left during a code review.
Path: src/process/exec.windows.test.ts
Line: 115-137
Comment:
**Inline assertions duplicate the existing helper**
The new test reinvents the same assertion pattern already present in `expectCmdWrappedInvocation` (lines 53-64), with the only difference being the command string (`"bunx.cmd --version"` vs the hardcoded `"pnpm.cmd --version"`). The helper is not reusable today because its inner check is hardcoded. Consider accepting the expected command substring as a parameter so both tests (and any future ones) can share the helper instead of copying the four `expect` lines each time:
```ts
function expectCmdWrappedInvocation(params: {
captured: SpawnCall | ExecCall | undefined;
expectedComSpec: string;
expectedCmdSubstring: string; // e.g. "pnpm.cmd --version" or "bunx.cmd --version"
}) {
if (!params.captured) {
throw new Error("expected command wrapper to be called");
}
expect(params.captured[0]).toBe(params.expectedComSpec);
expect(params.captured[1].slice(0, 3)).toEqual(["/d", "/s", "/c"]);
expect(params.captured[1][3]).toContain(params.expectedCmdSubstring);
expect(params.captured[2].windowsVerbatimArguments).toBe(true);
}
```
How can I resolve this? If you propose a fix, please make it concise.Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
| } finally { | ||
| platformSpy.mockRestore(); | ||
| } | ||
| }); |
There was a problem hiding this comment.
Missing runExec coverage for bunx
A parallel test exists for pnpm via runExec (the second test in the suite, lines 91-113) that exercises the execFile code path. The new test only covers runCommandWithTimeout (the spawn path). Because the resolveCommand call appears independently in both runExec and runCommandWithTimeout, adding a corresponding runExec("bunx", ...) test would give the same regression coverage as the existing pnpm pair, and keep the pattern symmetric.
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/process/exec.windows.test.ts
Line: 137
Comment:
**Missing `runExec` coverage for `bunx`**
A parallel test exists for `pnpm` via `runExec` (the second test in the suite, lines 91-113) that exercises the `execFile` code path. The new test only covers `runCommandWithTimeout` (the `spawn` path). Because the `resolveCommand` call appears independently in both `runExec` and `runCommandWithTimeout`, adding a corresponding `runExec("bunx", ...)` test would give the same regression coverage as the existing pnpm pair, and keep the pattern symmetric.
How can I resolve this? If you propose a fix, please make it concise.
Summary\n- add to the Windows command shim list in \n- ensure wraps via with \n- add a Windows-focused regression test for the path\n\n## Why\nIssue #47748 reports Windows update failures caused by batch-command spawning behavior. The Feishu onboarding import is already fixed in the current tree, but the Windows command wrapper still only special-cased and . Extending the same shim handling to keeps Windows package-manager launches on the safe wrapper path and avoids another spawn failure class.\n\nFixes #47748\n