Commit 5a3e890
Changed files (5)
test
src/core.ts
@@ -22,9 +22,12 @@ import { chalk, which } from './goods.js'
import { log } from './log.js'
import { exitCodeInfo, noop, psTree, quote, substitute } from './util.js'
-type Shell = (pieces: TemplateStringsArray, ...args: any[]) => ProcessPromise
+export type Shell = (
+ pieces: TemplateStringsArray,
+ ...args: any[]
+) => ProcessPromise
-type Options = {
+export type Options = {
verbose: boolean
cwd: string
env: NodeJS.ProcessEnv
@@ -93,7 +96,7 @@ export const $ = new Proxy<Shell & Options>(
}
cmd += s + pieces[++i]
}
- promise._bind(cmd, $.cwd, from, resolve!, reject!)
+ promise._bind(cmd, from, resolve!, reject!, getStore())
// Make sure all subprocesses are started, if not explicitly by await or then().
setImmediate(() => promise._run())
return promise
@@ -115,10 +118,10 @@ type IO = StdioPipe | StdioNull
export class ProcessPromise extends Promise<ProcessOutput> {
child?: ChildProcess
private _command = ''
- private _cwd = ''
private _from = ''
private _resolve: Resolve = noop
private _reject: Resolve = noop
+ private _snapshot = getStore()
private _stdio: [IO, IO, IO] = ['inherit', 'pipe', 'pipe']
private _nothrow = false
private _quiet = false
@@ -129,24 +132,29 @@ export class ProcessPromise extends Promise<ProcessOutput> {
_bind(
cmd: string,
- cwd: string,
from: string,
resolve: Resolve,
- reject: Resolve
+ reject: Resolve,
+ options: Options
) {
this._command = cmd
- this._cwd = cwd
this._from = from
this._resolve = resolve
this._reject = reject
+ this._snapshot = { ...options }
}
_run() {
+ const $ = this._snapshot
if (this.child) return // The _run() called from two places: then() and setImmediate().
this._prerun() // In case $1.pipe($2), the $2 returned, and on $2._run() invoke $1._run().
- $.log('cmd', this._command, { source: this })
+ $.log({
+ kind: 'cmd',
+ cmd: this._command,
+ verbose: $.verbose && !this._quiet,
+ })
this.child = spawn($.prefix + this._command, {
- cwd: this._cwd,
+ cwd: $.cwd,
shell: typeof $.shell === 'string' ? $.shell : true,
stdio: this._stdio,
windowsHide: true,
@@ -182,12 +190,12 @@ export class ProcessPromise extends Promise<ProcessOutput> {
stderr = '',
combined = ''
let onStdout = (data: any) => {
- $.log('stdout', data, { source: this })
+ $.log({ kind: 'stdout', data, verbose: $.verbose && !this._quiet })
stdout += data
combined += data
}
let onStderr = (data: any) => {
- $.log('stderr', data, { source: this })
+ $.log({ kind: 'stderr', data, verbose: $.verbose && !this._quiet })
stderr += data
combined += data
}
src/goods.ts
@@ -40,12 +40,12 @@ globbyModule)
export const glob = globby
export async function fetch(url: RequestInfo, init?: RequestInit) {
- $.log('fetch', url.toString(), { init })
+ $.log({ kind: 'fetch', url, init })
return nodeFetch(url, init)
}
export function cd(dir: string) {
- $.log('cd', dir)
+ $.log({ kind: 'cd', dir })
$.cwd = path.resolve($.cwd, dir)
process.chdir($.cwd)
}
src/index.ts
@@ -14,7 +14,14 @@
import { ProcessPromise } from './core.js'
-export { $, ProcessPromise, ProcessOutput, within } from './core.js'
+export {
+ $,
+ Shell,
+ Options,
+ ProcessPromise,
+ ProcessOutput,
+ within,
+} from './core.js'
export {
argv,
@@ -34,7 +41,7 @@ export {
YAML,
} from './goods.js'
-export { log, formatCmd, LogKind, LogExtra } from './log.js'
+export { log, formatCmd, LogEntry } from './log.js'
/**
* @deprecated Use $.nothrow() instead.
src/log.ts
@@ -12,38 +12,54 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import { RequestInit } from 'node-fetch'
+import { RequestInfo, RequestInit } from 'node-fetch'
import { inspect } from 'node:util'
-import { $, ProcessPromise } from './core.js'
+import { $ } from './core.js'
import { colorize } from './util.js'
-export type LogKind = 'cmd' | 'stdout' | 'stderr' | 'cd' | 'fetch'
-export type LogExtra = {
- source?: ProcessPromise
- init?: RequestInit
-}
-
-export function log(kind: LogKind, data: string, extra: LogExtra = {}) {
- if (extra.source?.isQuiet()) return
- if ($.verbose) {
- switch (kind) {
- case 'cmd':
- process.stderr.write(formatCmd(data))
- break
- case 'stdout':
- case 'stderr':
- process.stderr.write(data)
- break
- case 'cd':
- process.stderr.write('$ ' + colorize(`cd ${data}`) + '\n')
- break
- case 'fetch':
- const init = extra.init ? ' ' + inspect(extra.init) : ''
- process.stderr.write('$ ' + colorize(`fetch ${data}`) + init + '\n')
- break
- default:
- throw new Error(`Unknown log kind "${kind}".`)
+export type LogEntry =
+ | {
+ kind: 'cmd'
+ verbose: boolean
+ cmd: string
+ }
+ | {
+ kind: 'stdout' | 'stderr'
+ verbose: boolean
+ data: Buffer
}
+ | {
+ kind: 'cd'
+ dir: string
+ }
+ | {
+ kind: 'fetch'
+ url: RequestInfo
+ init?: RequestInit
+ }
+
+export function log(entry: LogEntry) {
+ switch (entry.kind) {
+ case 'cmd':
+ if (!entry.verbose) return
+ process.stderr.write(formatCmd(entry.cmd))
+ break
+ case 'stdout':
+ case 'stderr':
+ if (!entry.verbose) return
+ process.stderr.write(entry.data)
+ break
+ case 'cd':
+ if (!$.verbose) return
+ process.stderr.write('$ ' + colorize(`cd ${entry.dir}`) + '\n')
+ break
+ case 'fetch':
+ if (!$.verbose) return
+ const init = entry.init ? ' ' + inspect(entry.init) : ''
+ process.stderr.write('$ ' + colorize(`fetch ${entry.url}`) + init + '\n')
+ break
+ default:
+ throw new Error(`Unknown log kind.`)
}
}
test/index.test.js
@@ -467,4 +467,15 @@ test('stdio() works', async () => {
assert.is((await b).stdout, 'bar')
})
+test('snapshots works', async () => {
+ await within(async () => {
+ $.prefix += 'echo success;'
+ let p = $`:`
+ $.prefix += 'echo fail;'
+ let out = await p
+ assert.is(out.stdout, 'success\n')
+ assert.not.match(out.stdout, 'fail')
+ })
+})
+
test.run()