import { spawn } from "node:child_process" export type CommandResult = { stdout: string stderr: string code: number } export const commandExists = (command: string) => new Promise((resolve) => { const child = spawn("sh", ["-lc", `command -v ${command}`]) child.on("error", () => resolve(false)) child.on("close", (code) => resolve(code === 0)) }) export const runCommand = ( command: string, args: string[], options: { timeoutMs?: number } = {} ) => new Promise((resolve, reject) => { const child = spawn(command, args, { stdio: ["ignore", "pipe", "pipe"], }) const stdout: Buffer[] = [] const stderr: Buffer[] = [] const timeout = options.timeoutMs ? setTimeout(() => { child.kill("SIGTERM") reject(new Error(`${command} wurde nach ${options.timeoutMs} ms beendet`)) }, options.timeoutMs) : null child.stdout.on("data", (chunk) => stdout.push(Buffer.from(chunk))) child.stderr.on("data", (chunk) => stderr.push(Buffer.from(chunk))) child.on("error", reject) child.on("close", (code) => { if (timeout) clearTimeout(timeout) resolve({ stdout: Buffer.concat(stdout).toString("utf8"), stderr: Buffer.concat(stderr).toString("utf8"), code: code ?? 0, }) }) })