@oclif/plugin-plugins
Version:
plugins plugin for oclif
91 lines (90 loc) • 3.95 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const core_1 = require("@oclif/core");
const child_process_1 = require("child_process");
const path = require("path");
const debug = require('debug')('cli:yarn');
class Yarn {
constructor({ config }) {
this.config = config;
}
get bin() {
return require.resolve('yarn/bin/yarn.js');
}
fork(modulePath, args = [], options = {}) {
return new Promise((resolve, reject) => {
var _a, _b, _c;
const forked = (0, child_process_1.fork)(modulePath, args, options);
(_a = forked.stderr) === null || _a === void 0 ? void 0 : _a.on('data', (d) => process.stderr.write(d));
(_b = forked.stdout) === null || _b === void 0 ? void 0 : _b.setEncoding('utf8');
(_c = forked.stdout) === null || _c === void 0 ? void 0 : _c.on('data', (d) => {
if (options.verbose)
process.stdout.write(d);
else
core_1.ux.action.status = d.replace(/\n$/, '').split('\n').pop();
});
forked.on('error', reject);
forked.on('exit', (code) => {
if (code === 0) {
resolve();
}
else {
reject(new Error(`${modulePath} ${args.join(' ')} exited with code ${code}`));
}
});
// Fix windows bug with node-gyp hanging for input forever
// if (this.config.windows) {
// forked.stdin.write('\n')
// }
});
}
// eslint-disable-next-line default-param-last
async exec(args = [], opts) {
const cwd = opts.cwd;
if (args[0] !== 'run') {
// https://classic.yarnpkg.com/lang/en/docs/cli/#toc-concurrency-and-mutex
// Default port is: 31997
const port = this.config.scopedEnvVar('NETWORK_MUTEX_PORT');
const optionalPort = port ? `:${port}` : '';
const mutex = this.config.scopedEnvVar('USE_NETWORK_MUTEX') ? `network${optionalPort}` : `file:${path.join(cwd, 'yarn.lock')}`;
const cacheDir = path.join(this.config.cacheDir, 'yarn');
args = [
...args,
'--non-interactive',
`--mutex=${mutex}`,
`--preferred-cache-folder=${cacheDir}`,
'--check-files',
];
if (opts.verbose) {
args.push('--verbose');
}
if (this.config.npmRegistry) {
args.push(`--registry=${this.config.npmRegistry}`);
}
}
const npmRunPath = require('npm-run-path');
const options = Object.assign(Object.assign({}, opts), { cwd, stdio: [0, null, null, 'ipc'], env: npmRunPath.env({ cwd, env: process.env }),
// Remove --loader ts-node/esm from execArgv so that the subprocess doesn't fail if it can't find ts-node.
// The ts-node/esm loader isn't need to execute yarn commands anyways.
execArgv: process.execArgv.join(' ').replace('--loader ts-node/esm', '').split(' ').filter(Boolean) });
if (opts.verbose) {
process.stderr.write(`${cwd}: ${this.bin} ${args.join(' ')}`);
}
debug(`${cwd}: ${this.bin} ${args.join(' ')}`);
try {
await this.fork(this.bin, args, options);
debug('yarn done');
}
catch (error) {
debug('yarn error', error);
// to-do: https://github.com/yarnpkg/yarn/issues/2191
const networkConcurrency = '--network-concurrency=1';
if (error.message.includes('EAI_AGAIN') && !args.includes(networkConcurrency)) {
debug('EAI_AGAIN');
return this.exec([...args, networkConcurrency], opts);
}
throw error;
}
}
}
exports.default = Yarn;