Commit 24ca004

Anton Medvedev <anton@medv.io>
2022-06-02 22:20:12
Use stderr as default for debug logs
1 parent 129017a
src/cli.ts
@@ -35,60 +35,51 @@ await (async function main() {
   if (argv.experimental) {
     Object.assign(global, await import('./experimental.js'))
   }
-  try {
-    if (
-      process.argv.length == 3 &&
-      ['--version', '-v', '-V'].includes(process.argv[2])
-    ) {
+  if (process.argv.length == 3) {
+    if (['--version', '-v', '-V'].includes(process.argv[2])) {
       console.log(getVersion())
       return (process.exitCode = 0)
     }
-    if (
-      process.argv.length == 3 &&
-      ['--help', '-h'].includes(process.argv[2])
-    ) {
+    if (['--help', '-h'].includes(process.argv[2])) {
       printUsage()
       return (process.exitCode = 0)
     }
-    if (
-      process.argv.length == 3 &&
-      ['--interactive', '-i'].includes(process.argv[2])
-    ) {
+    if (['--interactive', '-i'].includes(process.argv[2])) {
       startRepl()
       return (process.exitCode = 0)
     }
-    let firstArg = process.argv.slice(2).find((a) => !a.startsWith('--'))
-    if (typeof firstArg === 'undefined' || firstArg === '-') {
-      let ok = await scriptFromStdin()
-      if (!ok) {
-        startRepl()
-      }
-    } else if (
-      firstArg.startsWith('http://') ||
-      firstArg.startsWith('https://')
-    ) {
-      await scriptFromHttp(firstArg)
-    } else {
-      let filepath
-      if (firstArg.startsWith('/')) {
-        filepath = firstArg
-      } else if (firstArg.startsWith('file:///')) {
-        filepath = url.fileURLToPath(firstArg)
-      } else {
-        filepath = resolve(firstArg)
-      }
-      await importPath(filepath)
+  }
+  let firstArg = process.argv.slice(2).find((a) => !a.startsWith('--'))
+  if (typeof firstArg === 'undefined' || firstArg === '-') {
+    let ok = await scriptFromStdin()
+    if (!ok) {
+      startRepl()
     }
-  } catch (p) {
-    if (p instanceof ProcessOutput) {
-      console.error('Error: ' + p.message)
-      return (process.exitCode = 1)
+  } else if (
+    firstArg.startsWith('http://') ||
+    firstArg.startsWith('https://')
+  ) {
+    await scriptFromHttp(firstArg)
+  } else {
+    let filepath
+    if (firstArg.startsWith('/')) {
+      filepath = firstArg
+    } else if (firstArg.startsWith('file:///')) {
+      filepath = url.fileURLToPath(firstArg)
     } else {
-      throw p
+      filepath = resolve(firstArg)
     }
+    await importPath(filepath)
   }
   return (process.exitCode = 0)
-})()
+})().catch((err) => {
+  if (err instanceof ProcessOutput) {
+    console.error('Error:', err.message)
+  } else {
+    console.error(err)
+  }
+  process.exitCode = 1
+})
 
 async function scriptFromStdin() {
   let script = ''
src/core.ts
@@ -168,7 +168,7 @@ export class ProcessPromise extends Promise<ProcessOutput> {
       stderr = '',
       combined = ''
     let onStdout = (data: any) => {
-      if ($.verbose && !this._quiet) process.stdout.write(data)
+      if ($.verbose && !this._quiet) process.stderr.write(data)
       stdout += data
       combined += data
     }
src/print.ts
@@ -16,13 +16,13 @@ import { colorize } from './util.js'
 
 export function printCmd(cmd: string) {
   if (/\n/.test(cmd)) {
-    console.log(
+    process.stderr.write(
       cmd
         .split('\n')
-        .map((line, i) => (i === 0 ? '$' : '>') + ' ' + colorize(line))
-        .join('\n')
+        .map((line, i) => `${i == 0 ? '$' : '>'} ${colorize(line)}`)
+        .join('\n') + '\n'
     )
   } else {
-    console.log('$', colorize(cmd))
+    process.stderr.write(`$ ${colorize(cmd)}\n`)
   }
 }
test/cli.test.js
@@ -47,13 +47,14 @@ test('starts repl with -i', async () => {
 })
 
 test('supports `--experimental` flag', async () => {
-  await $`echo 'echo("test")' | node build/cli.js --experimental`
+  let out = await $`echo 'echo("test")' | node build/cli.js --experimental`
+  assert.match(out.stdout, 'test')
 })
 
 test('supports `--quiet` flag', async () => {
   let p = await $`node build/cli.js test/fixtures/markdown.md`
-  assert.ok(!p.stdout.includes('ignore'), 'ignore was printed')
-  assert.ok(p.stdout.includes('hello'), 'no hello')
+  assert.ok(!p.stderr.includes('ignore'), 'ignore was printed')
+  assert.ok(p.stderr.includes('hello'), 'no hello')
   assert.ok(p.stdout.includes('world'), 'no world')
 })
 
@@ -61,31 +62,26 @@ test('supports `--shell` flag ', async () => {
   let shell = $.shell
   let p =
     await $`node build/cli.js --shell=${shell} <<< '$\`echo \${$.shell}\`'`
-  assert.ok(p.stdout.includes(shell))
+  assert.ok(p.stderr.includes(shell))
 })
 
 test('supports `--prefix` flag ', async () => {
   let prefix = 'set -e;'
   let p =
     await $`node build/cli.js --prefix=${prefix} <<< '$\`echo \${$.prefix}\`'`
-  assert.ok(p.stdout.includes(prefix))
+  assert.ok(p.stderr.includes(prefix))
 })
 
 test('scripts from https', async () => {
-  let script = path.resolve('test/fixtures/echo.http')
-  let server = $`while true; do cat ${script} | nc -l 8080; done`.quiet()
-  let p = await $`node build/cli.js http://127.0.0.1:8080/echo.mjs`.quiet()
-
-  assert.ok(p.stdout.includes('test'))
-  server.kill()
+  $`cat ${path.resolve('test/fixtures/echo.http')} | nc -l 8080`
+  let out = await $`node build/cli.js http://127.0.0.1:8080/echo.mjs`
+  assert.match(out.stderr, 'test')
+})
 
-  let err
-  try {
-    await $`node build/cli.js http://127.0.0.1:8081/echo.mjs`.quiet()
-  } catch (e) {
-    err = e
-  }
-  assert.ok(err.stderr.includes('ECONNREFUSED'))
+test('scripts from https not ok', async () => {
+  $`echo $'HTTP/1.1 500\n\n' | nc -l 8081`
+  let out = await $`node build/cli.js http://127.0.0.1:8081`.nothrow()
+  assert.match(out.stderr, "Error: Can't get")
 })
 
 test('scripts with no extension', async () => {
@@ -98,7 +94,9 @@ test('scripts with no extension', async () => {
 })
 
 test('require() is working from stdin', async () => {
-  await $`node build/cli.js <<< 'require("./package.json").name'`
+  let out =
+    await $`node build/cli.js <<< 'console.log(require("./package.json").name)'`
+  assert.match(out.stdout, 'zx')
 })
 
 test('require() is working in ESM', async () => {
@@ -113,4 +111,11 @@ test('markdown scripts are working', async () => {
   await $`node build/cli.js docs/markdown.md`
 })
 
+test('exceptions are caught', async () => {
+  let out1 = await $`node build/cli.js <<<${'await $`wtf`'}`.nothrow()
+  assert.match(out1.stderr, 'Error:')
+  let out2 = await $`node build/cli.js <<<'throw 42'`.nothrow()
+  assert.match(out2.stderr, '42')
+})
+
 test.run()