UNPKG

too

Version:

Combine multiple processes' Stdout/Stderr/SIGINT to keep them all foreground

90 lines (89 loc) 2.79 kB
import { getColorByIndex } from './colors.js'; import { Command } from './command.js'; import { DefaultLogger } from './logger.js'; export class SequentialExecutor { state; definition; env; logger; steps = []; constructor(state, definition = { steps: [] }, env = {}, logger = new DefaultLogger()) { this.state = state; this.definition = definition; this.env = env; this.logger = logger; for (let i = 0; i < definition.steps.length; i++) { const step = definition.steps[i]; const cmd = new Command(step.run, env, getColorByIndex(i), logger, step.label); this.steps.push(cmd); } } async run() { if (this.steps.length === 0) return; this.logger.stage(this.state); for (const step of this.steps) { step.env = { ...step.env, ...this.env }; await step.exec(); } } } export class ParallelExecutor { state; definition; env; logger; jobs = []; procs = []; constructor(state, definition, env = {}, logger = new DefaultLogger()) { this.state = state; this.definition = definition; this.env = env; this.logger = logger; for (let i = 0; i < definition.jobs.length; i++) { const job = definition.jobs[i]; const cmd = new Command(job.run, env, getColorByIndex(i), logger, job.label); this.jobs.push(cmd); } } async run() { this.logger.stage(this.state); for (const job of this.jobs) { job.env = { ...job.env, ...this.env }; this.procs.push(await job.start()); } await this.wait(); } async cleanup(signal) { const promises = []; this.procs.forEach((proc) => { promises.push(new Promise((resolve) => { try { if (proc.pid) process.kill(-proc.pid, signal); } catch (err) { const error = err; if (error.code === "ESRCH") return resolve(true); console.error(err.message); resolve(false); } proc.on("close", () => resolve(true)); })); }); return Promise.all(promises); } wait() { return Promise.all(this.procs.map((proc) => { return new Promise((resolve, reject) => { proc.on("exit", (code, signal) => { if (code !== 0) reject({ code, signal }); else resolve(code); }); }); })); } }