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