Commit 73aa581

Anton Golub <antongolub@antongolub.com>
2024-12-22 10:33:03
refactor: extract log from core
1 parent 6c30645
src/core.ts
@@ -39,13 +39,11 @@ import {
   ps,
   VoidStream,
   type ChalkInstance,
-  type RequestInfo,
-  type RequestInit,
   type TSpawnStore,
 } from './vendor-core.js'
 import {
   type Duration,
-  formatCmd,
+  log,
   isString,
   isStringLiteral,
   noop,
@@ -59,6 +57,8 @@ import {
   toCamelCase,
 } from './util.js'
 
+export { log, type LogEntry } from './util.js'
+
 const CWD = Symbol('processCwd')
 const SYNC = Symbol('syncExec')
 const EOL = Buffer.from(_EOL)
@@ -805,7 +805,7 @@ export function cd(dir: string | ProcessOutput) {
     dir = dir.toString().trim()
   }
 
-  $.log({ kind: 'cd', dir })
+  $.log({ kind: 'cd', dir, verbose: !$.quiet && $.verbose })
   process.chdir(dir)
   $[CWD] = process.cwd()
 }
@@ -826,61 +826,6 @@ export async function kill(pid: number, signal = $.killSignal) {
   }
 }
 
-export type LogEntry = {
-  verbose?: boolean
-} & (
-  | {
-      kind: 'cmd'
-      cmd: string
-    }
-  | {
-      kind: 'stdout' | 'stderr'
-      data: Buffer
-    }
-  | {
-      kind: 'cd'
-      dir: string
-    }
-  | {
-      kind: 'fetch'
-      url: RequestInfo
-      init?: RequestInit
-    }
-  | {
-      kind: 'retry'
-      error: string
-    }
-  | {
-      kind: 'custom'
-      data: any
-    }
-)
-
-export function log(entry: LogEntry) {
-  if (!(entry.verbose ?? $.verbose)) return
-  switch (entry.kind) {
-    case 'cmd':
-      process.stderr.write(formatCmd(entry.cmd))
-      break
-    case 'stdout':
-    case 'stderr':
-    case 'custom':
-      process.stderr.write(entry.data)
-      break
-    case 'cd':
-      process.stderr.write('$ ' + chalk.greenBright('cd') + ` ${entry.dir}\n`)
-      break
-    case 'fetch':
-      const init = entry.init ? ' ' + inspect(entry.init) : ''
-      process.stderr.write(
-        '$ ' + chalk.greenBright('fetch') + ` ${entry.url}${init}\n`
-      )
-      break
-    case 'retry':
-      process.stderr.write(entry.error + '\n')
-  }
-}
-
 const promisifyStream = <S extends Writable>(
   stream: S,
   from: ProcessPromise
src/goods.ts
@@ -68,7 +68,7 @@ export async function fetch(
   url: RequestInfo,
   init?: RequestInit
 ): Promise<Response> {
-  $.log({ kind: 'fetch', url, init })
+  $.log({ kind: 'fetch', url, init, verbose: !$.quiet && $.verbose })
   return nodeFetch(url, init)
 }
 
@@ -163,10 +163,12 @@ export async function retry<T>(
       if (delayGen) delay = delayGen.next().value
       $.log({
         kind: 'retry',
-        error:
-          chalk.bgRed.white(' FAIL ') +
-          ` Attempt: ${attempt}${total == Infinity ? '' : `/${total}`}` +
-          (delay > 0 ? `; next in ${delay}ms` : ''),
+        total,
+        attempt,
+        delay,
+        exception: err,
+        verbose: !$.quiet && $.verbose,
+        error: `FAIL Attempt: ${attempt}/${total}, next: ${delay}`, // legacy
       })
       lastErr = err
       if (count == 0) break
src/repl.ts
@@ -16,7 +16,7 @@ import os from 'node:os'
 import path from 'node:path'
 import { inspect } from 'node:util'
 import { ProcessOutput, defaults } from './core.js'
-import { chalk } from './vendor.js'
+import { chalk } from './vendor-core.js'
 
 export async function startRepl() {
   defaults.verbose = false
src/util.ts
@@ -15,7 +15,8 @@
 import os from 'node:os'
 import path from 'node:path'
 import fs from 'node:fs'
-import { chalk } from './vendor-core.js'
+import { chalk, type RequestInfo, type RequestInit } from './vendor-core.js'
+import { inspect } from 'node:util'
 
 export { isStringLiteral } from './vendor-core.js'
 
@@ -139,6 +140,69 @@ export function parseDuration(d: Duration) {
   throw new Error(`Unknown duration: "${d}".`)
 }
 
+export type LogEntry = {
+  verbose?: boolean
+} & (
+  | {
+      kind: 'cmd'
+      cmd: string
+    }
+  | {
+      kind: 'stdout' | 'stderr'
+      data: Buffer
+    }
+  | {
+      kind: 'cd'
+      dir: string
+    }
+  | {
+      kind: 'fetch'
+      url: RequestInfo
+      init?: RequestInit
+    }
+  | {
+      kind: 'retry'
+      attempt: number
+      total: number
+      delay: number
+      exception: unknown
+      error?: string
+    }
+  | {
+      kind: 'custom'
+      data: any
+    }
+)
+
+export function log(entry: LogEntry) {
+  if (!entry.verbose) return
+  const stream = process.stderr
+  switch (entry.kind) {
+    case 'cmd':
+      stream.write(formatCmd(entry.cmd))
+      break
+    case 'stdout':
+    case 'stderr':
+    case 'custom':
+      stream.write(entry.data)
+      break
+    case 'cd':
+      stream.write('$ ' + chalk.greenBright('cd') + ` ${entry.dir}\n`)
+      break
+    case 'fetch':
+      const init = entry.init ? ' ' + inspect(entry.init) : ''
+      stream.write('$ ' + chalk.greenBright('fetch') + ` ${entry.url}${init}\n`)
+      break
+    case 'retry':
+      stream.write(
+        chalk.bgRed.white(' FAIL ') +
+          ` Attempt: ${entry.attempt}${entry.total == Infinity ? '' : `/${entry.total}`}` +
+          (entry.delay > 0 ? `; next in ${entry.delay}ms` : '') +
+          '\n'
+      )
+  }
+}
+
 export function formatCmd(cmd?: string): string {
   if (cmd == undefined) return chalk.grey('undefined')
   const chars = [...cmd]
test/package.test.js
@@ -62,9 +62,6 @@ describe('package', () => {
         'build/index.cjs',
         'build/index.d.ts',
         'build/index.js',
-        'build/repl.cjs',
-        'build/repl.d.ts',
-        'build/repl.js',
         'build/util.cjs',
         'build/util.d.ts',
         'build/util.js',
.size-limit.json
@@ -9,7 +9,7 @@
   {
     "name": "zx/index",
     "path": "build/*.{js,cjs}",
-    "limit": "803 kB",
+    "limit": "804 kB",
     "brotli": false,
     "gzip": false
   },
package.json
@@ -63,10 +63,10 @@
     "fmt": "prettier --write .",
     "fmt:check": "prettier --check .",
     "build": "npm run build:js && npm run build:dts && npm run build:tests",
-    "build:js": "node scripts/build-js.mjs --format=cjs --hybrid --entry=src/*.ts:!src/error.ts && npm run build:vendor",
+    "build:js": "node scripts/build-js.mjs --format=cjs --hybrid --entry=src/*.ts:!src/error.ts:!src/repl.ts && npm run build:vendor",
     "build:vendor": "node scripts/build-js.mjs --format=cjs --entry=src/vendor-*.ts --bundle=all",
     "build:tests": "node scripts/build-tests.mjs",
-    "build:dts": "tsc --project tsconfig.prod.json && rm build/error.d.ts && node scripts/build-dts.mjs",
+    "build:dts": "tsc --project tsconfig.prod.json && rm build/error.d.ts build/repl.d.ts && node scripts/build-dts.mjs",
     "docs:dev": "vitepress dev docs",
     "docs:build": "vitepress build docs",
     "docs:preview": "vitepress preview docs",