()
| 160 | const bin = [command, ...(args ?? [])].join(' '); |
| 161 | |
| 162 | const worker = () => |
| 163 | new Promise<ProcessResult>((resolve, reject) => { |
| 164 | const spawnedProcess = spawn(command, args ?? [], { |
| 165 | // shell:true tells Windows to use shell command for spawning a child process |
| 166 | // https://stackoverflow.com/questions/60386867/node-spawn-child-process-not-working-in-windows |
| 167 | shell: true, |
| 168 | windowsHide: true, |
| 169 | ...options, |
| 170 | }) as ChildProcessByStdio<Writable, Readable, Readable>; |
| 171 | |
| 172 | // eslint-disable-next-line functional/no-let |
| 173 | let stdout = ''; |
| 174 | // eslint-disable-next-line functional/no-let |
| 175 | let stderr = ''; |
| 176 | // eslint-disable-next-line functional/no-let |
| 177 | let output = ''; // interleaved stdout and stderr |
| 178 | |
| 179 | spawnedProcess.stdout.on('data', (data: unknown) => { |
| 180 | const message = String(data); |
| 181 | stdout += message; |
| 182 | output += message; |
| 183 | onStdout?.(message, spawnedProcess); |
| 184 | }); |
| 185 | |
| 186 | spawnedProcess.stderr.on('data', (data: unknown) => { |
| 187 | const message = String(data); |
| 188 | stderr += message; |
| 189 | output += message; |
| 190 | onStderr?.(message, spawnedProcess); |
| 191 | }); |
| 192 | |
| 193 | spawnedProcess.on('error', error => { |
| 194 | reject(error); |
| 195 | }); |
| 196 | |
| 197 | spawnedProcess.on('close', (code, signal) => { |
| 198 | const result: ProcessResult = { bin, code, signal, stdout, stderr }; |
| 199 | if (code === 0 || ignoreExitCode) { |
| 200 | if (!silent) { |
| 201 | logger.debug(output); |
| 202 | } |
| 203 | onComplete?.(); |
| 204 | resolve(result); |
| 205 | } else { |
| 206 | if (!silent) { |
| 207 | // ensure stdout and stderr are logged to help debug failure |
| 208 | logger.debug(output, { force: true }); |
| 209 | } |
| 210 | const error = new ProcessError(result); |
| 211 | onError?.(error); |
| 212 | reject(error); |
| 213 | } |
| 214 | }); |
| 215 | }); |
| 216 | |
| 217 | return silent ? worker() : logger.command(bin, worker); |
| 218 | } |
no test coverage detected