import { execFile, spawn, type ChildProcess, type SpawnOptions } from "node:child_process"; import { promisify } from "node:util"; import { isWindowsCommandScript, isWindowsPowerShellScript, quoteWindowsArgument, quoteWindowsCommand, windowsPowerShellScriptArgs, } from "./executable.js"; const execFileAsync = promisify(execFile); interface ExecCommandOptions { cwd?: string; env?: NodeJS.ProcessEnv; encoding?: BufferEncoding; timeout?: number; maxBuffer?: number; } interface ExecCommandResult { stdout: string; stderr: string; } export function spawnProcess( command: string, args: string[], options?: SpawnOptions, ): ChildProcess { const isWindows = process.platform === "win32"; if (isWindowsPowerShellScript(command)) { return spawn("powershell.exe", windowsPowerShellScriptArgs(command, args), { ...options, shell: false, windowsHide: true, }); } const shell = isWindowsCommandScript(command) ? true : (options?.shell ?? isWindows); const shouldQuoteForShell = isWindows && shell !== false; const resolvedCommand = shouldQuoteForShell ? quoteWindowsCommand(command) : command; const resolvedArgs = shouldQuoteForShell ? args.map(quoteWindowsArgument) : args; return spawn(resolvedCommand, resolvedArgs, { ...options, shell, windowsHide: true, }); } export async function execCommand( command: string, args: string[], options?: ExecCommandOptions, ): Promise { const isWindows = process.platform === "win32"; if (isWindowsPowerShellScript(command)) { return execFileAsync("powershell.exe", windowsPowerShellScriptArgs(command, args), { cwd: options?.cwd, env: options?.env, encoding: options?.encoding ?? "utf8", timeout: options?.timeout, maxBuffer: options?.maxBuffer, shell: false, windowsHide: true, }) as Promise; } const shell = isWindowsCommandScript(command) ? true : isWindows; const shouldQuoteForShell = isWindows && shell !== false; const resolvedCommand = shouldQuoteForShell ? quoteWindowsCommand(command) : command; const resolvedArgs = shouldQuoteForShell ? args.map(quoteWindowsArgument) : args; return execFileAsync(resolvedCommand, resolvedArgs, { cwd: options?.cwd, env: options?.env, encoding: options?.encoding ?? "utf8", timeout: options?.timeout, maxBuffer: options?.maxBuffer, shell, windowsHide: true, }) as Promise; } export function platformShell(): { command: string; flag: string[] } { if (process.platform === "win32") { return { command: "cmd.exe", flag: ["/c"] }; } return { command: "/bin/sh", flag: ["-lc"] }; } export function platformBash(): { command: string; flag: string[] } { if (process.platform === "win32") { return { command: "cmd.exe", flag: ["/c"] }; } return { command: "/bin/bash", flag: ["-lc"] }; }