[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#1058615: marked as done (bookworm-pu: package node-yarnpkg/1.22.19+~cs24.27.18-2+deb12u1)



Your message dated Sat, 10 Feb 2024 13:11:20 +0000
with message-id <E1rYn8a-002yZE-1T@coccia.debian.org>
and subject line Released with 12.5
has caused the Debian Bug report #1058615,
regarding bookworm-pu: package node-yarnpkg/1.22.19+~cs24.27.18-2+deb12u1
to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact owner@bugs.debian.org
immediately.)


-- 
1058615: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1058615
Debian Bug Tracking System
Contact owner@bugs.debian.org with problems
--- Begin Message ---
Package: release.debian.org
Severity: normal
Tags: bookworm
User: release.debian.org@packages.debian.org
Usertags: pu
X-Debbugs-Cc: node-yarnpkg@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.)
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@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@debian.org>
+Author: Yadd <yadd@debian.org>, Konstantin Demin <rockdrilla@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));
+   }

Attachment: OpenPGP_0x8F53E0193B294B75.asc
Description: OpenPGP public key

Attachment: OpenPGP_signature
Description: OpenPGP digital signature


--- End Message ---
--- Begin Message ---
Version: 12.5

The upload requested in this bug has been released as part of 12.5.

--- End Message ---

Reply to: