fix: keep CLI runner cross-platform
This commit is contained in:
parent
37b964450c
commit
3ccd535ead
|
|
@ -0,0 +1,14 @@
|
|||
import { describe, expect, it } from "vitest";
|
||||
import { runCli } from "./cli-runner.js";
|
||||
|
||||
describe("runCli", () => {
|
||||
it("runs argv without shell interpolation", async () => {
|
||||
const out = await runCli(process.execPath, ["-e", "console.log(process.argv[1])", "hello&world"], 10_000);
|
||||
expect(out).toBe("hello&world");
|
||||
});
|
||||
|
||||
it("reports nonzero exits as errors", async () => {
|
||||
const out = await runCli(process.execPath, ["-e", "console.log('bad'); process.exit(7)"], 10_000);
|
||||
expect(out).toContain("CLI exited 7");
|
||||
});
|
||||
});
|
||||
|
|
@ -2,19 +2,15 @@ import { spawn } from "node:child_process";
|
|||
|
||||
const MAX_OUTPUT_BYTES = 10 * 1024 * 1024;
|
||||
|
||||
function cmdQuote(value: string): string {
|
||||
// ponytail: minimal cmd.exe quoting for Windows .cmd shims; callers still pass argv, not shell text.
|
||||
return `"${value.replace(/(["^&|<>()%!])/g, "^$1")}"`;
|
||||
function isCmdShim(bin: string): boolean {
|
||||
return process.platform === "win32" && /(?:\.cmd|\.bat)$/i.test(bin);
|
||||
}
|
||||
|
||||
export function runCli(bin: string, args: string[], timeoutMs = 120_000): Promise<string> {
|
||||
return new Promise((resolve) => {
|
||||
const isWin = process.platform === "win32";
|
||||
const command = isWin ? "cmd.exe" : bin;
|
||||
const commandArgs = isWin
|
||||
? ["/d", "/s", "/c", [cmdQuote(bin), ...args.map(cmdQuote)].join(" ")]
|
||||
: args;
|
||||
|
||||
// ponytail: only .cmd/.bat need cmd.exe; real .exe paths keep true argv semantics.
|
||||
const command = isCmdShim(bin) ? process.env.ComSpec ?? "cmd.exe" : bin;
|
||||
const commandArgs = isCmdShim(bin) ? ["/d", "/s", "/c", bin, ...args] : args;
|
||||
const child = spawn(command, commandArgs, {
|
||||
shell: false,
|
||||
timeout: timeoutMs,
|
||||
|
|
|
|||
Loading…
Reference in New Issue