UNPKG

@dependabot/yarn-lib

Version:

📦🐈 Fast, reliable, and secure dependency management.

214 lines (169 loc) 5.81 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.exec = exports.queue = undefined; exports.forkp = forkp; exports.spawnp = spawnp; exports.forwardSignalToSpawnedProcesses = forwardSignalToSpawnedProcesses; exports.spawn = spawn; var _constants; function _load_constants() { return _constants = _interopRequireWildcard(require('../constants.js')); } var _blockingQueue; function _load_blockingQueue() { return _blockingQueue = _interopRequireDefault(require('./blocking-queue.js')); } var _errors; function _load_errors() { return _errors = require('../errors.js'); } var _promise; function _load_promise() { return _promise = require('./promise.js'); } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } /* global child_process$spawnOpts */ const os = require('os'); const child = require('child_process'); const fs = require('fs'); const path = require('path'); const queue = exports.queue = new (_blockingQueue || _load_blockingQueue()).default('child', (_constants || _load_constants()).CHILD_CONCURRENCY); // TODO: this uid check is kinda whack let uid = 0; const exec = exports.exec = (0, (_promise || _load_promise()).promisify)(child.exec); function validate(program, opts = {}) { if (program.match(/[\\\/]/)) { return; } if (process.platform === 'win32' && process.env.PATHEXT) { const cwd = opts.cwd || process.cwd(); const pathext = process.env.PATHEXT; for (var _iterator = pathext.split(';'), _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) { var _ref; if (_isArray) { if (_i >= _iterator.length) break; _ref = _iterator[_i++]; } else { _i = _iterator.next(); if (_i.done) break; _ref = _i.value; } const ext = _ref; const candidate = path.join(cwd, `${program}${ext}`); if (fs.existsSync(candidate)) { throw new Error(`Potentially dangerous call to "${program}" in ${cwd}`); } } } } function forkp(program, args, opts) { validate(program, opts); const key = String(++uid); return new Promise((resolve, reject) => { const proc = child.fork(program, args, opts); spawnedProcesses[key] = proc; proc.on('error', error => { reject(error); }); proc.on('close', (exitCode, signal) => { const finalExitCode = typeof exitCode !== `undefined` && exitCode !== null ? exitCode : 128 + os.constants.signals[signal]; resolve(finalExitCode); }); }); } function spawnp(program, args, opts) { validate(program, opts); const key = String(++uid); return new Promise((resolve, reject) => { const proc = child.spawn(program, args, opts); spawnedProcesses[key] = proc; proc.on('error', error => { reject(error); }); proc.on('close', (exitCode, signal) => { const finalExitCode = typeof exitCode !== `undefined` && exitCode !== null ? exitCode : 128 + os.constants.signals[signal]; resolve(finalExitCode); }); }); } const spawnedProcesses = {}; function forwardSignalToSpawnedProcesses(signal) { for (var _iterator2 = Object.keys(spawnedProcesses), _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) { var _ref2; if (_isArray2) { if (_i2 >= _iterator2.length) break; _ref2 = _iterator2[_i2++]; } else { _i2 = _iterator2.next(); if (_i2.done) break; _ref2 = _i2.value; } const key = _ref2; spawnedProcesses[key].kill(signal); } } function spawn(program, args, opts = {}, onData) { const key = opts.cwd || String(++uid); return queue.push(key, () => new Promise((resolve, reject) => { validate(program, opts); const proc = child.spawn(program, args, opts); spawnedProcesses[key] = proc; let processingDone = false; let processClosed = false; let err = null; let stdout = ''; proc.on('error', err => { if (err.code === 'ENOENT') { reject(new (_errors || _load_errors()).ProcessSpawnError(`Couldn't find the binary ${program}`, err.code, program)); } else { reject(err); } }); function updateStdout(chunk) { stdout += chunk; if (onData) { onData(chunk); } } function finish() { delete spawnedProcesses[key]; if (err) { reject(err); } else { resolve(stdout.trim()); } } if (typeof opts.process === 'function') { opts.process(proc, updateStdout, reject, function () { if (processClosed) { finish(); } else { processingDone = true; } }); } else { if (proc.stderr) { proc.stderr.on('data', updateStdout); } if (proc.stdout) { proc.stdout.on('data', updateStdout); } processingDone = true; } proc.on('close', (code, signal) => { if (signal || code >= 1) { err = new (_errors || _load_errors()).ProcessTermError(['Command failed.', signal ? `Exit signal: ${signal}` : `Exit code: ${code}`, `Command: ${program}`, `Arguments: ${args.join(' ')}`, `Directory: ${opts.cwd || process.cwd()}`, `Output:\n${stdout.trim()}`].join('\n')); err.EXIT_SIGNAL = signal; err.EXIT_CODE = code; } if (processingDone || err) { finish(); } else { processClosed = true; } }); })); }