@dependabot/yarn-lib
Version:
📦🐈 Fast, reliable, and secure dependency management.
214 lines (169 loc) • 5.81 kB
JavaScript
;
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;
}
});
}));
}