spawn-streaming
Version:
Formats spawn with prefix and colors
72 lines (71 loc) • 2.7 kB
JavaScript
import spawn, { crossSpawn } from 'cross-spawn-cb';
import oo from 'on-one';
import Queue from 'queue-cb';
import concatWritable from './lib/concatWritable.js';
import nextColor from './lib/nextColor.js';
import prefixTransform from './lib/prefixTransform.js';
function pipeline(input, output, options, color) {
if (options.prefix) return input.pipe(prefixTransform(options.prefix, color)).pipe(output);
return input.pipe(output);
}
export default function spawnStreaming(command, args, spawnOptions, options, callback) {
const { encoding, stdio, ...csOptions } = spawnOptions;
const cp = crossSpawn(command, args, csOptions);
const color = options.prefix ? nextColor() : null;
const outputs = {
stdout: null,
stderr: null
};
if (cp.stdout && process.stdout.getMaxListeners) {
process.stdout.setMaxListeners(process.stdout.getMaxListeners() + 1);
process.stderr.setMaxListeners(process.stderr.getMaxListeners() + 1);
}
const queue = new Queue();
if (cp.stdout) {
if (stdio === 'inherit') pipeline(cp.stdout, process.stdout, options, color);
else {
outputs.stdout = concatWritable((output)=>{
outputs.stdout.output = output.toString(encoding || 'utf8');
});
queue.defer(oo.bind(null, pipeline(cp.stdout, outputs.stdout, options, color), [
'error',
'end',
'close',
'finish'
]));
}
}
if (cp.stderr) {
if (stdio === 'inherit') pipeline(cp.stderr, process.stderr, options, color);
else {
outputs.stderr = concatWritable((output)=>{
outputs.stderr.output = output.toString(encoding || 'utf8');
});
queue.defer(oo.bind(null, pipeline(cp.stderr, outputs.stderr, options, color), [
'error',
'end',
'close',
'finish'
]));
}
}
queue.defer(spawn.worker.bind(null, cp, {
...csOptions,
encoding: 'utf8'
}));
queue.await((err)=>{
if (cp.stdout && process.stdout.getMaxListeners) {
process.stdout.setMaxListeners(process.stdout.getMaxListeners() - 1);
process.stderr.setMaxListeners(process.stderr.getMaxListeners() - 1);
}
const res = err ? err : {};
res.stdout = outputs.stdout ? outputs.stdout.output : null;
res.stderr = outputs.stderr ? outputs.stderr.output : null;
res.output = [
res.stdout,
res.stderr,
null
];
err ? callback(err) : callback(null, res);
});
}