Commit 53a215e

Anton Medvedev <anton@medv.io>
2022-02-27 14:34:40
Add signal field to ProcessOutput
1 parent bf88f50
index.d.ts
@@ -45,7 +45,8 @@ export interface ProcessPromise<T> extends Promise<T> {
 }
 
 export class ProcessOutput {
-  readonly exitCode: number
+  readonly exitCode: number | null
+  readonly signal: NodeJS.Signals | null
   readonly stdout: string
   readonly stderr: string
 
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) + ')') : '')}
 }`
   }
README.md
@@ -131,6 +131,7 @@ class ProcessOutput {
   readonly stdout: string
   readonly stderr: string
   readonly exitCode: number
+  readonly signal: 'SIGTERM' | 'SIGKILL' | ...
   toString(): string
 }
 ```
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'))