Commit f0c10cd

Anton Golub <antongolub@antongolub.com>
2024-04-08 08:33:52
feat: add `stdio` option (#772)
closes #771
1 parent 5ad9ce3
src/core.ts
@@ -13,7 +13,7 @@
 // limitations under the License.
 
 import assert from 'node:assert'
-import { spawn, spawnSync, StdioNull, StdioPipe } from 'node:child_process'
+import { spawn, spawnSync, StdioOptions, IOType } from 'node:child_process'
 import { AsyncHook, AsyncLocalStorage, createHook } from 'node:async_hooks'
 import { Readable, Writable } from 'node:stream'
 import { inspect } from 'node:util'
@@ -59,6 +59,7 @@ export interface Options {
   ac?: AbortController
   signal?: AbortSignal
   input?: string | Buffer | Readable | ProcessOutput | ProcessPromise
+  stdio: StdioOptions
   verbose: boolean
   sync: boolean
   env: NodeJS.ProcessEnv
@@ -95,6 +96,7 @@ export const defaults: Options = {
   env: process.env,
   sync: false,
   shell: true,
+  stdio: ['inherit', 'pipe', 'pipe'],
   nothrow: false,
   quiet: false,
   prefix: '',
@@ -192,7 +194,6 @@ try {
 } catch (err) {}
 
 type Resolve = (out: ProcessOutput) => void
-type IO = StdioPipe | StdioNull
 
 export class ProcessPromise extends Promise<ProcessOutput> {
   private _command = ''
@@ -200,7 +201,7 @@ export class ProcessPromise extends Promise<ProcessOutput> {
   private _resolve: Resolve = noop
   private _reject: Resolve = noop
   private _snapshot = getStore()
-  private _stdio: [IO, IO, IO] = ['inherit', 'pipe', 'pipe']
+  private _stdio?: StdioOptions
   private _nothrow?: boolean
   private _quiet?: boolean
   private _timeout?: number
@@ -245,7 +246,7 @@ export class ProcessPromise extends Promise<ProcessOutput> {
 
     this._zurk = exec({
       input,
-      cmd: $.prefix + this._command + $.postfix,
+      cmd: $.prefix + self._command + $.postfix,
       cwd: $.cwd ?? $[processCwd],
       ac: $.ac,
       signal: $.signal,
@@ -253,7 +254,7 @@ export class ProcessPromise extends Promise<ProcessOutput> {
       env: $.env,
       spawn: $.spawn,
       spawnSync: $.spawnSync,
-      stdio: this._stdio as any,
+      stdio: self._stdio ?? $.stdio,
       sync: $[syncExec],
       detached: !isWin,
       run: (cb) => cb(),
@@ -427,7 +428,11 @@ export class ProcessPromise extends Promise<ProcessOutput> {
     return $.kill(this.child.pid, signal)
   }
 
-  stdio(stdin: IO, stdout: IO = 'pipe', stderr: IO = 'pipe'): ProcessPromise {
+  stdio(
+    stdin: IOType,
+    stdout: IOType = 'pipe',
+    stderr: IOType = 'pipe'
+  ): ProcessPromise {
     this._stdio = [stdin, stdout, stderr]
     return this
   }
test/fixtures/js-project/package-lock.json
@@ -20,7 +20,7 @@
         "@types/node": ">=20.11.30",
         "@types/which": "^3.0.3",
         "@webpod/ingrid": "^0.0.0-beta.3",
-        "@webpod/ps": "^0.0.0-beta.2",
+        "@webpod/ps": "^0.0.0-beta.3",
         "c8": "^9.1.0",
         "chalk": "^5.3.0",
         "depseek": "^0.4.1",
@@ -39,14 +39,14 @@
         "typescript": "^5.4.4",
         "which": "^4.0.0",
         "yaml": "^2.4.1",
-        "zurk": "^0.1.0"
+        "zurk": "^0.1.2"
       },
       "engines": {
         "node": ">= 16.0.0"
       },
       "optionalDependencies": {
         "@types/fs-extra": "^11.0.4",
-        "@types/node": ">=20.12.4"
+        "@types/node": ">=20.12.5"
       }
     },
     "node_modules/zx": {
test/core.test.js
@@ -451,6 +451,12 @@ describe('core', () => {
     assert.equal((await b).stdout, 'bar')
   })
 
+  test('stdio as option', async () => {
+    let p = $({ stdio: 'ignore' })`echo foo`
+
+    assert.equal((await p).stdout, '')
+  })
+
   test('snapshots works', async () => {
     await within(async () => {
       $.prefix += 'echo success;'
package-lock.json
@@ -36,7 +36,7 @@
         "typescript": "^5.4.4",
         "which": "^4.0.0",
         "yaml": "^2.4.1",
-        "zurk": "^0.1.0"
+        "zurk": "^0.1.2"
       },
       "engines": {
         "node": ">= 16.0.0"
@@ -4384,9 +4384,9 @@
       }
     },
     "node_modules/zurk": {
-      "version": "0.1.0",
-      "resolved": "https://registry.npmjs.org/zurk/-/zurk-0.1.0.tgz",
-      "integrity": "sha512-lJPh6OG7eBAkAw1zlB15U0tRSb7Cq/nZhcW1/gfNYB+HUTwzlK1PvKDp6zV6jyix8xYiTnIfiHGPMVav8x3YuQ==",
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/zurk/-/zurk-0.1.2.tgz",
+      "integrity": "sha512-iulDU6SgS+YvvPqLaHrBzDMXxPj72JKCHzbx3oo+38zcyMcF/kwK4vClnHwRZ8UqtQB35Lj1cRXRqoXKvRUdqg==",
       "dev": true
     }
   }
package.json
@@ -80,7 +80,7 @@
     "typescript": "^5.4.4",
     "which": "^4.0.0",
     "yaml": "^2.4.1",
-    "zurk": "^0.1.0"
+    "zurk": "^0.1.2"
   },
   "publishConfig": {
     "registry": "https://wombat-dressing-room.appspot.com"