fix
This commit is contained in:
@@ -1,21 +1,71 @@
|
||||
import { execFile } from 'node:child_process';
|
||||
import { spawn } from 'node:child_process';
|
||||
|
||||
export interface ShellResult {
|
||||
export interface RunResult {
|
||||
stdout: string;
|
||||
stderr: string;
|
||||
code: number;
|
||||
}
|
||||
|
||||
export function run(cmd: string, args: string[], timeoutMs = 120000): Promise<ShellResult> {
|
||||
export function run(
|
||||
command: string,
|
||||
args: string[] = [],
|
||||
timeoutMs = 120000,
|
||||
): Promise<RunResult> {
|
||||
return new Promise((resolve, reject) => {
|
||||
execFile(cmd, args, { timeout: timeoutMs, maxBuffer: 10 * 1024 * 1024 }, (error, stdout, stderr) => {
|
||||
if (error) {
|
||||
const err = new Error(`Command failed: ${cmd} ${args.join(' ')}\n${stderr || error.message}`);
|
||||
(err as any).stdout = stdout;
|
||||
(err as any).stderr = stderr;
|
||||
const printable = [command, ...args].join(' ');
|
||||
console.log(`[shell] running: ${printable}`);
|
||||
|
||||
const child = spawn(command, args, {
|
||||
stdio: ['ignore', 'pipe', 'pipe'],
|
||||
env: process.env,
|
||||
});
|
||||
|
||||
let stdout = '';
|
||||
let stderr = '';
|
||||
|
||||
const timer = setTimeout(() => {
|
||||
child.kill('SIGKILL');
|
||||
reject(new Error(`Command timed out after ${timeoutMs}ms: ${printable}`));
|
||||
}, timeoutMs);
|
||||
|
||||
child.stdout.on('data', (chunk) => {
|
||||
stdout += chunk.toString();
|
||||
});
|
||||
|
||||
child.stderr.on('data', (chunk) => {
|
||||
stderr += chunk.toString();
|
||||
});
|
||||
|
||||
child.on('error', (err) => {
|
||||
clearTimeout(timer);
|
||||
console.error(`[shell] failed to start: ${printable}`);
|
||||
console.error(`[shell] error: ${err.message}`);
|
||||
reject(err);
|
||||
});
|
||||
|
||||
child.on('close', (code) => {
|
||||
clearTimeout(timer);
|
||||
|
||||
const exitCode = code ?? -1;
|
||||
|
||||
if (stdout.trim()) {
|
||||
console.log(`[shell] stdout for ${printable}:\n${stdout.trim()}`);
|
||||
}
|
||||
|
||||
if (stderr.trim()) {
|
||||
console.warn(`[shell] stderr for ${printable}:\n${stderr.trim()}`);
|
||||
}
|
||||
|
||||
if (exitCode !== 0) {
|
||||
const err = new Error(
|
||||
`Command failed with exit code ${exitCode}: ${printable}\n${stderr || stdout}`,
|
||||
);
|
||||
reject(err);
|
||||
return;
|
||||
}
|
||||
resolve({ stdout, stderr });
|
||||
|
||||
console.log(`[shell] completed: ${printable}`);
|
||||
resolve({ stdout, stderr, code: exitCode });
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user