import { spawnSync } from "node:child_process";
const windowsShellCommandPattern = /\.(cmd|bat)$/i;
const windowsShellCommandNames = new Set(["npm", "pnpm"]);
export function resolveSpawnRuntimeOptions(command, platform = process.platform) {
if (
platform === "win32" &&
(windowsShellCommandPattern.test(command) || windowsShellCommandNames.has(command))
) {
return {
// Windows runner bare `pnpm` / `npm` cmd shim
// `pnpm.cmd` `pnpm exec` cwd
// tsup scripts/src/... Cannot find src/main/index.ts
// shell/cmd.exe shim pnpm
shell: true,
};
}
return {};
}
// shell:true Node args DEP0190
// Windows E:\Z Code\...pnpm --dir cmd
// E:\Z ENOENT: lstat cmd.exe
// CI
export function quoteArgsForWindowsShell(args) {
return args.map((arg) => (/\s/.test(arg) ? `"${arg}"` : arg));
}
export function runCommand(command, args, options = {}) {
const runtimeOptions = resolveSpawnRuntimeOptions(command);
const spawnArgs = runtimeOptions.shell ? quoteArgsForWindowsShell(args) : args;
const result = spawnSync(command, spawnArgs, {
stdio: "inherit",
...options,
...runtimeOptions,
});
if (result.error) {
throw result.error;
}
if (typeof result.status === "number" && result.status !== 0) {
throw new Error(`${command} ${args.join(" ")} failed with code ${result.status}`);
}
return result;
}
export function runCommandAndReadStdout(command, args, options = {}) {
const runtimeOptions = resolveSpawnRuntimeOptions(command);
const spawnArgs = runtimeOptions.shell ? quoteArgsForWindowsShell(args) : args;
const result = spawnSync(command, spawnArgs, {
encoding: "utf8",
...options,
...runtimeOptions,
});
if (result.error) {
throw result.error;
}
if (typeof result.status === "number" && result.status !== 0) {
throw new Error(`${command} ${args.join(" ")} failed with code ${result.status}`);
}
return result.stdout;
}