UNPKG

veendor

Version:

a tool for stroing your npm dependencies in arbitraty storage

129 lines (128 loc) 5.12 kB
'use strict'; 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;