diff --git a/README.md b/README.md index 956d7226db..0c5fc994a3 100644 --- a/README.md +++ b/README.md @@ -131,6 +131,7 @@ class ProcessOutput { readonly stdout: string readonly stderr: string readonly exitCode: number + readonly signal: 'SIGTERM' | 'SIGKILL' | ... toString(): string } ``` diff --git a/index.d.ts b/index.d.ts index a1e731f6c3..465d94f069 100644 --- a/index.d.ts +++ b/index.d.ts @@ -45,7 +45,8 @@ export interface ProcessPromise extends Promise { } export class ProcessOutput { - readonly exitCode: number + readonly exitCode: number | null + readonly signal: NodeJS.Signals | null readonly stdout: string readonly stderr: string diff --git a/index.mjs b/index.mjs index 2223e8a438..22e0094f58 100644 --- a/index.mjs +++ b/index.mjs @@ -88,15 +88,22 @@ export function $(pieces, ...args) { maxBuffer: 200 * 1024 * 1024, // 200 MiB }) - child.on('exit', code => { - child.on('close', () => { - let output = new ProcessOutput({ - code, stdout, stderr, combined, - message: `${stderr || '\n'} at ${__from}\n exit code: ${code}` + (exitCodeInfo(code) ? ' (' + exitCodeInfo(code) + ')' : '') - }); - (code === 0 || promise._nothrow ? resolve : reject)(output) - promise._resolved = true - }) + child.on('close', (code, signal) => { + let message = `${stderr || '\n'} at ${__from}` + message += `\n exit code: ${code}${exitCodeInfo(code) ? ' (' + exitCodeInfo(code) + ')' : ''}` + if (signal !== null) { + message += `\n signal: ${signal}` + } + let output = new ProcessOutput({ + code, + signal, + stdout, + stderr, + combined, + message, + }); + (code === 0 || promise._nothrow ? resolve : reject)(output) + promise._resolved = true }) let stdout = '', stderr = '', combined = '' @@ -257,14 +264,16 @@ export class ProcessPromise extends Promise { } export class ProcessOutput extends Error { - #code = 0 + #code = null + #signal = null #stdout = '' #stderr = '' #combined = '' - constructor({code, stdout, stderr, combined, message}) { + constructor({code, signal, stdout, stderr, combined, message}) { super(message) this.#code = code + this.#signal = signal this.#stdout = stdout this.#stderr = stderr this.#combined = combined @@ -286,11 +295,16 @@ export class ProcessOutput extends Error { return this.#code } + get signal() { + return this.#signal + } + [inspect.custom]() { let stringify = (s, c) => s.length === 0 ? '\'\'' : c(inspect(s)) return `ProcessOutput { stdout: ${stringify(this.stdout, chalk.green)}, stderr: ${stringify(this.stderr, chalk.red)}, + signal: ${inspect(this.signal)}, exitCode: ${(this.exitCode === 0 ? chalk.green : chalk.red)(this.exitCode)}${(exitCodeInfo(this.exitCode) ? chalk.grey(' (' + exitCodeInfo(this.exitCode) + ')') : '')} }` } diff --git a/test.mjs b/test.mjs index 7b32a342c2..fcbe193c50 100755 --- a/test.mjs +++ b/test.mjs @@ -222,6 +222,18 @@ if (test('The kill() method works')) { await p } +if (test('The signal is passed with kill() method')) { + let p = $`while true; do :; done` + setTimeout(() => p.kill('SIGKILL'), 100) + let signal + try { + await p + } catch (p) { + signal = p.signal + } + assert.equal(signal, 'SIGKILL') +} + if (test('YAML works')) { assert.deepEqual(YAML.parse(YAML.stringify({foo: 'bar'})), {foo: 'bar'}) console.log(chalk.greenBright('YAML works'))