166 lines
3.9 KiB
JavaScript
166 lines
3.9 KiB
JavaScript
'use strict';
|
|
|
|
var child_process = require('child_process');
|
|
var crossSpawn = require('cross-spawn');
|
|
var ChildProcessPromise = require('./ChildProcessPromise');
|
|
var ChildProcessError = require('./ChildProcessError');
|
|
|
|
var slice = Array.prototype.slice;
|
|
|
|
/**
|
|
* Promise wrapper for exec, execFile
|
|
*
|
|
* @param {String} method
|
|
* @param {...*} args
|
|
* @return {Promise}
|
|
*/
|
|
function doExec(method, args) {
|
|
var cp;
|
|
var cpPromise = new ChildProcessPromise();
|
|
var reject = cpPromise._cpReject;
|
|
var resolve = cpPromise._cpResolve;
|
|
|
|
var finalArgs = slice.call(args, 0);
|
|
finalArgs.push(callback);
|
|
|
|
cp = child_process[method].apply(child_process, finalArgs);
|
|
|
|
function callback(err, stdout, stderr) {
|
|
if (err) {
|
|
var commandStr = args[0] + (Array.isArray(args[1]) ? ' ' + args[1].join(' ') : '');
|
|
err.message += ' `' + commandStr + '` (exited with error code ' + err.code + ')';
|
|
err.stdout = stdout;
|
|
err.stderr = stderr;
|
|
var cpError = new ChildProcessError(err.message, err.code, child_process, stdout, stderr);
|
|
reject(cpError);
|
|
} else {
|
|
resolve({
|
|
childProcess: cp,
|
|
stdout: stdout,
|
|
stderr: stderr
|
|
});
|
|
}
|
|
}
|
|
|
|
cpPromise.childProcess = cp;
|
|
|
|
return cpPromise;
|
|
}
|
|
|
|
/**
|
|
* `exec` as Promised
|
|
*
|
|
* @param {String} command
|
|
* @param {Object} options
|
|
* @return {Promise}
|
|
*/
|
|
function exec() {
|
|
return doExec('exec', arguments);
|
|
}
|
|
|
|
/**
|
|
* `execFile` as Promised
|
|
*
|
|
* @param {String} command
|
|
* @param {Array} args
|
|
* @param {Object} options
|
|
* @return {Promise}
|
|
*/
|
|
function execFile() {
|
|
return doExec('execFile', arguments);
|
|
}
|
|
|
|
/**
|
|
* `spawn` as Promised
|
|
*
|
|
* @param {String} command
|
|
* @param {Array} args
|
|
* @param {Object} options
|
|
* @return {Promise}
|
|
*/
|
|
function doSpawn(method, command, args, options) {
|
|
var result = {};
|
|
|
|
var cp;
|
|
var cpPromise = new ChildProcessPromise();
|
|
var reject = cpPromise._cpReject;
|
|
var resolve = cpPromise._cpResolve;
|
|
|
|
var successfulExitCodes = options && options.successfulExitCodes || [0];
|
|
|
|
cp = method(command, args, options);
|
|
|
|
// Don't return the whole Buffered result by default.
|
|
var captureStdout = false;
|
|
var captureStderr = false;
|
|
|
|
var capture = options && options.capture;
|
|
if (capture) {
|
|
for (var i = 0, len = capture.length; i < len; i++) {
|
|
var cur = capture[i];
|
|
if (cur === 'stdout') {
|
|
captureStdout = true;
|
|
} else if (cur === 'stderr') {
|
|
captureStderr = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
result.childProcess = cp;
|
|
|
|
if (captureStdout) {
|
|
result.stdout = '';
|
|
|
|
cp.stdout.on('data', function (data) {
|
|
result.stdout += data;
|
|
});
|
|
}
|
|
|
|
if (captureStderr) {
|
|
result.stderr = '';
|
|
|
|
cp.stderr.on('data', function (data) {
|
|
result.stderr += data;
|
|
});
|
|
}
|
|
|
|
cp.on('error', reject);
|
|
|
|
cp.on('close', function (code) {
|
|
if (successfulExitCodes.indexOf(code) === -1) {
|
|
var commandStr = command + (args.length ? ' ' + args.join(' ') : '');
|
|
var message = '`' + commandStr + '` failed with code ' + code;
|
|
var err = new ChildProcessError(message, code, cp);
|
|
|
|
if (captureStderr) {
|
|
err.stderr = result.stderr.toString();
|
|
}
|
|
|
|
if (captureStdout) {
|
|
err.stdout = result.stdout.toString();
|
|
}
|
|
|
|
reject(err);
|
|
} else {
|
|
result.code = code;
|
|
resolve(result);
|
|
}
|
|
});
|
|
|
|
cpPromise.childProcess = cp;
|
|
|
|
return cpPromise;
|
|
}
|
|
|
|
function spawn(command, args, options) {
|
|
return doSpawn(crossSpawn, command, args, options);
|
|
}
|
|
|
|
function fork(modulePath, args, options) {
|
|
return doSpawn(child_process.fork, modulePath, args, options);
|
|
}
|
|
|
|
exports.exec = exec;
|
|
exports.execFile = execFile;
|
|
exports.spawn = spawn;
|
|
exports.fork = fork; |