1 | import { Errors, ux } from '@oclif/core';
|
2 | import makeDebug from 'debug';
|
3 | import { createRequire } from 'node:module';
|
4 | import { fileURLToPath } from 'node:url';
|
5 | import { spawn } from './spawn.js';
|
6 | const require = createRequire(import.meta.url);
|
7 | const debug = makeDebug('@oclif/plugin-plugins:yarn');
|
8 | export class Yarn {
|
9 | bin;
|
10 | config;
|
11 | logLevel;
|
12 | constructor({ config, logLevel }) {
|
13 | this.config = config;
|
14 | this.logLevel = logLevel;
|
15 | }
|
16 | async exec(args = [], options) {
|
17 | const bin = await this.findYarn();
|
18 | debug('yarn binary path', bin);
|
19 | if (options.logLevel === 'verbose')
|
20 | args.push('--verbose');
|
21 | if (this.config.npmRegistry)
|
22 | args.push(`--registry=${this.config.npmRegistry}`);
|
23 | if (options.logLevel !== 'notice' && options.logLevel !== 'silent') {
|
24 | ux.stderr(`${options.cwd}: ${bin} ${args.join(' ')}`);
|
25 | }
|
26 | debug(`${options.cwd}: ${bin} ${args.join(' ')}`);
|
27 | try {
|
28 | const output = await spawn(bin, args, options);
|
29 | debug('yarn done');
|
30 | return output;
|
31 | }
|
32 | catch (error) {
|
33 | debug('yarn error', error);
|
34 | throw error;
|
35 | }
|
36 | }
|
37 | async install(args, opts) {
|
38 | return this.exec(['install', ...args], opts);
|
39 | }
|
40 | async findYarn() {
|
41 | if (this.bin)
|
42 | return this.bin;
|
43 | try {
|
44 | this.bin = require.resolve('yarn/bin/yarn.js', { paths: [this.config.root, fileURLToPath(import.meta.url)] });
|
45 | }
|
46 | catch {
|
47 | const { default: which } = await import('which');
|
48 | this.bin = await which('yarn');
|
49 | }
|
50 | if (!this.bin) {
|
51 | throw new Errors.CLIError('yarn not found');
|
52 | }
|
53 | return this.bin;
|
54 | }
|
55 | }
|