mirror of
https://github.com/meteor/meteor.git
synced 2026-05-02 03:01:46 -04:00
Now that we no longer have an automatic newline on printing, we don't have to support the awkward legacy functions that the Console used to provide. Eliminating.
124 lines
3.2 KiB
JavaScript
124 lines
3.2 KiB
JavaScript
var Future = require('fibers/future');
|
|
var _ = require('underscore');
|
|
var child_process = require('child_process');
|
|
var Console = require('./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;
|