Files
meteor/tools/utils/processes.js
2015-08-06 16:39:00 -07:00

124 lines
3.2 KiB
JavaScript

var Future = require('fibers/future');
var _ = require('underscore');
var child_process = require('child_process');
var Console = require('../console/console.js').Console;
var processes = exports;
var RunCommand = function (command, args, options) {
var self = this;
var defaultOptions = {};
// Make stdin,stdout & stderr pipes (not shared)
defaultOptions.stdio = ['pipe', 'pipe', 'pipe'];
defaultOptions.env = process.env;
defaultOptions.checkExitCode = true;
options = _.extend(defaultOptions, options);
self.command = command;
self.args = args;
self.options = options;
self.exitFuture = new Future();
self.exitCode = undefined;
self.stdout = '';
self.stderr = '';
};
_.extend(RunCommand.prototype, {
start: function () {
var self = this;
if (self.process) {
throw new Error("Process already started");
}
if (Console.isDebugEnabled()) {
var envString = '';
var defaultEnv = process.env;
if (self.options.env) {
_.each(self.options.env, function (v,k) {
var defaultV = defaultEnv[k];
if (v !== defaultV) {
envString += k + "=" + v + " ";
}
});
}
Console.debug("Running command", envString, self.command, self.args.join(' '));
}
self.process = child_process.spawn( self.command,
self.args,
self.options);
self.process.on('close', function (exitCode) {
self.exitCode = exitCode;
if (self.options.checkExitCode && exitCode != 0) {
console.log("Unexpected exit code", exitCode, "from", self.command, self.args, "\nstdout:\n", self.stdout, "\nstderr:\n", self.stderr);
}
self.exitFuture.isResolved() || self.exitFuture['return'](exitCode);
});
self.process.on('error', function (err) {
Console.debug("Error while running command", err);
self.exitError = err;
self.exitFuture.isResolved() || self.exitFuture['throw'](err);
});
self.process.stdout.on('data', function (data) {
self.stdout = self.stdout + data;
if (self.options.pipeOutput) {
Console.rawInfo(data);
}
if (self.options.onStdout) {
self.options.onStdout(data);
}
});
self.process.stderr.on('data', function (data) {
self.stderr = self.stderr + data;
if (self.options.pipeOutput) {
Console.rawError(data);
}
if (self.options.onStderr) {
self.options.onStderr(data);
}
});
self.stdin = self.process.stdin;
if (self.options.stdin) {
self.stdin.write(self.options.stdin);
}
if (self.options.detached) {
self.process.unref();
}
},
waitForExit: function () {
var self = this;
return self.exitFuture.wait();
},
kill: function () {
var self = this;
self.process.kill();
},
run: function () {
var self = this;
self.start();
if (self.options.detached) {
Console.debug("run called on detached process; won't wait");
return undefined;
}
self.waitForExit();
return { stdout: self.stdout, stderr: self.stderr, exitCode: self.exitCode };
}
});
exports.RunCommand = RunCommand;