execa
execa copied to clipboard
Ability to prefix child process stdio lines with a custom string
Proposal: add a new option prefix (optional, string). If given, the child's stdout and stderr streams would be transformed so each line is prefixed with the given string.
Use case: when running several child processes in parallel and using inherit to pipe each child's stdio to the parent, prefixing would make it easier to see what's going on:
Promise.all(jobs.map((job, i) => execa(job.cmd, job.args, {
stdio: 'inherit',
prefix: `[job ${i + 1} of jobs.length] `,
}))).then(() => {
// ...
});
[job 1 of 4] blah blah
[job 3 of 4] blah blah
[job 3 of 4] blah blah blah
[job 2 of 4] blah
...
I think the best API would be to have a prefix option which would apply to both stdout and stderr streams, and also prefixStdout and prefixStderr in case you want to override them individually.
Happy to implement this if interested.
It's not possible to intercept the stdout/stderr when you're using inherit (Really wish it was though). We could support it on pipe, but not sure it belongs here.
Can't we just reimplement inherit so it doesn't actually use the underlying cp's inherit? AFAICT inherit is just shorthand for [process.stdin, process.stdout, process.stderr].
Relevant Node.js issue: https://github.com/nodejs/node/issues/8033
Re-opening because this feature still depends on #695.
PR at #699 implementing this.
The initial message's example would then written as:
const prefixLine = function * (line) {
yield `[job ${i + 1} of jobs.length] ${line}`
}
await Promise.all(jobs.map((job, i) => execa(
job.cmd,
job.args,
{ stdout: ['inherit', prefixLine] },
)))