From 1b1fc5e92bed218eb26cd05c090128f694aab7c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Nison?= Date: Fri, 28 Jul 2023 11:22:34 +0200 Subject: [PATCH] Refactors context passing --- .yarn/versions/bfe31a8a.yml | 23 ++++++++ packages/yarnpkg-cli/sources/cli.ts | 3 +- packages/yarnpkg-cli/sources/index.ts | 16 +++--- packages/yarnpkg-cli/sources/lib.ts | 78 ++++++++++++++------------- 4 files changed, 76 insertions(+), 44 deletions(-) create mode 100644 .yarn/versions/bfe31a8a.yml diff --git a/.yarn/versions/bfe31a8a.yml b/.yarn/versions/bfe31a8a.yml new file mode 100644 index 000000000000..69dbdb38f160 --- /dev/null +++ b/.yarn/versions/bfe31a8a.yml @@ -0,0 +1,23 @@ +releases: + "@yarnpkg/cli": major + +declined: + - "@yarnpkg/plugin-compat" + - "@yarnpkg/plugin-constraints" + - "@yarnpkg/plugin-dlx" + - "@yarnpkg/plugin-essentials" + - "@yarnpkg/plugin-init" + - "@yarnpkg/plugin-interactive-tools" + - "@yarnpkg/plugin-nm" + - "@yarnpkg/plugin-npm-cli" + - "@yarnpkg/plugin-pack" + - "@yarnpkg/plugin-patch" + - "@yarnpkg/plugin-pnp" + - "@yarnpkg/plugin-pnpm" + - "@yarnpkg/plugin-stage" + - "@yarnpkg/plugin-typescript" + - "@yarnpkg/plugin-version" + - "@yarnpkg/plugin-workspace-tools" + - "@yarnpkg/builder" + - "@yarnpkg/core" + - "@yarnpkg/doctor" diff --git a/packages/yarnpkg-cli/sources/cli.ts b/packages/yarnpkg-cli/sources/cli.ts index b57b83a664da..cff0d93912c8 100644 --- a/packages/yarnpkg-cli/sources/cli.ts +++ b/packages/yarnpkg-cli/sources/cli.ts @@ -1,10 +1,11 @@ import '@yarnpkg/cli/polyfills'; -import {npath} from '@yarnpkg/fslib'; +import {npath, ppath} from '@yarnpkg/fslib'; import {runExit} from './lib'; import {getPluginConfiguration} from './tools/getPluginConfiguration'; runExit(process.argv.slice(2), { + cwd: ppath.cwd(), selfPath: npath.toPortablePath(npath.resolve(process.argv[1])), pluginConfiguration: getPluginConfiguration(), }); diff --git a/packages/yarnpkg-cli/sources/index.ts b/packages/yarnpkg-cli/sources/index.ts index 3be1c02c620a..293fe244287f 100644 --- a/packages/yarnpkg-cli/sources/index.ts +++ b/packages/yarnpkg-cli/sources/index.ts @@ -1,7 +1,9 @@ -export {BaseCommand} from './tools/BaseCommand'; -export {WorkspaceRequiredError} from './tools/WorkspaceRequiredError'; -export {getDynamicLibs} from './tools/getDynamicLibs'; -export {getPluginConfiguration} from './tools/getPluginConfiguration'; -export {openWorkspace} from './tools/openWorkspace'; -export {getCli, runExit} from './lib'; -export {pluginCommands} from './pluginCommands'; +export {type CommandContext} from '@yarnpkg/core'; + +export {BaseCommand} from './tools/BaseCommand'; +export {WorkspaceRequiredError} from './tools/WorkspaceRequiredError'; +export {getDynamicLibs} from './tools/getDynamicLibs'; +export {getPluginConfiguration} from './tools/getPluginConfiguration'; +export {openWorkspace} from './tools/openWorkspace'; +export {type YarnCli, getCli, runExit} from './lib'; +export {pluginCommands} from './pluginCommands'; diff --git a/packages/yarnpkg-cli/sources/lib.ts b/packages/yarnpkg-cli/sources/lib.ts index ab528e3c9790..c6f03be00a59 100644 --- a/packages/yarnpkg-cli/sources/lib.ts +++ b/packages/yarnpkg-cli/sources/lib.ts @@ -5,16 +5,31 @@ import {isCI} import {Cli, UsageError} from 'clipanion'; import {pluginCommands} from './pluginCommands'; +import {getPluginConfiguration} from './tools/getPluginConfiguration'; -function getBaseCli() { - return new Cli({ +export type YarnCli = ReturnType; + +function getBaseCli({cwd, pluginConfiguration}: {cwd: PortablePath, pluginConfiguration: PluginConfiguration}) { + const cli = new Cli({ binaryLabel: `Yarn Package Manager`, binaryName: `yarn`, binaryVersion: YarnVersion ?? ``, }); + + return Object.assign(cli, { + defaultContext: { + ...Cli.defaultContext, + cwd, + plugins: pluginConfiguration, + quiet: false, + stdin: process.stdin, + stdout: process.stdout, + stderr: process.stderr, + }, + }); } -function validateNodejsVersion(cli: Cli) { +function validateNodejsVersion(cli: YarnCli) { // YARN_IGNORE_NODE is special because this code needs to execute as early as possible. // It's not a regular core setting because Configuration.find may use functions not available // on older Node versions. @@ -46,7 +61,7 @@ async function getCoreConfiguration({selfPath, pluginConfiguration}: {selfPath: }); } -function runYarnPath(cli: Cli, argv: Array, {yarnPath}: {yarnPath: PortablePath}) { +function runYarnPath(cli: YarnCli, argv: Array, {yarnPath}: {yarnPath: PortablePath}) { if (!xfs.existsSync(yarnPath)) { (cli.error(new Error(`The "yarn-path" option has been set, but the specified location doesn't exist (${yarnPath}).`))); return 1; @@ -74,17 +89,23 @@ function runYarnPath(cli: Cli, argv: Array, {yarnPath}: return 0; } -function checkCwd(argv: Array): [PortablePath, Array] { - if (argv.length >= 2 && argv[0] === `--cwd`) - return [xfs.realpathSync(npath.toPortablePath(argv[1])), argv.slice(2)]; +function checkCwd(cli: YarnCli, argv: Array) { + let cwd: PortablePath | null = null; - if (argv.length >= 1 && argv[0].startsWith(`--cwd=`)) - return [xfs.realpathSync(npath.toPortablePath(argv[0].slice(6))), argv.slice(1)]; + let postCwdArgv = argv; + if (argv.length >= 2 && argv[0] === `--cwd`) { + cwd = xfs.realpathSync(npath.toPortablePath(argv[1])); + postCwdArgv = argv.slice(2); + } else if (argv.length >= 1 && argv[0].startsWith(`--cwd=`)) { + cwd = xfs.realpathSync(npath.toPortablePath(argv[0].slice(6))); + postCwdArgv = argv.slice(1); + } - return [ppath.cwd(), argv]; + cli.defaultContext.cwd = cwd ?? ppath.cwd(); + return postCwdArgv; } -function initTelemetry(cli: Cli, {configuration}: {configuration: Configuration}) { +function initTelemetry(cli: YarnCli, {configuration}: {configuration: Configuration}) { const isTelemetryEnabled = configuration.get(`enableTelemetry`); if (!isTelemetryEnabled || isCI || !process.stdout.isTTY) return; @@ -100,7 +121,7 @@ function initTelemetry(cli: Cli, {configuration}: {configuration } } -function initCommands(cli: Cli, {configuration}: {configuration: Configuration}) { +function initCommands(cli: YarnCli, {configuration}: {configuration: Configuration}) { for (const plugin of configuration.plugins.values()) { for (const command of plugin.commands || []) { cli.register(command); @@ -108,23 +129,7 @@ function initCommands(cli: Cli, {configuration}: {configuration: } } -function processArgv(cli: Cli, argv: Array, {cwd, pluginConfiguration}: {cwd: PortablePath, pluginConfiguration: PluginConfiguration}) { - const context = { - cwd, - plugins: pluginConfiguration, - quiet: false, - stdin: process.stdin, - stdout: process.stdout, - stderr: process.stderr, - }; - - return { - context, - command: cli.process(argv, context), - }; -} - -async function run(cli: Cli, argv: Array, {selfPath, pluginConfiguration}: {selfPath: PortablePath | null, pluginConfiguration: PluginConfiguration}) { +async function run(cli: YarnCli, argv: Array, {selfPath, pluginConfiguration}: {selfPath: PortablePath | null, pluginConfiguration: PluginConfiguration}) { if (!validateNodejsVersion(cli)) return 1; @@ -141,20 +146,21 @@ async function run(cli: Cli, argv: Array, {selfPath, plu delete process.env.YARN_IGNORE_PATH; - const [cwd, postCwdArgv] = checkCwd(argv); + const postCwdArgv = checkCwd(cli, argv); initTelemetry(cli, {configuration}); initCommands(cli, {configuration}); - const {command, context} = processArgv(cli, postCwdArgv, {cwd, pluginConfiguration}); + const command = cli.process(postCwdArgv, cli.defaultContext); + if (!command.help) Configuration.telemetry?.reportCommandName(command.path.join(` `)); - return await cli.run(command, context); + return await cli.run(command, cli.defaultContext); } -export async function getCli({pluginConfiguration}: {pluginConfiguration: PluginConfiguration}) { - const cli = getBaseCli(); +export async function getCli({cwd = ppath.cwd(), pluginConfiguration = getPluginConfiguration()}: {cwd?: PortablePath, pluginConfiguration?: PluginConfiguration} = {}) { + const cli = getBaseCli({cwd, pluginConfiguration}); const configuration = await getCoreConfiguration({ pluginConfiguration, @@ -166,8 +172,8 @@ export async function getCli({pluginConfiguration}: {pluginConfiguration: Plugin return cli; } -export async function runExit(argv: Array, {selfPath, pluginConfiguration}: {selfPath: PortablePath | null, pluginConfiguration: PluginConfiguration}) { - const cli = getBaseCli(); +export async function runExit(argv: Array, {cwd = ppath.cwd(), selfPath, pluginConfiguration}: {cwd: PortablePath, selfPath: PortablePath | null, pluginConfiguration: PluginConfiguration}) { + const cli = getBaseCli({cwd, pluginConfiguration}); try { process.exitCode = await run(cli, argv, {selfPath, pluginConfiguration});