[Pkg-javascript-devel] Bug#1058615: bookworm-pu: package node-yarnpkg/1.22.19+~cs24.27.18-2+deb12u1

Praveen Arimbrathodiyil praveen at onenetbeyond.org
Wed Dec 13 15:39:37 GMT 2023


Package: release.debian.org
Severity: normal
Tags: bookworm
User: release.debian.org at packages.debian.org
Usertags: pu
X-Debbugs-Cc: node-yarnpkg at packages.debian.org
Control: affects -1 + src:node-yarnpkg

This fixes rc bug #1058596

[ Reason ]
The version in bookworm included a patch for node-commander 8+ support 
but which was not working, this was fixed in unstable later but was not 
backported to stable.

[ Impact ]
yarnpkg command is broken if any command line argument is used.

[ Tests ]
Tested manually on bookworm.

[ Risks ]
This is already working on unstable.

[ Checklist ]
   [x] *all* changes are documented in the d/changelog
   [x] I reviewed all changes and I approve them
   [x] attach debdiff against the package in (old)stable
   [x] the issue is verified as fixed in unstable

[ Changes ]
Backported the patch from unstable.

[ Other info ]
(Anything else the release team should know.)
-------------- next part --------------
diff -Nru node-yarnpkg-1.22.19+~cs24.27.18/debian/changelog node-yarnpkg-1.22.19+~cs24.27.18/debian/changelog
--- node-yarnpkg-1.22.19+~cs24.27.18/debian/changelog	2022-11-14 09:52:50.000000000 +0530
+++ node-yarnpkg-1.22.19+~cs24.27.18/debian/changelog	2023-12-13 20:54:48.000000000 +0530
@@ -1,3 +1,9 @@
+node-yarnpkg (1.22.19+~cs24.27.18-2+deb12u1) bookworm; urgency=medium
+
+  * Backport patch from unstable for commander 8 support (Closes: #1058596)
+
+ -- Pirate Praveen <praveen at debian.org>  Wed, 13 Dec 2023 20:54:48 +0530
+
 node-yarnpkg (1.22.19+~cs24.27.18-2) unstable; urgency=medium
 
   * Team upload
diff -Nru node-yarnpkg-1.22.19+~cs24.27.18/debian/patches/fix-for-commander-8.patch node-yarnpkg-1.22.19+~cs24.27.18/debian/patches/fix-for-commander-8.patch
--- node-yarnpkg-1.22.19+~cs24.27.18/debian/patches/fix-for-commander-8.patch	2022-11-14 09:52:50.000000000 +0530
+++ node-yarnpkg-1.22.19+~cs24.27.18/debian/patches/fix-for-commander-8.patch	2023-12-13 20:52:11.000000000 +0530
@@ -1,11 +1,1037 @@
 Description: fix for node-commander ≥ 8
-Author: Yadd <yadd at debian.org>
+Author: Yadd <yadd at debian.org>, Konstantin Demin <rockdrilla at gmail.com>
 Forwarded: no
-Last-Update: 2022-11-13
+Last-Update: 2023-09-15
 
+---
+ src/cli/commands/_build-sub-commands.js |  4 +-
+ src/cli/commands/access.js              | 31 ++++----
+ src/cli/commands/add.js                 |  4 +-
+ src/cli/commands/audit.js               |  2 +-
+ src/cli/commands/autoclean.js           |  2 +-
+ src/cli/commands/bin.js                 |  2 +-
+ src/cli/commands/cache.js               |  8 +-
+ src/cli/commands/check.js               |  2 +-
+ src/cli/commands/config.js              | 27 ++++---
+ src/cli/commands/create.js              |  4 +-
+ src/cli/commands/exec.js                |  2 +-
+ src/cli/commands/generate-lock-entry.js |  2 +-
+ src/cli/commands/global.js              | 22 +++---
+ src/cli/commands/help.js                | 38 +++++-----
+ src/cli/commands/import.js              |  2 +-
+ src/cli/commands/info.js                |  2 +-
+ src/cli/commands/init.js                |  2 +-
+ src/cli/commands/install.js             |  4 +-
+ src/cli/commands/licenses.js            | 19 +++--
+ src/cli/commands/link.js                |  4 +-
+ src/cli/commands/list.js                |  6 +-
+ src/cli/commands/login.js               |  2 +-
+ src/cli/commands/logout.js              |  2 +-
+ src/cli/commands/node.js                |  2 +-
+ src/cli/commands/outdated.js            |  4 +-
+ src/cli/commands/owner.js               | 23 +++---
+ src/cli/commands/pack.js                |  1 +
+ src/cli/commands/policies.js            |  2 +-
+ src/cli/commands/publish.js             |  2 +-
+ src/cli/commands/remove.js              |  4 +-
+ src/cli/commands/run.js                 |  2 +-
+ src/cli/commands/tag.js                 | 23 +++---
+ src/cli/commands/team.js                | 17 +++--
+ src/cli/commands/unlink.js              |  4 +-
+ src/cli/commands/unplug.js              |  6 +-
+ src/cli/commands/upgrade-interactive.js |  2 +-
+ src/cli/commands/upgrade.js             |  2 +-
+ src/cli/commands/version.js             |  4 +-
+ src/cli/commands/versions.js            |  2 +-
+ src/cli/commands/why.js                 |  4 +-
+ src/cli/commands/workspace.js           |  2 +-
+ src/cli/commands/workspaces.js          |  4 +-
+ src/cli/index.js                        | 99 +++++++++++++------------
+ src/rc.js                               |  6 +-
+ src/util/execute-lifecycle-script.js    |  2 +-
+ 45 files changed, 218 insertions(+), 192 deletions(-)
+
+--- a/src/cli/commands/_build-sub-commands.js
++++ b/src/cli/commands/_build-sub-commands.js
+@@ -26,11 +26,11 @@
+     commander.usage(`${rootCommandName} [${subCommandNames.join('|')}] [flags]`);
+   }
+ 
+-  async function run(config: Config, reporter: Reporter, flags: Object, args: Array<string>): Promise<void> {
++  async function run(config: Config, reporter: Reporter, commander: Object, flags: Object, args: Array<string>): Promise<void> {
+     const subName: ?string = camelCase(args.shift() || '');
+     if (subName && subCommands[subName]) {
+       const command: CLIFunction = subCommands[subName];
+-      const res = await command(config, reporter, flags, args);
++      const res = await command(config, reporter, commander, flags, args);
+       if (res !== false) {
+         return Promise.resolve();
+       }
+--- a/src/cli/commands/access.js
++++ b/src/cli/commands/access.js
+@@ -2,25 +2,21 @@
+ 
+ import buildSubCommands from './_build-sub-commands.js';
+ 
+-const notYetImplemented = () => Promise.reject(new Error('This command is not implemented yet.'));
++const notImplemented = () => Promise.reject(new Error('This command is not implemented.'));
+ 
+-export function setFlags(commander: Object) {
+-  commander.description('Has not been implemented yet');
+-}
+-
+-export const {run, hasWrapper, examples} = buildSubCommands(
++const {run, setFlags: _setFlags, hasWrapper, examples} = buildSubCommands(
+   'access',
+   {
+-    public: notYetImplemented,
+-    restricted: notYetImplemented,
+-    grant: notYetImplemented,
+-    revoke: notYetImplemented,
+-    lsPackages: notYetImplemented,
+-    lsCollaborators: notYetImplemented,
+-    edit: notYetImplemented,
++    public: notImplemented,
++    restricted: notImplemented,
++    grant: notImplemented,
++    revoke: notImplemented,
++    lsPackages: notImplemented,
++    lsCollaborators: notImplemented,
++    edit: notImplemented,
+   },
+   [
+-    'WARNING: This command yet to be implemented.',
++    'WARNING: This command is not implemented.',
+     'public [<package>]',
+     'restricted [<package>]',
+     'grant <read-only|read-write> <scope:team> [<package>]',
+@@ -30,3 +26,10 @@
+     'edit [<package>]',
+   ],
+ );
++
++export {run, hasWrapper, examples};
++
++export function setFlags(commander: Object) {
++  _setFlags(commander);
++  commander.description('Has not been implemented');
++}
+--- a/src/cli/commands/add.js
++++ b/src/cli/commands/add.js
+@@ -303,8 +303,8 @@
+   commander.option('-A, --audit', 'Run vulnerability audit on installed packages');
+ }
+ 
+-export async function run(config: Config, reporter: Reporter, flags: Object, args: Array<string>): Promise<void> {
+-  if (!args.length) {
++export async function run(config: Config, reporter: Reporter, commander: Object, flags: Object, args: Array<string>): Promise<void> {
++  if (args.length < 1) {
+     throw new MessageError(reporter.lang('missingAddDependencies'));
+   }
+ 
+--- a/src/cli/commands/audit.js
++++ b/src/cli/commands/audit.js
+@@ -140,7 +140,7 @@
+   return true;
+ }
+ 
+-export async function run(config: Config, reporter: Reporter, flags: Object, args: Array<string>): Promise<number> {
++export async function run(config: Config, reporter: Reporter, commander: Object, flags: Object, args: Array<string>): Promise<number> {
+   const DEFAULT_LOG_LEVEL = 'info';
+   const audit = new Audit(config, reporter, {
+     groups: flags.groups || OWNED_DEPENDENCY_TYPES,
+--- a/src/cli/commands/autoclean.js
++++ b/src/cli/commands/autoclean.js
+@@ -147,7 +147,7 @@
+   return exists;
+ }
+ 
+-export async function run(config: Config, reporter: Reporter, flags: Object, args: Array<string>): Promise<void> {
++export async function run(config: Config, reporter: Reporter, commander: Object, flags: Object, args: Array<string>): Promise<void> {
+   const cleanFileExists = await checkForCleanFile(config.cwd);
+ 
+   if (flags.init && cleanFileExists) {
+--- a/src/cli/commands/bin.js
++++ b/src/cli/commands/bin.js
+@@ -14,7 +14,7 @@
+   commander.description('Displays the location of the yarn bin folder.');
+ }
+ 
+-export async function run(config: Config, reporter: Reporter, flags: Object, args: Array<string>): Promise<void> {
++export async function run(config: Config, reporter: Reporter, commander: Object, flags: Object, args: Array<string>): Promise<void> {
+   const binFolder = path.join(config.cwd, config.registryFolders[0], '.bin');
+   if (args.length === 0) {
+     reporter.log(binFolder, {force: true});
+--- a/src/cli/commands/cache.js
++++ b/src/cli/commands/cache.js
+@@ -76,7 +76,7 @@
+   );
+ }
+ 
+-async function list(config: Config, reporter: Reporter, flags: Object, args: Array<string>): Promise<void> {
++async function list(config: Config, reporter: Reporter, commander: Object, flags: Object, args: Array<string>): Promise<void> {
+   const filterOut = ({registry, package: manifest, remote} = {}) => {
+     if (flags.pattern && !micromatch.contains(manifest.name, flags.pattern)) {
+       return false;
+@@ -96,7 +96,7 @@
+   reporter.table(['Name', 'Version', 'Registry', 'Resolved'], body);
+ }
+ 
+-async function clean(config: Config, reporter: Reporter, flags: Object, args: Array<string>): Promise<void> {
++async function clean(config: Config, reporter: Reporter, commander: Object, flags: Object, args: Array<string>): Promise<void> {
+   if (config.cacheFolder) {
+     const activity = reporter.activity();
+ 
+@@ -127,9 +127,9 @@
+ }
+ 
+ const {run, setFlags: _setFlags, examples} = buildSubCommands('cache', {
+-  async ls(config: Config, reporter: Reporter, flags: Object, args: Array<string>): Promise<void> {
++  async ls(config: Config, reporter: Reporter, commander: Object, flags: Object, args: Array<string>): Promise<void> {
+     reporter.warn(`\`yarn cache ls\` is deprecated. Please use \`yarn cache list\`.`);
+-    await list(config, reporter, flags, args);
++    await list(config, reporter, commander, flags, args);
+   },
+   list,
+   clean,
+--- a/src/cli/commands/check.js
++++ b/src/cli/commands/check.js
+@@ -193,7 +193,7 @@
+   }
+ }
+ 
+-export async function run(config: Config, reporter: Reporter, flags: Object, args: Array<string>): Promise<void> {
++export async function run(config: Config, reporter: Reporter, commander: Object, flags: Object, args: Array<string>): Promise<void> {
+   if (flags.verifyTree) {
+     await verifyTreeCheck(config, reporter, flags, args);
+     return;
+--- a/src/cli/commands/config.js
++++ b/src/cli/commands/config.js
+@@ -44,12 +44,8 @@
+   return args[0] !== 'get';
+ }
+ 
+-export function setFlags(commander: Object) {
+-  commander.description('Manages the yarn configuration files.');
+-}
+-
+-export const {run, examples} = buildSubCommands('config', {
+-  async set(config: Config, reporter: Reporter, flags: Object, args: Array<string>): Promise<boolean> {
++const {run, setFlags: _setFlags, examples} = buildSubCommands('config', {
++  async set(config: Config, reporter: Reporter, commander: Object, flags: Object, args: Array<string>): Promise<boolean> {
+     if (args.length === 0 || args.length > 2) {
+       return false;
+     }
+@@ -60,7 +56,7 @@
+     return true;
+   },
+ 
+-  get(config: Config, reporter: Reporter, flags: Object, args: Array<string>): boolean {
++  get(config: Config, reporter: Reporter, commander: Object, flags: Object, args: Array<string>): boolean {
+     if (args.length !== 1) {
+       return false;
+     }
+@@ -69,7 +65,7 @@
+     return true;
+   },
+ 
+-  delete: async function(config: Config, reporter: Reporter, flags: Object, args: Array<string>): Promise<boolean> {
++  delete: async function(config: Config, reporter: Reporter, commander: Object, flags: Object, args: Array<string>): Promise<boolean> {
+     if (args.length !== 1) {
+       return false;
+     }
+@@ -81,8 +77,8 @@
+     return true;
+   },
+ 
+-  list(config: Config, reporter: Reporter, flags: Object, args: Array<string>): boolean {
+-    if (args.length) {
++  list(config: Config, reporter: Reporter, commander: Object, flags: Object, args: Array<string>): boolean {
++    if (args.length > 0) {
+       return false;
+     }
+ 
+@@ -95,8 +91,8 @@
+     return true;
+   },
+ 
+-  current(config: Config, reporter: Reporter, flags: Object, args: Array<string>): boolean {
+-    if (args.length) {
++  current(config: Config, reporter: Reporter, commander: Object, flags: Object, args: Array<string>): boolean {
++    if (args.length > 0) {
+       return false;
+     }
+ 
+@@ -105,3 +101,10 @@
+     return true;
+   },
+ });
++
++export {run, examples};
++
++export function setFlags(commander: Object) {
++  _setFlags(commander);
++  commander.description('Manages the yarn configuration files.');
++}
+--- a/src/cli/commands/create.js
++++ b/src/cli/commands/create.js
+@@ -51,7 +51,7 @@
+   return coercedPkgNameObj;
+ }
+ 
+-export async function run(config: Config, reporter: Reporter, flags: Object, args: Array<string>): Promise<void> {
++export async function run(config: Config, reporter: Reporter, commander: Object, flags: Object, args: Array<string>): Promise<void> {
+   const [builderName, ...rest] = args;
+ 
+   if (!builderName) {
+@@ -64,7 +64,7 @@
+   if (await fs.exists(linkLoc)) {
+     reporter.info(reporter.lang('linkUsing', packageName));
+   } else {
+-    await runGlobal(config, reporter, {}, ['add', packageName]);
++    await runGlobal(config, reporter, commander, {}, ['add', packageName]);
+   }
+ 
+   const binFolder = await getBinFolder(config, {});
+--- a/src/cli/commands/exec.js
++++ b/src/cli/commands/exec.js
+@@ -12,7 +12,7 @@
+   return true;
+ }
+ 
+-export async function run(config: Config, reporter: Reporter, flags: Object, args: Array<string>): Promise<void> {
++export async function run(config: Config, reporter: Reporter, commander: Object, flags: Object, args: Array<string>): Promise<void> {
+   const env = await makeEnv(`exec`, config.cwd, config);
+ 
+   if (args.length < 1) {
+--- a/src/cli/commands/generate-lock-entry.js
++++ b/src/cli/commands/generate-lock-entry.js
+@@ -9,7 +9,7 @@
+   return false;
+ }
+ 
+-export async function run(config: Config, reporter: Reporter, flags: Object, args: Array<string>): Promise<void> {
++export async function run(config: Config, reporter: Reporter, commander: Object, flags: Object, args: Array<string>): Promise<void> {
+   let manifest;
+   if (flags.useManifest) {
+     manifest = await config.readJson(flags.useManifest);
+--- a/src/cli/commands/global.js
++++ b/src/cli/commands/global.js
+@@ -208,7 +208,7 @@
+ }
+ 
+ const {run, setFlags: _setFlags} = buildSubCommands('global', {
+-  async add(config: Config, reporter: Reporter, flags: Object, args: Array<string>): Promise<void> {
++  async add(config: Config, reporter: Reporter, commander: Object, flags: Object, args: Array<string>): Promise<void> {
+     await updateCwd(config);
+ 
+     const updateBins = await initUpdateBins(config, reporter, flags);
+@@ -225,55 +225,55 @@
+     await updateBins();
+   },
+ 
+-  async bin(config: Config, reporter: Reporter, flags: Object, args: Array<string>): Promise<void> {
++  async bin(config: Config, reporter: Reporter, commander: Object, flags: Object, args: Array<string>): Promise<void> {
+     reporter.log(await getBinFolder(config, flags), {force: true});
+   },
+ 
+-  dir(config: Config, reporter: Reporter, flags: Object, args: Array<string>): Promise<void> {
++  dir(config: Config, reporter: Reporter, commander: Object, flags: Object, args: Array<string>): Promise<void> {
+     reporter.log(config.globalFolder, {force: true});
+     return Promise.resolve();
+   },
+ 
+-  async ls(config: Config, reporter: Reporter, flags: Object, args: Array<string>): Promise<void> {
++  async ls(config: Config, reporter: Reporter, commander: Object, flags: Object, args: Array<string>): Promise<void> {
+     reporter.warn(`\`yarn global ls\` is deprecated. Please use \`yarn global list\`.`);
+     await list(config, reporter, flags, args);
+   },
+ 
+-  async list(config: Config, reporter: Reporter, flags: Object, args: Array<string>): Promise<void> {
++  async list(config: Config, reporter: Reporter, commander: Object, flags: Object, args: Array<string>): Promise<void> {
+     await list(config, reporter, flags, args);
+   },
+ 
+-  async remove(config: Config, reporter: Reporter, flags: Object, args: Array<string>): Promise<void> {
++  async remove(config: Config, reporter: Reporter, commander: Object, flags: Object, args: Array<string>): Promise<void> {
+     await updateCwd(config);
+ 
+     const updateBins = await initUpdateBins(config, reporter, flags);
+ 
+     // remove module
+-    await runRemove(config, reporter, flags, args);
++    await runRemove(config, reporter, commander, flags, args);
+ 
+     // remove binaries
+     await updateBins();
+   },
+ 
+-  async upgrade(config: Config, reporter: Reporter, flags: Object, args: Array<string>): Promise<void> {
++  async upgrade(config: Config, reporter: Reporter, commander: Object, flags: Object, args: Array<string>): Promise<void> {
+     await updateCwd(config);
+ 
+     const updateBins = await initUpdateBins(config, reporter, flags);
+ 
+     // upgrade module
+-    await runUpgrade(config, reporter, flags, args);
++    await runUpgrade(config, reporter, commander, flags, args);
+ 
+     // update binaries
+     await updateBins();
+   },
+ 
+-  async upgradeInteractive(config: Config, reporter: Reporter, flags: Object, args: Array<string>): Promise<void> {
++  async upgradeInteractive(config: Config, reporter: Reporter, commander: Object, flags: Object, args: Array<string>): Promise<void> {
+     await updateCwd(config);
+ 
+     const updateBins = await initUpdateBins(config, reporter, flags);
+ 
+     // upgrade module
+-    await runUpgradeInteractive(config, reporter, flags, args);
++    await runUpgradeInteractive(config, reporter, commander, flags, args);
+ 
+     // update binaries
+     await updateBins();
+--- a/src/cli/commands/help.js
++++ b/src/cli/commands/help.js
+@@ -16,8 +16,8 @@
+   commander.description('Displays help information.');
+ }
+ 
+-export function run(config: Config, reporter: Reporter, commander: Object, args: Array<string>): Promise<void> {
+-  if (args.length) {
++export function run(config: Config, reporter: Reporter, commander: Object, flags: Object, args: Array<string>): Promise<void> {
++  if (args.length > 0) {
+     const commandName = args.shift();
+     if (Object.prototype.hasOwnProperty.call(commands, commandName)) {
+       const command = commands[commandName];
+@@ -25,34 +25,30 @@
+         command.setFlags(commander);
+         const examples: Array<string> = (command.examples || []).map(example => `    $ yarn ${example}`);
+         if (examples.length) {
+-          commander.on('--help', () => {
+-            reporter.log(reporter.lang('helpExamples', reporter.rawText(examples.join('\n'))));
+-          });
++          commander.addHelpText('after', '\n' + reporter.lang('helpExamples', reporter.rawText(examples.join('\n'))));
+         }
+         // eslint-disable-next-line yarn-internal/warn-language
+-        commander.on('--help', () => reporter.log('  ' + command.getDocsInfo + '\n'));
++        commander.addHelpText('afterAll', '\n' + command.getDocsInfo + '\n');
+         commander.help();
+         return Promise.resolve();
+       }
+     }
+   }
+ 
+-  commander.on('--help', () => {
+-    const commandsText = [];
+-    for (const name of Object.keys(commands).sort(sortAlpha)) {
+-      if (commands[name].useless || Object.keys(aliases).map(key => aliases[key]).indexOf(name) > -1) {
+-        continue;
+-      }
+-      if (aliases[name]) {
+-        commandsText.push(`    - ${hyphenate(name)} / ${aliases[name]}`);
+-      } else {
+-        commandsText.push(`    - ${hyphenate(name)}`);
+-      }
++  const commandsText = [];
++  for (const name of Object.keys(commands).sort(sortAlpha)) {
++    if (commands[name].useless || Object.keys(aliases).map(key => aliases[key]).indexOf(name) > -1) {
++      continue;
+     }
+-    reporter.log(reporter.lang('helpCommands', reporter.rawText(commandsText.join('\n'))));
+-    reporter.log(reporter.lang('helpCommandsMore', reporter.rawText(chalk.bold('yarn help COMMAND'))));
+-    reporter.log(reporter.lang('helpLearnMore', reporter.rawText(chalk.bold(constants.YARN_DOCS))));
+-  });
++    if (aliases[name]) {
++      commandsText.push(`    - ${hyphenate(name)} / ${aliases[name]}`);
++    } else {
++      commandsText.push(`    - ${hyphenate(name)}`);
++    }
++  }
++  commander.addHelpText('after', '\n' + reporter.lang('helpCommands', reporter.rawText(commandsText.join('\n'))));
++  commander.addHelpText('after', reporter.lang('helpCommandsMore', reporter.rawText(chalk.bold('yarn help COMMAND'))));
++  commander.addHelpText('after', reporter.lang('helpLearnMore', reporter.rawText(chalk.bold(constants.YARN_DOCS))));
+ 
+   commander.options.sort(sortOptionsByFlags);
+ 
+--- a/src/cli/commands/import.js
++++ b/src/cli/commands/import.js
+@@ -406,7 +406,7 @@
+   return true;
+ }
+ 
+-export async function run(config: Config, reporter: Reporter, flags: Object, args: Array<string>): Promise<void> {
++export async function run(config: Config, reporter: Reporter, commander: Object, flags: Object, args: Array<string>): Promise<void> {
+   const imp = new Import(flags, config, reporter, new Lockfile({cache: {}}));
+   await imp.init();
+ }
+--- a/src/cli/commands/info.js
++++ b/src/cli/commands/info.js
+@@ -44,7 +44,7 @@
+   return true;
+ }
+ 
+-export async function run(config: Config, reporter: Reporter, flags: Object, args: Array<string>): Promise<void> {
++export async function run(config: Config, reporter: Reporter, commander: Object, flags: Object, args: Array<string>): Promise<void> {
+   if (args.length > 2) {
+     reporter.error(reporter.lang('tooManyArguments', 2));
+     return;
+--- a/src/cli/commands/init.js
++++ b/src/cli/commands/init.js
+@@ -28,7 +28,7 @@
+ 
+ export const shouldRunInCurrentCwd = true;
+ 
+-export async function run(config: Config, reporter: Reporter, flags: Object, args: Array<string>): Promise<void> {
++export async function run(config: Config, reporter: Reporter, commander: Object, flags: Object, args: Array<string>): Promise<void> {
+   const installVersion = flags[`2`] ? `berry` : flags.install;
+   const forwardedArgs = process.argv.slice(process.argv.indexOf('init', 2) + 1);
+ 
+--- a/src/cli/commands/install.js
++++ b/src/cli/commands/install.js
+@@ -1155,7 +1155,7 @@
+   });
+ }
+ 
+-export async function run(config: Config, reporter: Reporter, flags: Object, args: Array<string>): Promise<void> {
++export async function run(config: Config, reporter: Reporter, commander: Object, flags: Object, args: Array<string>): Promise<void> {
+   let lockfile;
+   let error = 'installCommandRenamed';
+   if (flags.lockfile === false) {
+@@ -1164,7 +1164,7 @@
+     lockfile = await Lockfile.fromDirectory(config.lockfileFolder, reporter);
+   }
+ 
+-  if (args.length) {
++  if (args.length > 0) {
+     const exampleArgs = args.slice();
+ 
+     if (flags.saveDev) {
+--- a/src/cli/commands/licenses.js
++++ b/src/cli/commands/licenses.js
+@@ -118,20 +118,18 @@
+     reporter.tree('licenses', trees, {force: true});
+   }
+ }
+-export function setFlags(commander: Object) {
+-  commander.description('Lists licenses for installed packages.');
+-}
+-export const {run, examples} = buildSubCommands('licenses', {
+-  async ls(config: Config, reporter: Reporter, flags: Object, args: Array<string>): Promise<void> {
++
++const {run, setFlags: _setFlags, examples} = buildSubCommands('licenses', {
++  async ls(config: Config, reporter: Reporter, commander: Object, flags: Object, args: Array<string>): Promise<void> {
+     reporter.warn(`\`yarn licenses ls\` is deprecated. Please use \`yarn licenses list\`.`);
+     await list(config, reporter, flags, args);
+   },
+ 
+-  async list(config: Config, reporter: Reporter, flags: Object, args: Array<string>): Promise<void> {
++  async list(config: Config, reporter: Reporter, commander: Object, flags: Object, args: Array<string>): Promise<void> {
+     await list(config, reporter, flags, args);
+   },
+ 
+-  async generateDisclaimer(config: Config, reporter: Reporter, flags: Object, args: Array<string>): Promise<void> {
++  async generateDisclaimer(config: Config, reporter: Reporter, commander: Object, flags: Object, args: Array<string>): Promise<void> {
+     /* eslint-disable no-console */
+ 
+     // `reporter.log` dumps a bunch of ANSI escapes to clear the current line and
+@@ -208,3 +206,10 @@
+     }
+   },
+ });
++
++export {run, examples};
++
++export function setFlags(commander: Object) {
++  _setFlags(commander);
++  commander.description('Lists licenses for installed packages.');
++}
+--- a/src/cli/commands/link.js
++++ b/src/cli/commands/link.js
+@@ -30,8 +30,8 @@
+   commander.description('Symlink a package folder during development.');
+ }
+ 
+-export async function run(config: Config, reporter: Reporter, flags: Object, args: Array<string>): Promise<void> {
+-  if (args.length) {
++export async function run(config: Config, reporter: Reporter, commander: Object, flags: Object, args: Array<string>): Promise<void> {
++  if (args.length > 0) {
+     for (const name of args) {
+       const src = path.join(config.linkFolder, name);
+ 
+--- a/src/cli/commands/list.js
++++ b/src/cli/commands/list.js
+@@ -191,7 +191,7 @@
+   }
+ }
+ 
+-export async function run(config: Config, reporter: Reporter, flags: Object, args: Array<string>): Promise<void> {
++export async function run(config: Config, reporter: Reporter, commander: Object, flags: Object, args: Array<string>): Promise<void> {
+   const lockfile = await Lockfile.fromDirectory(config.lockfileFolder, reporter);
+   const install = new Install(flags, config, reporter, lockfile);
+ 
+@@ -216,10 +216,10 @@
+ 
+   let {trees}: {trees: Trees} = await buildTree(install.resolver, install.linker, activePatterns, opts);
+ 
+-  if (args.length) {
++  if (args.length > 0) {
+     reporter.warn(reporter.lang('deprecatedListArgs'));
+   }
+-  if (args.length || flags.pattern) {
++  if ((args.length > 0) || flags.pattern) {
+     trees = trees.filter(tree => filterTree(tree, args, flags.pattern));
+   }
+ 
+--- a/src/cli/commands/login.js
++++ b/src/cli/commands/login.js
+@@ -136,6 +136,6 @@
+   commander.description('Stores registry username and email.');
+ }
+ 
+-export async function run(config: Config, reporter: Reporter, flags: Object, args: Array<string>): Promise<void> {
++export async function run(config: Config, reporter: Reporter, commander: Object, flags: Object, args: Array<string>): Promise<void> {
+   await getCredentials(config, reporter);
+ }
+--- a/src/cli/commands/logout.js
++++ b/src/cli/commands/logout.js
+@@ -11,7 +11,7 @@
+   return true;
+ }
+ 
+-export async function run(config: Config, reporter: Reporter, flags: Object, args: Array<string>): Promise<void> {
++export async function run(config: Config, reporter: Reporter, commander: Object, flags: Object, args: Array<string>): Promise<void> {
+   await config.registries.yarn.saveHomeConfig({
+     username: undefined,
+     email: undefined,
+--- a/src/cli/commands/node.js
++++ b/src/cli/commands/node.js
+@@ -18,7 +18,7 @@
+   return true;
+ }
+ 
+-export async function run(config: Config, reporter: Reporter, flags: Object, args: Array<string>): Promise<void> {
++export async function run(config: Config, reporter: Reporter, commander: Object, flags: Object, args: Array<string>): Promise<void> {
+   const pnpPath = `${config.lockfileFolder}/${PNP_FILENAME}`;
+ 
+   let nodeOptions = process.env.NODE_OPTIONS || '';
+--- a/src/cli/commands/outdated.js
++++ b/src/cli/commands/outdated.js
+@@ -19,12 +19,12 @@
+   return true;
+ }
+ 
+-export async function run(config: Config, reporter: Reporter, flags: Object, args: Array<string>): Promise<number> {
++export async function run(config: Config, reporter: Reporter, commander: Object, flags: Object, args: Array<string>): Promise<number> {
+   const lockfile = await Lockfile.fromDirectory(config.lockfileFolder);
+   const install = new Install({...flags, includeWorkspaceDeps: true}, config, reporter, lockfile);
+   let deps = await PackageRequest.getOutdatedPackages(lockfile, install, config, reporter);
+ 
+-  if (args.length) {
++  if (args.length > 0) {
+     const requested = new Set(args);
+ 
+     deps = deps.filter(({name}) => requested.has(name));
+--- a/src/cli/commands/owner.js
++++ b/src/cli/commands/owner.js
+@@ -138,14 +138,10 @@
+   );
+ }
+ 
+-export function setFlags(commander: Object) {
+-  commander.description('Manages package owners.');
+-}
+-
+-export const {run, hasWrapper, examples} = buildSubCommands(
++const {run, setFlags: _setFlags, hasWrapper, examples} = buildSubCommands(
+   'owner',
+   {
+-    add(config: Config, reporter: Reporter, flags: Object, args: Array<string>): Promise<boolean> {
++    add(config: Config, reporter: Reporter, commander: Object, flags: Object, args: Array<string>): Promise<boolean> {
+       return mutate(
+         args,
+         config,
+@@ -170,23 +166,30 @@
+       );
+     },
+ 
+-    rm(config: Config, reporter: Reporter, flags: Object, args: Array<string>): Promise<boolean> {
++    rm(config: Config, reporter: Reporter, commander: Object, flags: Object, args: Array<string>): Promise<boolean> {
+       reporter.warn(`\`yarn owner rm\` is deprecated. Please use \`yarn owner remove\`.`);
+       return remove(config, reporter, flags, args);
+     },
+ 
+-    remove(config: Config, reporter: Reporter, flags: Object, args: Array<string>): Promise<boolean> {
++    remove(config: Config, reporter: Reporter, commander: Object, flags: Object, args: Array<string>): Promise<boolean> {
+       return remove(config, reporter, flags, args);
+     },
+ 
+-    ls(config: Config, reporter: Reporter, flags: Object, args: Array<string>): Promise<boolean> {
++    ls(config: Config, reporter: Reporter, commander: Object, flags: Object, args: Array<string>): Promise<boolean> {
+       reporter.warn(`\`yarn owner ls\` is deprecated. Please use \`yarn owner list\`.`);
+       return list(config, reporter, flags, args);
+     },
+ 
+-    list(config: Config, reporter: Reporter, flags: Object, args: Array<string>): Promise<boolean> {
++    list(config: Config, reporter: Reporter, commander: Object, flags: Object, args: Array<string>): Promise<boolean> {
+       return list(config, reporter, flags, args);
+     },
+   },
+   ['add <user> [[<@scope>/]<pkg>]', 'remove <user> [[<@scope>/]<pkg>]', 'list [<@scope>/]<pkg>'],
+ );
++
++export {run, hasWrapper, examples};
++
++export function setFlags(commander: Object) {
++  _setFlags(commander);
++  commander.description('Manages package owners.');
++}
+--- a/src/cli/commands/pack.js
++++ b/src/cli/commands/pack.js
+@@ -177,6 +177,7 @@
+ export async function run(
+   config: Config,
+   reporter: Reporter,
++  commander: Object,
+   flags: {filename?: string},
+   args?: Array<string>,
+ ): Promise<void> {
+--- a/src/cli/commands/policies.js
++++ b/src/cli/commands/policies.js
+@@ -108,7 +108,7 @@
+ }
+ 
+ const {run, setFlags, examples} = buildSubCommands('policies', {
+-  async setVersion(config: Config, reporter: Reporter, flags: Object, args: Array<string>): Promise<void> {
++  async setVersion(config: Config, reporter: Reporter, commander: Object, flags: Object, args: Array<string>): Promise<void> {
+     const initialRange = args[0] || 'latest';
+     let range = initialRange;
+ 
+--- a/src/cli/commands/publish.js
++++ b/src/cli/commands/publish.js
+@@ -123,7 +123,7 @@
+   await config.executeLifecycleScript('postpublish');
+ }
+ 
+-export async function run(config: Config, reporter: Reporter, flags: Object, args: Array<string>): Promise<void> {
++export async function run(config: Config, reporter: Reporter, commander: Object, flags: Object, args: Array<string>): Promise<void> {
+   // validate arguments
+   const dir = args[0] ? path.resolve(config.cwd, args[0]) : config.cwd;
+   if (args.length > 1) {
+--- a/src/cli/commands/remove.js
++++ b/src/cli/commands/remove.js
+@@ -25,10 +25,10 @@
+   return true;
+ }
+ 
+-export async function run(config: Config, reporter: Reporter, flags: Object, args: Array<string>): Promise<void> {
++export async function run(config: Config, reporter: Reporter, commander: Object, flags: Object, args: Array<string>): Promise<void> {
+   const isWorkspaceRoot = config.workspaceRootFolder && config.cwd === config.workspaceRootFolder;
+ 
+-  if (!args.length) {
++  if (args.length < 1) {
+     throw new MessageError(reporter.lang('tooFewArguments', 1));
+   }
+ 
+--- a/src/cli/commands/run.js
++++ b/src/cli/commands/run.js
+@@ -71,7 +71,7 @@
+   return true;
+ }
+ 
+-export async function run(config: Config, reporter: Reporter, flags: Object, args: Array<string>): Promise<void> {
++export async function run(config: Config, reporter: Reporter, commander: Object, flags: Object, args: Array<string>): Promise<void> {
+   const pkg = await config.readManifest(config.cwd);
+ 
+   const binCommands = new Set();
+--- a/src/cli/commands/tag.js
++++ b/src/cli/commands/tag.js
+@@ -78,14 +78,10 @@
+   }
+ }
+ 
+-export function setFlags(commander: Object) {
+-  commander.description('Add, remove, or list tags on a package.');
+-}
+-
+-export const {run, hasWrapper, examples} = buildSubCommands(
++const {run, setFlags: _setFlags, hasWrapper, examples} = buildSubCommands(
+   'tag',
+   {
+-    async add(config: Config, reporter: Reporter, flags: Object, args: Array<string>): Promise<boolean> {
++    async add(config: Config, reporter: Reporter, commander: Object, flags: Object, args: Array<string>): Promise<boolean> {
+       if (args.length !== 2) {
+         return false;
+       }
+@@ -128,23 +124,30 @@
+       }
+     },
+ 
+-    async rm(config: Config, reporter: Reporter, flags: Object, args: Array<string>): Promise<void> {
++    async rm(config: Config, reporter: Reporter, commander: Object, flags: Object, args: Array<string>): Promise<void> {
+       reporter.warn(`\`yarn tag rm\` is deprecated. Please use \`yarn tag remove\`.`);
+       await remove(config, reporter, flags, args);
+     },
+ 
+-    async remove(config: Config, reporter: Reporter, flags: Object, args: Array<string>): Promise<void> {
++    async remove(config: Config, reporter: Reporter, commander: Object, flags: Object, args: Array<string>): Promise<void> {
+       await remove(config, reporter, flags, args);
+     },
+ 
+-    async ls(config: Config, reporter: Reporter, flags: Object, args: Array<string>): Promise<void> {
++    async ls(config: Config, reporter: Reporter, commander: Object, flags: Object, args: Array<string>): Promise<void> {
+       reporter.warn(`\`yarn tag ls\` is deprecated. Please use \`yarn tag list\`.`);
+       await list(config, reporter, flags, args);
+     },
+ 
+-    async list(config: Config, reporter: Reporter, flags: Object, args: Array<string>): Promise<void> {
++    async list(config: Config, reporter: Reporter, commander: Object, flags: Object, args: Array<string>): Promise<void> {
+       await list(config, reporter, flags, args);
+     },
+   },
+   ['add <pkg>@<version> [<tag>]', 'remove <pkg> <tag>', 'list [<pkg>]'],
+ );
++
++export {run, hasWrapper, examples};
++
++export function setFlags(commander: Object) {
++  _setFlags(commander);
++  commander.description('Add, remove, or list tags on a package.');
++}
+--- a/src/cli/commands/team.js
++++ b/src/cli/commands/team.js
+@@ -64,7 +64,7 @@
+       warnDeprecation(reporter, deprecationInfo);
+     }
+ 
+-    if (!args.length) {
++    if (args.length < 1) {
+       return false;
+     }
+ 
+@@ -97,6 +97,7 @@
+       parts: TeamParts,
+       config: Config,
+       reporter: Reporter,
++      commander: Object,
+       flags: Object,
+       args: Array<string>,
+     ): CLIFunctionReturn {
+@@ -117,6 +118,7 @@
+       parts: TeamParts,
+       config: Config,
+       reporter: Reporter,
++      commander: Object,
+       flags: Object,
+       args: Array<string>,
+     ): CLIFunctionReturn {
+@@ -164,11 +166,7 @@
+   return true;
+ }
+ 
+-export function setFlags(commander: Object) {
+-  commander.description('Maintain team memberships');
+-}
+-
+-export const {run, hasWrapper, examples} = buildSubCommands(
++const {run, setFlags: _setFlags, hasWrapper, examples} = buildSubCommands(
+   'team',
+   {
+     create: wrapRequiredTeam(async function(
+@@ -274,3 +272,10 @@
+     'list <scope>|<scope:team>',
+   ],
+ );
++
++export {run, hasWrapper, examples};
++
++export function setFlags(commander: Object) {
++  _setFlags(commander);
++  commander.description('Maintain team memberships');
++}
+--- a/src/cli/commands/unlink.js
++++ b/src/cli/commands/unlink.js
+@@ -17,8 +17,8 @@
+   return true;
+ }
+ 
+-export async function run(config: Config, reporter: Reporter, flags: Object, args: Array<string>): Promise<void> {
+-  if (args.length) {
++export async function run(config: Config, reporter: Reporter, commander: Object, flags: Object, args: Array<string>): Promise<void> {
++  if (args.length > 0) {
+     for (const name of args) {
+       const linkLoc = path.join(config.linkFolder, name);
+       if (await fs.exists(linkLoc)) {
+--- a/src/cli/commands/unplug.js
++++ b/src/cli/commands/unplug.js
+@@ -22,14 +22,14 @@
+   commander.option('--clear-all', 'Delete all unplugged packages');
+ }
+ 
+-export async function run(config: Config, reporter: Reporter, flags: Object, args: Array<string>): Promise<void> {
++export async function run(config: Config, reporter: Reporter, commander: Object, flags: Object, args: Array<string>): Promise<void> {
+   if (!config.plugnplayEnabled) {
+     throw new MessageError(reporter.lang('unplugDisabled'));
+   }
+-  if (!args.length && flags.clear) {
++  if ((args.length < 1) && flags.clear) {
+     throw new MessageError(reporter.lang('tooFewArguments', 1));
+   }
+-  if (args.length && flags.clearAll) {
++  if ((args.length > 0) && flags.clearAll) {
+     throw new MessageError(reporter.lang('noArguments'));
+   }
+ 
+--- a/src/cli/commands/upgrade-interactive.js
++++ b/src/cli/commands/upgrade-interactive.js
+@@ -35,7 +35,7 @@
+   return true;
+ }
+ 
+-export async function run(config: Config, reporter: Reporter, flags: Object, args: Array<string>): Promise<void> {
++export async function run(config: Config, reporter: Reporter, commander: Object, flags: Object, args: Array<string>): Promise<void> {
+   const outdatedFieldName = flags.latest ? 'latest' : 'wanted';
+   const lockfile = await Lockfile.fromDirectory(config.lockfileFolder);
+ 
+--- a/src/cli/commands/upgrade.js
++++ b/src/cli/commands/upgrade.js
+@@ -167,7 +167,7 @@
+ 
+ export const requireLockfile = true;
+ 
+-export async function run(config: Config, reporter: Reporter, flags: Object, args: Array<string>): Promise<void> {
++export async function run(config: Config, reporter: Reporter, commander: Object, flags: Object, args: Array<string>): Promise<void> {
+   let addArgs = [];
+   const upgradeAll = args.length === 0 && typeof flags.scope === 'undefined' && typeof flags.pattern === 'undefined';
+   const addFlags = Object.assign({}, flags, {
+--- a/src/cli/commands/version.js
++++ b/src/cli/commands/version.js
+@@ -55,7 +55,7 @@
+   }
+   invariant(pkgLoc, 'expected package location');
+ 
+-  if (args.length && !newVersion) {
++  if ((args.length > 0) && !newVersion) {
+     throw new MessageError(reporter.lang('invalidVersionArgument', NEW_VERSION_FLAG));
+   }
+ 
+@@ -211,7 +211,7 @@
+   };
+ }
+ 
+-export async function run(config: Config, reporter: Reporter, flags: Object, args: Array<string>): Promise<void> {
++export async function run(config: Config, reporter: Reporter, commander: Object, flags: Object, args: Array<string>): Promise<void> {
+   const commit = await setVersion(config, reporter, flags, args, true);
+   await commit();
+ }
+--- a/src/cli/commands/versions.js
++++ b/src/cli/commands/versions.js
+@@ -13,7 +13,7 @@
+   return true;
+ }
+ 
+-export async function run(config: Config, reporter: Reporter, flags: Object, args: Array<string>): Promise<void> {
++export async function run(config: Config, reporter: Reporter, commander: Object, flags: Object, args: Array<string>): Promise<void> {
+   const versions: {[name: string]: string} = {yarn: yarnVersion};
+ 
+   const pkg = await config.maybeReadManifest(config.cwd);
+--- a/src/cli/commands/why.js
++++ b/src/cli/commands/why.js
+@@ -125,8 +125,8 @@
+   return str;
+ }
+ 
+-export async function run(config: Config, reporter: Reporter, flags: Object, args: Array<string>): Promise<void> {
+-  if (!args.length) {
++export async function run(config: Config, reporter: Reporter, commander: Object, flags: Object, args: Array<string>): Promise<void> {
++  if (args.length < 1) {
+     throw new MessageError(reporter.lang('missingWhyDependency'));
+   }
+   if (args.length > 1) {
+--- a/src/cli/commands/workspace.js
++++ b/src/cli/commands/workspace.js
+@@ -14,7 +14,7 @@
+   return true;
+ }
+ 
+-export async function run(config: Config, reporter: Reporter, flags: Object, args: Array<string>): Promise<void> {
++export async function run(config: Config, reporter: Reporter, commander: Object, flags: Object, args: Array<string>): Promise<void> {
+   const {workspaceRootFolder} = config;
+ 
+   if (!workspaceRootFolder) {
+--- a/src/cli/commands/workspaces.js
++++ b/src/cli/commands/workspaces.js
+@@ -90,10 +90,10 @@
+ }
+ 
+ const {run, setFlags, examples} = buildSubCommands('workspaces', {
+-  async info(config: Config, reporter: Reporter, flags: Object, args: Array<string>): Promise<void> {
++  async info(config: Config, reporter: Reporter, commander: Object, flags: Object, args: Array<string>): Promise<void> {
+     await info(config, reporter, flags, args);
+   },
+-  async run(config: Config, reporter: Reporter, flags: Object, args: Array<string>): Promise<void> {
++  async run(config: Config, reporter: Reporter, commander: Object, flags: Object, args: Array<string>): Promise<void> {
+     await runScript(config, reporter, flags, args);
+   },
+ });
 --- a/src/cli/index.js
 +++ b/src/cli/index.js
-@@ -245,14 +245,16 @@
+@@ -4,7 +4,7 @@
+ import net from 'net';
+ import path from 'path';
+ 
+-import commander from 'commander';
++const { Command } = require('commander');
+ import fs from 'fs';
+ import invariant from 'invariant';
+ import lockfile from 'proper-lockfile';
+@@ -26,6 +26,8 @@
+ import {boolify, boolifyWithDefault} from '../util/conversion.js';
+ import {ProcessTermError} from '../errors';
+ 
++const commander = new Command();
++
+ process.stdout.prependListener('error', err => {
+   // swallow err only if downstream consumer process closed pipe early
+   if (err.code === 'EPIPE' || err.code === 'ERR_STREAM_DESTROYED') {
+@@ -67,7 +69,15 @@
+   loudRejection();
+   handleSignals();
+ 
++  // if -v/--version is the first argument, then always exit after returning the version
++  if ((args[0] === '-v') || (args[0] === '--version')) {
++    console.log(version.trim());
++    process.exitCode = 0;
++    return;
++  }
++
+   // set global options
++  commander.name('yarnpkg');
+   commander.version(version, '-v, --version');
+   commander.usage('[command] [flags]');
+   commander.option('--no-default-rc', 'prevent Yarn from automatically detecting yarnrc and npmrc files');
+@@ -136,18 +146,11 @@
+   commander.option('--focus', 'Focus on a single workspace by installing remote copies of its sibling workspaces.');
+   commander.option('--otp <otpcode>', 'one-time password for two factor authentication');
+ 
+-  // if -v is the first command, then always exit after returning the version
+-  if (args[0] === '-v') {
+-    console.log(version.trim());
+-    process.exitCode = 0;
+-    return;
+-  }
+-
+   // get command name
+   const firstNonFlagIndex = args.findIndex((arg, idx, arr) => {
+     const isOption = arg.startsWith('-');
+     const prev = idx > 0 && arr[idx - 1];
+-    const prevOption = prev && prev.startsWith('-') && commander.optionFor(prev);
++    const prevOption = prev && prev.startsWith('-') && commander._findOption(prev);
+     const boundToPrevOption = prevOption && (prevOption.optional || prevOption.required);
+ 
+     return !isOption && !boundToPrevOption;
+@@ -245,14 +248,16 @@
    console.assert(commander.args[0] === 'this-arg-will-get-stripped-later');
    commander.args.shift();
  
@@ -28,7 +1054,7 @@
    });
  
    const exit = exitCode => {
-@@ -266,15 +268,15 @@
+@@ -266,19 +271,19 @@
    const outputWrapperEnabled = boolifyWithDefault(process.env.YARN_WRAP_OUTPUT, true);
    const shouldWrapOutput =
      outputWrapperEnabled &&
@@ -47,7 +1073,12 @@
      reporter.warn(reporter.lang('unsupportedNodeVersion', process.versions.node, constants.SUPPORTED_NODE_VERSIONS));
    }
  
-@@ -286,12 +288,12 @@
+-  if (command.noArguments && commander.args.length) {
++  if (command.noArguments && (commander.args.length > 0)) {
+     reporter.error(reporter.lang('noArguments'));
+     reporter.info(command.getDocsInfo);
+     exit(1);
+@@ -286,12 +291,12 @@
    }
  
    //
@@ -62,16 +1093,16 @@
      reporter.warn(reporter.lang('networkWarning'));
    }
  
-@@ -303,7 +305,7 @@
+@@ -303,7 +308,7 @@
        reporter.warn(reporter.lang('dashDashDeprecation'));
      }
  
 -    return command.run(config, reporter, commander, commander.args).then(exitCode => {
-+    return command.run(config, reporter, commanderOpts, commander.args).then(exitCode => {
++    return command.run(config, reporter, commander, commanderOpts, commander.args).then(exitCode => {
        if (shouldWrapOutput) {
          reporter.footer(false);
        }
-@@ -519,15 +521,15 @@
+@@ -519,15 +524,15 @@
      return errorReportLoc;
    }
  
@@ -90,7 +1121,7 @@
      resolvedFolderOptions[folderOptionKey] = resolvedFolderOption;
    });
  
-@@ -536,28 +538,28 @@
+@@ -536,28 +541,28 @@
        cwd,
        commandName,
        ...resolvedFolderOptions,
@@ -141,7 +1172,7 @@
      })
      .then(() => {
        // lockfile check must happen after config.init sets lockfileFolder
-@@ -575,7 +577,7 @@
+@@ -575,7 +580,7 @@
        // verbose logs outputs process.uptime() with this line we can sync uptime to absolute time on the computer
        reporter.verbose(`current time: ${new Date().toISOString()}`);
  
@@ -150,3 +1181,40 @@
        if (mutex && typeof mutex === 'string') {
          const separatorLoc = mutex.indexOf(':');
          let mutexType;
+--- a/src/rc.js
++++ b/src/rc.js
+@@ -3,11 +3,13 @@
+ import {existsSync, readFileSync} from 'fs';
+ import {dirname, resolve} from 'path';
+ 
+-import commander from 'commander';
++const { Command } = require('commander');
+ 
+ import {parse} from './lockfile';
+ import * as rcUtil from './util/rc.js';
+ 
++const commander = new Command();
++
+ // Keys that will get resolved relative to the path of the rc file they belong to
+ const PATH_KEYS = new Set([
+   'yarn-path',
+@@ -92,7 +94,7 @@
+     argsForCommands.set(commandName, args);
+ 
+     // turn config value into appropriate cli flag
+-    const option = commander.optionFor(`--${arg}`);
++    const option = commander._findOption(`--${arg}`);
+ 
+     // If commander doesn't recognize the option or it takes a value after it
+     if (!option || option.optional || option.required) {
+--- a/src/util/execute-lifecycle-script.js
++++ b/src/util/execute-lifecycle-script.js
+@@ -317,7 +317,7 @@
+   reporter.info(reporter.lang('packageRequiresNodeGyp'));
+ 
+   try {
+-    await globalRun(config, reporter, {}, ['add', 'node-gyp']);
++    await globalRun(config, reporter, {}, {}, ['add', 'node-gyp']);
+   } catch (e) {
+     throw new MessageError(reporter.lang('nodeGypAutoInstallFailed', e.message));
+   }
-------------- next part --------------
A non-text attachment was scrubbed...
Name: OpenPGP_0x8F53E0193B294B75.asc
Type: application/pgp-keys
Size: 4044 bytes
Desc: OpenPGP public key
URL: <http://alioth-lists.debian.net/pipermail/pkg-javascript-devel/attachments/20231213/d4f9a9d6/attachment.key>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: OpenPGP_signature
Type: application/pgp-signature
Size: 840 bytes
Desc: OpenPGP digital signature
URL: <http://alioth-lists.debian.net/pipermail/pkg-javascript-devel/attachments/20231213/d4f9a9d6/attachment.sig>


More information about the Pkg-javascript-devel mailing list