dis-dat
Version:
Run commands in parallel (dad / dis-and-dat) or sequentially (dtd / dis-then-dat)
76 lines (75 loc) • 2.95 kB
JavaScript
import spawn from 'cross-spawn-cb';
import Queue from 'queue-cb';
import spawnStreaming from 'spawn-streaming';
import { createSession, formatArguments } from 'spawn-term';
import { parseArgsStringToArgv } from 'string-argv';
const bracketsRegEx = /\{([\s\S]*)\}/;
export default function worker(commands, options, callback) {
const spawnOptions = {
cwd: process.cwd(),
...options
};
let results = [];
const queue = new Queue(options.concurrency || Infinity);
// Create session once for all processes (only if multiple commands)
const interactive = !!options.interactive;
const session = commands.length >= 2 && process.stdout.isTTY && createSession && !options.streaming ? createSession({
header: commands.join(' | '),
interactive
}) : null;
commands.forEach((_, index)=>{
queue.defer((cb)=>{
const match = commands[index].match(bracketsRegEx);
const argv = match ? parseArgsStringToArgv(match[1]) : parseArgsStringToArgv(commands[index]);
const command = argv[0];
const args = argv.slice(1);
const prefix = formatArguments(argv).join(' ');
function next(err, res) {
if (err && err.message.indexOf('ExperimentalWarning') >= 0) {
res = err;
err = null;
}
// suppress error
if (err && match) {
res = err;
err = null;
}
results.push({
index,
command,
args,
error: err,
result: res
});
if (err && options.concurrency === 1) {
cb(err); // break early
return;
}
cb();
}
if (!session && !options.silent) console.log(`${index > 0 ? '\n' : ''}$ ${formatArguments([
command
].concat(args)).join(' ')}`);
// Show command when running single command (no terminal session, unless silent)
if (commands.length < 2) spawn(command, args, spawnOptions, next);
else if (session) session.spawn(command, args, spawnOptions, {
group: prefix,
expanded: options.expanded
}, next);
else spawnStreaming(command, args, spawnOptions, {
prefix: process.stdout.isTTY ? prefix : undefined
}, next);
});
});
queue.await((err)=>{
results = results.sort((a, b)=>a.index - b.index);
if (err) err.results = results;
if (session) {
session.waitAndClose(()=>{
err ? callback(err) : callback(null, results);
});
} else {
err ? callback(err) : callback(null, results);
}
});
}