veendor
Version:
a tool for stroing your npm dependencies in arbitraty storage
99 lines (82 loc) • 3.29 kB
JavaScript
;
const childProcess = require('child_process');
const getLogger = require('../logger').getLogger;
class CommandError extends Error {
constructor(message, output) {
super(message);
this.output = output;
}
}
class CommandTimeoutError extends CommandError {}
class CommandReturnedNonZeroError extends CommandError {}
class CommandWasKilledError extends CommandError {}
module.exports = {
getOutput: function getOutput(executable, args, {
timeoutDuration = 0,
cwd = process.cwd(),
pipeToParent = false, // If true, every chunk of data will be pushed to stdout or stderr,
// like {stdio: 'inherit'}
} = {}) {
return new Promise((resolve, reject) => {
const commandName = `[${executable} ${args.join(' ')}]`;
const logger = getLogger();
let result = '';
let completed = false;
let timeout;
logger.debug(`Running ${commandName}; cwd: ${cwd}`);
const proc = childProcess.spawn(executable, args, {stdio: 'pipe', cwd});
if (timeoutDuration !== 0) {
timeout = setTimeout(() => {
if (!completed) {
const message = `command ${commandName} timed out (${timeoutDuration} ms)`;
logger.debug(message);
reject(new CommandTimeoutError(message, result));
completed = true;
}
}, timeoutDuration);
}
proc.stdout.on('data', data => {
result += data.toString();
if (pipeToParent) {
process.stdout.write(data);
}
});
proc.stderr.on('data', data => {
result += data.toString();
if (pipeToParent) {
process.stderr.write(data);
}
});
proc.on('exit', (code, signal) => {
if (!completed) {
if (code === 0) {
resolve(result);
} else if (code) {
const message = `command ${commandName} returned ${code}`;
logger.debug(message);
reject(new CommandReturnedNonZeroError(message, result));
} else {
const message = `command ${commandName} killed with signal ${signal}`;
logger.debug(message);
reject(new CommandWasKilledError(message, result));
}
clearTimeout(timeout);
completed = true;
}
});
proc.on('error', error => {
if (!completed) {
const message = `command ${commandName} failed: ${error.message}`;
logger.debug(message);
reject(new CommandError(message, result));
clearTimeout(timeout);
completed = true;
}
});
});
},
CommandError,
CommandTimeoutError,
CommandReturnedNonZeroError,
CommandWasKilledError,
};