| 73 | const force = setTimeout(() => { |
| 74 | try { |
| 75 | if (child.exitCode !== null) return |
| 76 | if (child.pid) process.kill(-child.pid, "SIGKILL") |
| 77 | else child.kill("SIGKILL") |
| 78 | } catch {} |
| 79 | }, 1_000) |
| 80 | force.unref?.() |
| 81 | } catch { |
| 82 | try { child.kill("SIGTERM") } catch {} |
| 83 | } |
| 84 | } |
| 85 | |
| 86 | function spawnOnce(command, commandArgs, cwd, options = {}) { |
| 87 | return new Promise((resolve) => { |
| 88 | let settled = false |
| 89 | let timedOut = false |
| 90 | const capture = options.capture === true |
| 91 | const stdout = [] |
| 92 | const stderr = [] |
| 93 | let timer |
| 94 | const done = (result) => { |
| 95 | if (settled) return |
| 96 | settled = true |
| 97 | if (timer) clearTimeout(timer) |
| 98 | resolve({ |
| 99 | ...result, |
| 100 | timedOut, |
| 101 | stdout: capture ? Buffer.concat(stdout).toString("utf8") : "", |
| 102 | stderr: capture ? Buffer.concat(stderr).toString("utf8") : "", |
| 103 | }) |
| 104 | } |
| 105 | |
| 106 | let child |
| 107 | try { |
| 108 | child = spawn(command, commandArgs, { |
| 109 | cwd, |
| 110 | shell: false, |
| 111 | stdio: capture ? ["ignore", "pipe", "pipe"] : "inherit", |
| 112 | env: process.env, |
| 113 | windowsHide: true, |
| 114 | detached: process.platform !== "win32", |
| 115 | }) |
| 116 | } catch (error) { |
| 117 | done({ code: -1, error }) |
| 118 | return |
| 119 | } |