Commit 423d77d

Anton Medvedev <anton@medv.io>
2021-08-13 03:35:08
The pipe() throws if already resolved
1 parent 479ca79
index.mjs
@@ -60,6 +60,7 @@ export function $(pieces, ...args) {
           message: `${stderr || '\n'}    at ${__from}`
         });
         (code === 0 || promise._nothrow ? resolve : reject)(output)
+        promise._resolved = true
       })
     })
   })
@@ -167,6 +168,7 @@ export class ProcessPromise extends Promise {
   child = undefined
   _stop = () => void 0
   _nothrow = false
+  _resolved = false
 
   get stdin() {
     return this.child.stdin
@@ -190,6 +192,13 @@ export class ProcessPromise extends Promise {
     if (typeof dest === 'string') {
       throw new Error('The pipe() method does not take strings. Forgot $?')
     }
+    if (this._resolved === true) {
+      if (dest instanceof ProcessPromise) {
+        nothrow(dest)
+        dest.child.kill()
+      }
+      throw new Error('The pipe() method shouldn\'t be called after promise is already resolved!')
+    }
     this._stop()
     if (dest instanceof ProcessPromise) {
       process.stdin.unpipe(dest.stdin)
test.mjs
@@ -134,6 +134,20 @@ import path from 'path'
   console.log('☝️ Error above is expected')
 }
 
+{ // The pipe() throws if already resolved
+  let out, p = $`echo "Hello"`
+  await p
+  try {
+    out = await p.pipe($`less`)
+  } catch (err) {
+    console.log(err)
+    console.log('☝️ Error above is expected')
+  }
+  if (out) {
+    assert.fail('Expected failure!')
+  }
+}
+
 { // ProcessOutput::exitCode doesn't throw
   assert(await $`grep qwerty README.md`.exitCode !== 0)
   assert(await $`[[ -f ${__filename} ]]`.exitCode === 0)
@@ -156,18 +170,12 @@ import path from 'path'
   console.log(chalk.greenBright('globby available'))
 }
 
-{ // require() is working in ESM
-  const {name, version} = require('./package.json')
-  assert(typeof name === 'string')
-  console.log(chalk.black.bgYellowBright(` ${name} version is ${version} `))
-}
-
 { // Executes a script from PATH.
   const isWindows = process.platform === 'win32'
   const oldPath = process.env.PATH
 
   const envPathSeparator = isWindows ? ';' : ':'
-  process.env.PATH +=  envPathSeparator + path.resolve('/tmp/')
+  process.env.PATH += envPathSeparator + path.resolve('/tmp/')
 
   const toPOSIXPath = (_path) =>
     _path.split(path.sep).join(path.posix.sep)
@@ -178,7 +186,7 @@ import path from 'path'
 
   try {
     await $`echo ${scriptCode}`
-      .pipe(fs.createWriteStream('/tmp/script-from-path', { mode: 0o744 }))
+      .pipe(fs.createWriteStream('/tmp/script-from-path', {mode: 0o744}))
     await $`script-from-path`
   } finally {
     process.env.PATH = oldPath
@@ -186,4 +194,10 @@ import path from 'path'
   }
 }
 
+{ // require() is working in ESM
+  const {name, version} = require('./package.json')
+  assert(typeof name === 'string')
+  console.log(chalk.black.bgYellowBright(` ${name} version is ${version} `))
+}
+
 console.log(chalk.greenBright(' 🍺 Success!'))
zx.mjs
@@ -188,7 +188,6 @@ function transformMarkdown(source) {
         break
     }
   }
-  console.log(output.join('\n'))
   return output.join('\n')
 }