UNPKG

dis-dat

Version:

Run commands in parallel (dad / dis-and-dat) or sequentially (dtd / dis-then-dat)

76 lines (75 loc) 2.95 kB
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); } }); }