veendor
Version:
a tool for stroing your npm dependencies in arbitraty storage
129 lines (128 loc) • 5.12 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
result["default"] = mod;
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
const child_process_1 = __importDefault(require("child_process"));
const errors = __importStar(require("../errors"));
const logger_1 = require("../util/logger");
class CommandError extends errors.VeendorError {
constructor(message, output) {
super(message);
this.output = output;
}
}
exports.CommandError = CommandError;
class CommandTimeoutError extends CommandError {
}
exports.CommandTimeoutError = CommandTimeoutError;
class CommandReturnedNonZeroError extends CommandError {
}
exports.CommandReturnedNonZeroError = CommandReturnedNonZeroError;
class CommandWasKilledError extends CommandError {
}
exports.CommandWasKilledError = CommandWasKilledError;
var StdioPolicy;
(function (StdioPolicy) {
StdioPolicy[StdioPolicy["inherit"] = 0] = "inherit";
// getOutput will not get data from corresponding stream
StdioPolicy[StdioPolicy["copy"] = 1] = "copy";
// `process.stdout` / `process.stderr`
StdioPolicy[StdioPolicy["collect"] = 2] = "collect";
StdioPolicy[StdioPolicy["pipe"] = 3] = "pipe";
StdioPolicy[StdioPolicy["ignore"] = 4] = "ignore";
})(StdioPolicy = exports.StdioPolicy || (exports.StdioPolicy = {}));
function stdioPolicyToCpStdio(policy, fd) {
if (policy === StdioPolicy.inherit) {
return fd;
}
else if (policy === StdioPolicy.ignore) {
return 'ignore';
}
return 'pipe';
}
function getOutput(executable, args, { timeoutDuration = 0, cwd = process.cwd(), controlToken = {}, stdout = StdioPolicy.collect, stderr = StdioPolicy.collect, } = {}) {
return new Promise((resolve, reject) => {
const commandName = `[${executable} ${args.join(' ')}]`;
const logger = logger_1.getLogger();
let result = '';
let completed = false;
let timeout;
logger.debug(`Running ${commandName}; cwd: ${cwd}`);
const proc = child_process_1.default.spawn(executable, args, {
stdio: ['pipe', stdioPolicyToCpStdio(stdout, 1), stdioPolicyToCpStdio(stderr, 2)],
cwd,
});
controlToken.terminate = () => {
logger.debug(`Terminating ${commandName} using control token`);
proc.kill();
};
const deathHand = () => proc.kill();
process.on('exit', deathHand);
controlToken.stdio = proc.stdio;
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);
}
if (stdout === StdioPolicy.collect || stdout === StdioPolicy.copy) {
proc.stdout.on('data', data => {
result += data.toString();
if (stdout === StdioPolicy.copy) {
process.stdout.write(data);
}
});
}
if (stderr === StdioPolicy.collect || stderr === StdioPolicy.copy) {
proc.stderr.on('data', data => {
result += data.toString();
if (stdout === StdioPolicy.copy) {
process.stderr.write(data);
}
});
}
proc.on('exit', (code, signal) => {
process.removeListener('exit', deathHand);
if (!completed) {
if (code === 0) {
logger.debug(`Command ${commandName} exited with 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;
}
});
});
}
exports.getOutput = getOutput;