Skip to content

Instantly share code, notes, and snippets.

@nmccready
Last active September 19, 2018 19:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nmccready/79338f6045c939785e5aebed2e1c4c99 to your computer and use it in GitHub Desktop.
Save nmccready/79338f6045c939785e5aebed2e1c4c99 to your computer and use it in GitHub Desktop.
easy running / chaining of spawn for gulp
const { spawn } = require('child_process');
const through = require('through2');
const Promise = require('bluebird');
const EventEmitter = require('events');
const logger = require('../debug').spawn('gulp:shell');
class NonZeroExit extends Error {
constructor(code, info) {
super();
this.info = info;
let infoMsg = '';
if (info) {
infoMsg = `\n\nInfo:\n${info.join('')}`;
}
this.message = `Non 0 exit code: ${code}${infoMsg}`;
}
}
const childProcessToEmitter = (child) => {
const retEmitter = new EventEmitter();
child.once('error', (e) => retEmitter.emit('error', e));
child.once('close', (code) => {
if (code !== 0) {
return retEmitter.emit('error', new NonZeroExit(code, child.$$extraInfo));
}
retEmitter.emit('close');
});
return retEmitter;
};
function enQueue(q, item, limit = 10) {
if (q.length === limit) {
q.shift();
}
q.push(item);
return item;
}
const handleOutput = (child, limit) =>
through((data, _, cb) => {
const str = String(data);
enQueue(child.$$extraInfo, str, limit);
logger(() => str);
cb();
});
const shell = (cmd, limit) => {
const child = spawn(cmd, { shell: true });
child.$$extraInfo = []; // cache last 10 lines
child.stdout.pipe(handleOutput(child, limit));
child.stderr.pipe(handleOutput(child, limit));
return childProcessToEmitter(child);
};
const shells = (commands, done) => {
const promise = Promise.each(
commands,
(c) =>
new Promise((resolve, reject) =>
shell(c)
.once('close', resolve)
.once('error', reject)
)
);
if (!done) return promise;
promise.then(() => done()).catch(done);
};
module.exports = {
NonZeroExit,
shell,
shells
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment