Incremental migration from cross-spawn
Swap cross-spawn for bellpull/cross-spawn in one import, then move call sites to run() one at a time, and know what changes at each step.
1. Change the import
- import spawn from 'cross-spawn';
+ import spawn from 'bellpull/cross-spawn';bellpull/cross-spawn passes cross-spawn 7.0.6's own suite, 68 of 68, and require() works
too. The dependency tree goes from four packages to none. npx burgee migrate --dry-run lists
the imports it would rewrite.
2. Move a call site to run()
The drop-in returns a ChildProcess, and the caller collects output and waits for close.
run() does that and returns the result:
import spawn from 'bellpull/cross-spawn';
import { run } from 'bellpull';
import { install, runtimeWith } from './tools.mjs';
install();
const runtime = runtimeWith('bin');
// Before: a ChildProcess, and the bookkeeping around it.
const child = spawn('greet', ['1'], { env: runtime.env });
let out = '';
child.stdout.on('data', (chunk) => (out += chunk));
const code = await new Promise((resolve) => child.on('close', resolve));
console.log('spawn:', code, out.trim());
// After: one value.
const result = await run('greet', ['1'], { runtime });
console.log('run: ', result.code, result.stdout.trim(), result.ok);spawn: 1 hello from bin
run: 1 hello from bin falseWhat changes at a call site that moves:
- A deadline appears.
run()kills a child after 30 s unless you passtimeout; a long-running child — a dev server, a watcher — needstimeout: 0. - A missing command rejects with
NotFoundError, wherespawnemitted anerrorevent. - Output is collected. For a child whose output should go straight to the terminal, pass
stdio: 'inherit'; the result then has emptystdoutandstderr. - The environment is explicit. The runtime's
envandcwdare the child's, unless the call passes its own.
From which
- import which from 'which';
+ import which from 'bellpull/node-which';graded 5 of 5 by node-which's suite. Moving on to bellpull/which changes the answer's shape
({ path, from, ext } instead of a string) and stops searching empty and relative PATH
entries — see Finding the executable.
Testing resolution without process.env
Test what your program would run — on Linux, on Windows, with a hostile PATH — by passing a literal runtime instead of mutating process.env.
bellpull
Every export of bellpull, with its signature and doc comment: ambientRuntime, DEFAULT_GRACE, DEFAULT_TIMEOUT, escapeArgument, escapeCommand, extensionCandidates and 20 more, plus 9 types.