Last active
October 27, 2020 18:09
-
-
Save isaacs/00521f823ef33da041f389aee55091c9 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
commit 5a7c615eea11ba4c540210c0a29c843da5def060 | |
Author: isaacs <i@izs.me> | |
Date: Tue Oct 27 11:07:00 2020 -0700 | |
Do not return 0-length buffer if stdio is inherited | |
diff --git a/README.md b/README.md | |
index 3b604f2..b569948 100644 | |
--- a/README.md | |
+++ b/README.md | |
@@ -45,13 +45,18 @@ Result or error will be decorated with the properties in the `extra` | |
object. You can use this to attach some helpful info about _why_ the | |
command is being run, if it makes sense for your use case. | |
+If `stdio` is set to anything other than `'inherit'`, then the result/error | |
+will be decorated with `stdout` and `stderr` values. If `stdioString` is | |
+set to `true`, these will be strings. Otherwise they will be Buffer | |
+objects. | |
+ | |
Returned promise is decorated with the `stdin` stream if the process is set | |
to pipe from `stdin`. Writing to this stream writes to the `stdin` of the | |
spawned process. | |
#### Options | |
-- `stdioString` Boolean, default `false`. Return stdio/stderr output as | |
+- `stdioString` Boolean, default `false`. Return stdout/stderr output as | |
strings rather than buffers. | |
- `cwd` String, default `process.cwd()`. Current working directory for | |
running the script. Also the argument to `infer-owner` to determine | |
diff --git a/index.js b/index.js | |
index 809da93..cc73d1d 100644 | |
--- a/index.js | |
+++ b/index.js | |
@@ -2,6 +2,11 @@ const {spawn} = require('child_process') | |
const inferOwner = require('infer-owner') | |
+const isPipe = (stdio = 'pipe', fd) => | |
+ stdio === 'pipe' || stdio === null ? true | |
+ : Array.isArray(stdio) ? isPipe(stdio[fd], fd) | |
+ : false | |
+ | |
// 'extra' object is for decorating the error a bit more | |
const promiseSpawn = (cmd, args, opts, extra = {}) => { | |
const cwd = opts.cwd || process.cwd() | |
@@ -20,13 +25,14 @@ const promiseSpawn = (cmd, args, opts, extra = {}) => { | |
}, extra)) | |
} | |
-const stdioResult = (stdout, stderr, {stdioString}) => | |
+const stdioResult = (stdout, stderr, {stdioString, stdio}) => | |
stdioString ? { | |
- stdout: Buffer.concat(stdout).toString(), | |
- stderr: Buffer.concat(stderr).toString(), | |
- } : { | |
- stdout: Buffer.concat(stdout), | |
- stderr: Buffer.concat(stderr), | |
+ stdout: isPipe(stdio, 1) ? Buffer.concat(stdout).toString() : null, | |
+ stderr: isPipe(stdio, 2) ? Buffer.concat(stderr).toString() : null, | |
+ } | |
+ : { | |
+ stdout: isPipe(stdio, 1) ? Buffer.concat(stdout) : null, | |
+ stderr: isPipe(stdio, 2) ? Buffer.concat(stderr) : null, | |
} | |
const promiseSpawnUid = (cmd, args, opts, extra) => { | |
diff --git a/test/promise-spawn.js b/test/promise-spawn.js | |
index a34f565..5a79fe2 100644 | |
--- a/test/promise-spawn.js | |
+++ b/test/promise-spawn.js | |
@@ -4,15 +4,20 @@ const Minipass = require('minipass') | |
const EE = require('events') | |
const fs = require('fs') | |
+const isPipe = (stdio = 'pipe', fd) => | |
+ stdio === 'pipe' || stdio === null ? true | |
+ : Array.isArray(stdio) ? isPipe(stdio[fd], fd) | |
+ : false | |
+ | |
class MockProc extends EE { | |
constructor (cmd, args, opts) { | |
super() | |
this.cmd = cmd | |
this.args = args | |
this.opts = opts | |
- this.stdout = opts.stdio === 'inherit' ? null : new Minipass() | |
- this.stderr = opts.stdio === 'inherit' ? null : new Minipass() | |
- this.stdin = opts.stdio === 'inherit' ? null : new Minipass() | |
+ this.stdin = isPipe(opts.stdio, 0) ? new Minipass() : null | |
+ this.stdout = isPipe(opts.stdio, 1) ? new Minipass() : null | |
+ this.stderr = isPipe(opts.stdio, 2) ? new Minipass() : null | |
this.code = null | |
this.signal = null | |
process.nextTick(() => this.run()) | |
@@ -111,8 +116,24 @@ t.test('pass', t => t.resolveMatch(promiseSpawn('pass', [], {stdioString: true}, | |
t.test('pass, share stdio', t => t.resolveMatch(promiseSpawn('pass', [], { stdio: 'inherit'}, {a: 1}), { | |
code: 0, | |
signal: null, | |
- stdout: Buffer.alloc(0), | |
- stderr: Buffer.alloc(0), | |
+ stdout: null, | |
+ stderr: null, | |
+ a: 1, | |
+})) | |
+ | |
+t.test('pass, share stdout', t => t.resolveMatch(promiseSpawn('pass', [], { stdioString: true, stdio: ['pipe', 'inherit', 'pipe']}, {a: 1}), { | |
+ code: 0, | |
+ signal: null, | |
+ stdout: null, | |
+ stderr: '', | |
+ a: 1, | |
+})) | |
+ | |
+t.test('pass, share stderr', t => t.resolveMatch(promiseSpawn('pass', [], { stdioString: true, stdio: ['pipe', 'pipe', 'inherit']}, {a: 1}), { | |
+ code: 0, | |
+ signal: null, | |
+ stdout: 'OK :)', | |
+ stderr: null, | |
a: 1, | |
})) | |
@@ -129,8 +150,8 @@ t.test('fail, shared stdio', t => t.rejects(promiseSpawn('fail', [], { stdio: 'i | |
message: 'command failed', | |
code: 1, | |
signal: null, | |
- stdout: Buffer.alloc(0), | |
- stderr: Buffer.alloc(0), | |
+ stdout: null, | |
+ stderr: null, | |
a: 1, | |
})) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment