Last active
September 19, 2018 19:58
-
-
Save nmccready/79338f6045c939785e5aebed2e1c4c99 to your computer and use it in GitHub Desktop.
easy running / chaining of spawn for gulp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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