From 344ea56acca0f1c143cac6ee25770012a181bd42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Mon, 4 Apr 2022 15:19:21 +0200 Subject: [PATCH] Bump commander to version 9.1.0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- .changeset/silver-readers-deliver.md | 8 +++ packages/cli/package.json | 2 +- packages/cli/src/commands/app/build.ts | 8 +-- packages/cli/src/commands/app/serve.ts | 8 +-- packages/cli/src/commands/backend/build.ts | 8 +-- packages/cli/src/commands/backend/bundle.ts | 6 +- packages/cli/src/commands/backend/dev.ts | 10 +-- packages/cli/src/commands/build/command.ts | 16 ++--- packages/cli/src/commands/buildWorkspace.ts | 3 +- packages/cli/src/commands/config/docs.ts | 6 +- packages/cli/src/commands/config/print.ts | 24 +++---- packages/cli/src/commands/config/schema.ts | 8 +-- packages/cli/src/commands/config/validate.ts | 14 ++-- .../commands/create-plugin/createPlugin.ts | 18 ++--- packages/cli/src/commands/create/create.ts | 16 ++--- packages/cli/src/commands/index.ts | 24 +++---- packages/cli/src/commands/install/install.ts | 4 +- packages/cli/src/commands/lint.ts | 16 +++-- packages/cli/src/commands/oldBuild.ts | 10 +-- packages/cli/src/commands/plugin/build.ts | 8 +-- packages/cli/src/commands/plugin/diff.ts | 8 +-- packages/cli/src/commands/plugin/serve.ts | 8 +-- .../plugin/{testCommand.ts => test.ts} | 8 +-- packages/cli/src/commands/repo/build.ts | 24 +++---- packages/cli/src/commands/repo/lint.ts | 14 ++-- .../src/commands/repo/list-deprecations.ts | 6 +- packages/cli/src/commands/start/command.ts | 14 ++-- .../src/commands/{testCommand.ts => test.ts} | 8 +-- packages/cli/src/commands/versions/bump.ts | 16 ++--- packages/cli/src/commands/versions/lint.ts | 4 +- packages/cli/src/index.ts | 2 +- .../cli/src/lib/role/packageRoles.test.ts | 3 +- packages/cli/src/lib/role/packageRoles.ts | 10 +-- packages/codemods/package.json | 2 +- packages/codemods/src/action.ts | 10 +-- packages/codemods/src/index.ts | 6 +- packages/create-app/package.json | 2 +- packages/create-app/src/createApp.ts | 14 ++-- packages/create-app/src/index.ts | 2 +- packages/e2e-test/package.json | 2 +- packages/e2e-test/src/commands/index.ts | 4 +- packages/e2e-test/src/index.ts | 2 +- packages/techdocs-cli/package.json | 2 +- .../src/commands/generate/generate.ts | 28 ++++---- packages/techdocs-cli/src/commands/index.ts | 4 +- .../src/commands/migrate/migrate.ts | 16 ++--- .../src/commands/publish/publish.ts | 12 ++-- .../techdocs-cli/src/commands/serve/mkdocs.ts | 22 +++---- .../techdocs-cli/src/commands/serve/serve.ts | 28 ++++---- packages/techdocs-cli/src/index.ts | 2 +- .../src/lib/PublisherConfig.test.ts | 18 ++--- .../techdocs-cli/src/lib/PublisherConfig.ts | 66 +++++++++++-------- yarn.lock | 10 +-- 53 files changed, 309 insertions(+), 285 deletions(-) create mode 100644 .changeset/silver-readers-deliver.md rename packages/cli/src/commands/plugin/{testCommand.ts => test.ts} (85%) rename packages/cli/src/commands/{testCommand.ts => test.ts} (92%) diff --git a/.changeset/silver-readers-deliver.md b/.changeset/silver-readers-deliver.md new file mode 100644 index 0000000000..ce175f97be --- /dev/null +++ b/.changeset/silver-readers-deliver.md @@ -0,0 +1,8 @@ +--- +'@backstage/cli': patch +'@backstage/codemods': patch +'@backstage/create-app': patch +'@techdocs/cli': patch +--- + +Bump `commander` to version 9.1.0 diff --git a/packages/cli/package.json b/packages/cli/package.json index e362caf40e..ec43f7b895 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -62,7 +62,7 @@ "buffer": "^6.0.3", "chalk": "^4.0.0", "chokidar": "^3.3.1", - "commander": "^6.1.0", + "commander": "^9.1.0", "css-loader": "^6.5.1", "diff": "^5.0.0", "esbuild": "^0.14.10", diff --git a/packages/cli/src/commands/app/build.ts b/packages/cli/src/commands/app/build.ts index 67b71632c7..f90052bc83 100644 --- a/packages/cli/src/commands/app/build.ts +++ b/packages/cli/src/commands/app/build.ts @@ -15,20 +15,20 @@ */ import fs from 'fs-extra'; -import { Command } from 'commander'; +import { OptionValues } from 'commander'; import { buildBundle } from '../../lib/bundler'; import { getEnvironmentParallelism } from '../../lib/parallel'; import { loadCliConfig } from '../../lib/config'; import { paths } from '../../lib/paths'; -export default async (cmd: Command) => { +export default async (opts: OptionValues) => { const { name } = await fs.readJson(paths.resolveTarget('package.json')); await buildBundle({ entry: 'src/index', parallelism: getEnvironmentParallelism(), - statsJsonEnabled: cmd.stats, + statsJsonEnabled: opts.stats, ...(await loadCliConfig({ - args: cmd.config, + args: opts.config, fromPackage: name, })), }); diff --git a/packages/cli/src/commands/app/serve.ts b/packages/cli/src/commands/app/serve.ts index 716d47bd4c..e41c2367da 100644 --- a/packages/cli/src/commands/app/serve.ts +++ b/packages/cli/src/commands/app/serve.ts @@ -17,14 +17,14 @@ import fs from 'fs-extra'; import chalk from 'chalk'; import uniq from 'lodash/uniq'; -import { Command } from 'commander'; +import { OptionValues } from 'commander'; import { serveBundle } from '../../lib/bundler'; import { loadCliConfig } from '../../lib/config'; import { paths } from '../../lib/paths'; import { Lockfile } from '../../lib/versioning'; import { forbiddenDuplicatesFilter, includedFilter } from '../versions/lint'; -export default async (cmd: Command) => { +export default async (opts: OptionValues) => { const lockFilePath = paths.resolveTargetRoot('yarn.lock'); if (fs.existsSync(lockFilePath)) { try { @@ -80,9 +80,9 @@ export default async (cmd: Command) => { const { name } = await fs.readJson(paths.resolveTarget('package.json')); const waitForExit = await serveBundle({ entry: 'src/index', - checksEnabled: cmd.check, + checksEnabled: opts.check, ...(await loadCliConfig({ - args: cmd.config, + args: opts.config, fromPackage: name, withFilteredKeys: true, })), diff --git a/packages/cli/src/commands/backend/build.ts b/packages/cli/src/commands/backend/build.ts index 5d4e17e392..c85eecfed3 100644 --- a/packages/cli/src/commands/backend/build.ts +++ b/packages/cli/src/commands/backend/build.ts @@ -14,13 +14,13 @@ * limitations under the License. */ -import { Command } from 'commander'; +import { OptionValues } from 'commander'; import { buildPackage, Output } from '../../lib/builder'; -export default async (cmd: Command) => { +export default async (opts: OptionValues) => { await buildPackage({ outputs: new Set([Output.cjs, Output.types]), - minify: cmd.minify, - useApiExtractor: cmd.experimentalTypeBuild, + minify: opts.minify, + useApiExtractor: opts.experimentalTypeBuild, }); }; diff --git a/packages/cli/src/commands/backend/bundle.ts b/packages/cli/src/commands/backend/bundle.ts index ec5fa0a131..78d4d72d92 100644 --- a/packages/cli/src/commands/backend/bundle.ts +++ b/packages/cli/src/commands/backend/bundle.ts @@ -18,7 +18,7 @@ import os from 'os'; import fs from 'fs-extra'; import { resolve as resolvePath } from 'path'; import tar, { CreateOptions } from 'tar'; -import { Command } from 'commander'; +import { OptionValues } from 'commander'; import { createDistWorkspace } from '../../lib/packager'; import { paths } from '../../lib/paths'; import { getEnvironmentParallelism } from '../../lib/parallel'; @@ -27,7 +27,7 @@ import { buildPackage, Output } from '../../lib/builder'; const BUNDLE_FILE = 'bundle.tar.gz'; const SKELETON_FILE = 'skeleton.tar.gz'; -export default async (cmd: Command) => { +export default async (opts: OptionValues) => { const targetDir = paths.resolveTarget('dist'); const pkg = await fs.readJson(paths.resolveTarget('package.json')); @@ -38,7 +38,7 @@ export default async (cmd: Command) => { try { await createDistWorkspace([pkg.name], { targetDir: tmpDir, - buildDependencies: Boolean(cmd.buildDependencies), + buildDependencies: Boolean(opts.buildDependencies), buildExcludes: [pkg.name], parallelism: getEnvironmentParallelism(), skeleton: SKELETON_FILE, diff --git a/packages/cli/src/commands/backend/dev.ts b/packages/cli/src/commands/backend/dev.ts index b14a1f3e20..2ee43958a2 100644 --- a/packages/cli/src/commands/backend/dev.ts +++ b/packages/cli/src/commands/backend/dev.ts @@ -15,11 +15,11 @@ */ import fs from 'fs-extra'; -import { Command } from 'commander'; +import { OptionValues } from 'commander'; import { paths } from '../../lib/paths'; import { serveBackend } from '../../lib/bundler/backend'; -export default async (cmd: Command) => { +export default async (opts: OptionValues) => { // Cleaning dist/ before we start the dev process helps work around an issue // where we end up with the entrypoint executing multiple times, causing // a port bind conflict among other things. @@ -27,9 +27,9 @@ export default async (cmd: Command) => { const waitForExit = await serveBackend({ entry: 'src/index', - checksEnabled: cmd.check, - inspectEnabled: cmd.inspect, - inspectBrkEnabled: cmd.inspectBrk, + checksEnabled: opts.check, + inspectEnabled: opts.inspect, + inspectBrkEnabled: opts.inspectBrk, }); await waitForExit(); diff --git a/packages/cli/src/commands/build/command.ts b/packages/cli/src/commands/build/command.ts index 5c8065dbb4..fcaf58e1ee 100644 --- a/packages/cli/src/commands/build/command.ts +++ b/packages/cli/src/commands/build/command.ts @@ -14,27 +14,27 @@ * limitations under the License. */ -import { Command } from 'commander'; +import { OptionValues } from 'commander'; import { buildPackage, Output } from '../../lib/builder'; import { findRoleFromCommand, getRoleInfo } from '../../lib/role'; import { paths } from '../../lib/paths'; import { buildFrontend } from './buildFrontend'; import { buildBackend } from './buildBackend'; -export async function command(cmd: Command): Promise { - const role = await findRoleFromCommand(cmd); +export async function command(opts: OptionValues): Promise { + const role = await findRoleFromCommand(opts); if (role === 'frontend') { return buildFrontend({ targetDir: paths.targetDir, - configPaths: cmd.config as string[], - writeStats: Boolean(cmd.stats), + configPaths: opts.config as string[], + writeStats: Boolean(opts.stats), }); } if (role === 'backend') { return buildBackend({ targetDir: paths.targetDir, - skipBuildDependencies: Boolean(cmd.skipBuildDependencies), + skipBuildDependencies: Boolean(opts.skipBuildDependencies), }); } @@ -54,7 +54,7 @@ export async function command(cmd: Command): Promise { return buildPackage({ outputs, - minify: Boolean(cmd.minify), - useApiExtractor: Boolean(cmd.experimentalTypeBuild), + minify: Boolean(opts.minify), + useApiExtractor: Boolean(opts.experimentalTypeBuild), }); } diff --git a/packages/cli/src/commands/buildWorkspace.ts b/packages/cli/src/commands/buildWorkspace.ts index 7a7aa28ad6..97bf2f1239 100644 --- a/packages/cli/src/commands/buildWorkspace.ts +++ b/packages/cli/src/commands/buildWorkspace.ts @@ -15,10 +15,9 @@ */ import fs from 'fs-extra'; -import { Command } from 'commander'; import { createDistWorkspace } from '../lib/packager'; -export default async (dir: string, _cmd: Command, packages: string[]) => { +export default async (dir: string, packages: string[]) => { if (!(await fs.pathExists(dir))) { throw new Error(`Target workspace directory doesn't exist, '${dir}'`); } diff --git a/packages/cli/src/commands/config/docs.ts b/packages/cli/src/commands/config/docs.ts index 7a807f7c78..98e683e87c 100644 --- a/packages/cli/src/commands/config/docs.ts +++ b/packages/cli/src/commands/config/docs.ts @@ -16,17 +16,17 @@ import { JsonObject } from '@backstage/types'; import { mergeConfigSchemas } from '@backstage/config-loader'; -import { Command } from 'commander'; +import { OptionValues } from 'commander'; import { JSONSchema7 as JSONSchema } from 'json-schema'; import openBrowser from 'react-dev-utils/openBrowser'; import { loadCliConfig } from '../../lib/config'; const DOCS_URL = 'https://config.backstage.io'; -export default async (cmd: Command) => { +export default async (opts: OptionValues) => { const { schema: appSchemas } = await loadCliConfig({ args: [], - fromPackage: cmd.package, + fromPackage: opts.package, mockEnv: true, }); diff --git a/packages/cli/src/commands/config/print.ts b/packages/cli/src/commands/config/print.ts index b640ee4f37..9ef725ebf8 100644 --- a/packages/cli/src/commands/config/print.ts +++ b/packages/cli/src/commands/config/print.ts @@ -14,36 +14,36 @@ * limitations under the License. */ -import { Command } from 'commander'; +import { OptionValues } from 'commander'; import { stringify as stringifyYaml } from 'yaml'; import { AppConfig, ConfigReader } from '@backstage/config'; import { loadCliConfig } from '../../lib/config'; import { ConfigSchema, ConfigVisibility } from '@backstage/config-loader'; -export default async (cmd: Command) => { +export default async (opts: OptionValues) => { const { schema, appConfigs } = await loadCliConfig({ - args: cmd.config, - fromPackage: cmd.package, - mockEnv: cmd.lax, - fullVisibility: !cmd.frontend, + args: opts.config, + fromPackage: opts.package, + mockEnv: opts.lax, + fullVisibility: !opts.frontend, }); - const visibility = getVisibilityOption(cmd); + const visibility = getVisibilityOption(opts); const data = serializeConfigData(appConfigs, schema, visibility); - if (cmd.format === 'json') { + if (opts.format === 'json') { process.stdout.write(`${JSON.stringify(data, null, 2)}\n`); } else { process.stdout.write(`${stringifyYaml(data)}\n`); } }; -function getVisibilityOption(cmd: Command): ConfigVisibility { - if (cmd.frontend && cmd.withSecrets) { +function getVisibilityOption(opts: OptionValues): ConfigVisibility { + if (opts.frontend && opts.withSecrets) { throw new Error('Not allowed to combine frontend and secret config'); } - if (cmd.frontend) { + if (opts.frontend) { return 'frontend'; - } else if (cmd.withSecrets) { + } else if (opts.withSecrets) { return 'secret'; } return 'backend'; diff --git a/packages/cli/src/commands/config/schema.ts b/packages/cli/src/commands/config/schema.ts index be228e1e7c..f9e6573be6 100644 --- a/packages/cli/src/commands/config/schema.ts +++ b/packages/cli/src/commands/config/schema.ts @@ -14,17 +14,17 @@ * limitations under the License. */ -import { Command } from 'commander'; +import { OptionValues } from 'commander'; import { JSONSchema7 as JSONSchema } from 'json-schema'; import { stringify as stringifyYaml } from 'yaml'; import { loadCliConfig } from '../../lib/config'; import { JsonObject } from '@backstage/types'; import { mergeConfigSchemas } from '@backstage/config-loader'; -export default async (cmd: Command) => { +export default async (opts: OptionValues) => { const { schema } = await loadCliConfig({ args: [], - fromPackage: cmd.package, + fromPackage: opts.package, mockEnv: true, }); @@ -38,7 +38,7 @@ export default async (cmd: Command) => { merged.description = 'This is the schema describing the structure of the app-config.yaml configuration file.'; - if (cmd.format === 'json') { + if (opts.format === 'json') { process.stdout.write(`${JSON.stringify(merged, null, 2)}\n`); } else { process.stdout.write(`${stringifyYaml(merged)}\n`); diff --git a/packages/cli/src/commands/config/validate.ts b/packages/cli/src/commands/config/validate.ts index 8d528b8300..c3d05291e0 100644 --- a/packages/cli/src/commands/config/validate.ts +++ b/packages/cli/src/commands/config/validate.ts @@ -14,15 +14,15 @@ * limitations under the License. */ -import { Command } from 'commander'; +import { OptionValues } from 'commander'; import { loadCliConfig } from '../../lib/config'; -export default async (cmd: Command) => { +export default async (opts: OptionValues) => { await loadCliConfig({ - args: cmd.config, - fromPackage: cmd.package, - mockEnv: cmd.lax, - fullVisibility: !cmd.frontend, - withDeprecatedKeys: cmd.deprecated, + args: opts.config, + fromPackage: opts.package, + mockEnv: opts.lax, + fullVisibility: !opts.frontend, + withDeprecatedKeys: opts.deprecated, }); }; diff --git a/packages/cli/src/commands/create-plugin/createPlugin.ts b/packages/cli/src/commands/create-plugin/createPlugin.ts index c80129662c..a12060bbd2 100644 --- a/packages/cli/src/commands/create-plugin/createPlugin.ts +++ b/packages/cli/src/commands/create-plugin/createPlugin.ts @@ -23,7 +23,7 @@ import { resolve as resolvePath, join as joinPath } from 'path'; import camelCase from 'lodash/camelCase'; import upperFirst from 'lodash/upperFirst'; import os from 'os'; -import { Command } from 'commander'; +import { OptionValues } from 'commander'; import { assertError } from '@backstage/errors'; import { parseOwnerIds, @@ -195,7 +195,7 @@ export async function movePlugin( }); } -export default async (cmd: Command) => { +export default async (opts: OptionValues) => { const codeownersPath = await getCodeownersFilePath(paths.targetRoot); const questions: Question[] = [ @@ -242,21 +242,21 @@ export default async (cmd: Command) => { const answers: Answers = await inquirer.prompt(questions); const pluginId = - cmd.backend && !answers.id.endsWith('-backend') + opts.backend && !answers.id.endsWith('-backend') ? `${answers.id}-backend` : answers.id; - const name = cmd.scope - ? `@${cmd.scope.replace(/^@/, '')}/plugin-${pluginId}` + const name = opts.scope + ? `@${opts.scope.replace(/^@/, '')}/plugin-${pluginId}` : `plugin-${pluginId}`; const pluginVar = `${camelCase(answers.id)}Plugin`; const extensionName = `${upperFirst(camelCase(answers.id))}Page`; - const npmRegistry = cmd.npmRegistry && cmd.scope ? cmd.npmRegistry : ''; - const privatePackage = cmd.private === false ? false : true; + const npmRegistry = opts.npmRegistry && opts.scope ? opts.npmRegistry : ''; + const privatePackage = opts.private === false ? false : true; const isMonoRepo = await fs.pathExists(paths.resolveTargetRoot('lerna.json')); const appPackage = paths.resolveTargetRoot('packages/app'); const templateDir = paths.resolveOwn( - cmd.backend + opts.backend ? 'templates/default-backend-plugin' : 'templates/default-plugin', ); @@ -309,7 +309,7 @@ export default async (cmd: Command) => { Task.section('Building the plugin'); await buildPlugin(pluginDir); - if ((await fs.pathExists(appPackage)) && !cmd.backend) { + if ((await fs.pathExists(appPackage)) && !opts.backend) { Task.section('Adding plugin as dependency in app'); await addPluginDependencyToApp(paths.targetRoot, name, pluginVersion); diff --git a/packages/cli/src/commands/create/create.ts b/packages/cli/src/commands/create/create.ts index 64067e1b7e..c784307738 100644 --- a/packages/cli/src/commands/create/create.ts +++ b/packages/cli/src/commands/create/create.ts @@ -17,7 +17,7 @@ import os from 'os'; import fs from 'fs-extra'; import { join as joinPath } from 'path'; -import { Command } from 'commander'; +import { OptionValues } from 'commander'; import { FactoryRegistry } from '../../lib/create/FactoryRegistry'; import { paths } from '../../lib/paths'; import { assertError } from '@backstage/errors'; @@ -40,12 +40,10 @@ function parseOptions(optionStrings: string[]): Record { return options; } -export default async (cmd: Command) => { - const cmdOpts = cmd.opts(); +export default async (opts: OptionValues) => { + const factory = await FactoryRegistry.interactiveSelect(opts.select); - const factory = await FactoryRegistry.interactiveSelect(cmdOpts.select); - - const providedOptions = parseOptions(cmdOpts.option); + const providedOptions = parseOptions(opts.option); const options = await FactoryRegistry.populateOptions( factory, providedOptions, @@ -93,9 +91,9 @@ export default async (cmd: Command) => { await factory.create(options, { isMonoRepo, defaultVersion, - scope: cmdOpts.scope?.replace(/^@/, ''), - npmRegistry: cmdOpts.npmRegistry, - private: Boolean(cmdOpts.private), + scope: opts.scope?.replace(/^@/, ''), + npmRegistry: opts.npmRegistry, + private: Boolean(opts.private), createTemporaryDirectory, markAsModified() { modified = true; diff --git a/packages/cli/src/commands/index.ts b/packages/cli/src/commands/index.ts index 2f345e8663..1a7b2c4f08 100644 --- a/packages/cli/src/commands/index.ts +++ b/packages/cli/src/commands/index.ts @@ -15,17 +15,17 @@ */ import { assertError } from '@backstage/errors'; -import { CommanderStatic } from 'commander'; +import { Command } from 'commander'; import { exitWithError } from '../lib/errors'; const configOption = [ '--config ', 'Config files to load instead of app-config.yaml', - (opt: string, opts: string[]) => [...opts, opt], + (opt: string, opts: string[]) => (opts ? [...opts, opt] : [opt]), Array(), ] as const; -export function registerRepoCommand(program: CommanderStatic) { +export function registerRepoCommand(program: Command) { const command = program .command('repo [command]') .description('Command that run across an entire Backstage project'); @@ -69,7 +69,7 @@ export function registerRepoCommand(program: CommanderStatic) { ); } -export function registerScriptCommand(program: CommanderStatic) { +export function registerScriptCommand(program: Command) { const command = program .command('package [command]') .description('Lifecycle scripts for individual packages'); @@ -110,13 +110,13 @@ export function registerScriptCommand(program: CommanderStatic) { .option( '--config ', 'Config files to load instead of app-config.yaml. Applies to app packages only.', - (opt: string, opts: string[]) => [...opts, opt], + (opt: string, opts: string[]) => (opts ? [...opts, opt] : [opt]), Array(), ) .action(lazy(() => import('./build').then(m => m.command))); command - .command('lint') + .command('lint [directories...]') .option( '--format ', 'Lint report output format', @@ -131,7 +131,7 @@ export function registerScriptCommand(program: CommanderStatic) { .allowUnknownOption(true) // Allows the command to run, but we still need to parse raw args .helpOption(', --backstage-cli-help') // Let Jest handle help .description('Run tests, forwarding args to Jest, defaulting to watch mode') - .action(lazy(() => import('./testCommand').then(m => m.default))); + .action(lazy(() => import('./test').then(m => m.default))); command .command('fix', { hidden: true }) @@ -155,7 +155,7 @@ export function registerScriptCommand(program: CommanderStatic) { .action(lazy(() => import('./pack').then(m => m.post))); } -export function registerMigrateCommand(program: CommanderStatic) { +export function registerMigrateCommand(program: Command) { const command = program .command('migrate [command]') .description('Migration utilities'); @@ -182,7 +182,7 @@ export function registerMigrateCommand(program: CommanderStatic) { ); } -export function registerCommands(program: CommanderStatic) { +export function registerCommands(program: Command) { // TODO(Rugvip): Deprecate in favor of package variant program .command('app:build') @@ -302,7 +302,7 @@ export function registerCommands(program: CommanderStatic) { // TODO(Rugvip): Deprecate in favor of package variant program - .command('lint') + .command('lint [directories...]') .option( '--format ', 'Lint report output format', @@ -320,7 +320,7 @@ export function registerCommands(program: CommanderStatic) { .description( 'Run tests, forwarding args to Jest, defaulting to watch mode [DEPRECATED]', ) - .action(lazy(() => import('./testCommand').then(m => m.default))); + .action(lazy(() => import('./test').then(m => m.default))); program .command('config:docs') @@ -423,7 +423,7 @@ export function registerCommands(program: CommanderStatic) { .action(lazy(() => import('./clean/clean').then(m => m.default))); program - .command('build-workspace ...') + .command('build-workspace [packages...]') .description('Builds a temporary dist workspace from the provided packages') .action(lazy(() => import('./buildWorkspace').then(m => m.default))); diff --git a/packages/cli/src/commands/install/install.ts b/packages/cli/src/commands/install/install.ts index bd3a05ebc1..e395088b3e 100644 --- a/packages/cli/src/commands/install/install.ts +++ b/packages/cli/src/commands/install/install.ts @@ -22,7 +22,7 @@ import { import { fetchPackageInfo } from '../../lib/versioning'; import { NotFoundError } from '../../lib/errors'; import * as stepDefinitionMap from './steps'; -import { Command } from 'commander'; +import { OptionValues } from 'commander'; import fs from 'fs-extra'; const stepDefinitions = Object.values(stepDefinitionMap); @@ -154,7 +154,7 @@ async function loadPeerPluginDeps( } } -export default async (pluginId?: string, cmd?: Command) => { +export default async (pluginId?: string, cmd?: OptionValues) => { const from = pluginId || cmd?.from; // TODO(himanshu): If no plugin id is provided, it should list all plugins available. Maybe in some other command? if (!from) { diff --git a/packages/cli/src/commands/lint.ts b/packages/cli/src/commands/lint.ts index 823d24fbe8..87c353f56f 100644 --- a/packages/cli/src/commands/lint.ts +++ b/packages/cli/src/commands/lint.ts @@ -14,27 +14,29 @@ * limitations under the License. */ -import { Command } from 'commander'; +import { OptionValues } from 'commander'; import { paths } from '../lib/paths'; import { ESLint } from 'eslint'; -export default async (cmd: Command, cmdArgs: string[]) => { +export default async (directories: string[], opts: OptionValues) => { const eslint = new ESLint({ cwd: paths.targetDir, - fix: cmd.fix, + fix: opts.fix, extensions: ['js', 'jsx', 'ts', 'tsx', 'mjs', 'cjs'], }); - const results = await eslint.lintFiles(cmdArgs ?? ['.']); + const results = await eslint.lintFiles( + directories.length ? directories : ['.'], + ); - if (cmd.fix) { + if (opts.fix) { await ESLint.outputFixes(results); } - const formatter = await eslint.loadFormatter(cmd.format); + const formatter = await eslint.loadFormatter(opts.format); // This formatter uses the cwd to format file paths, so let's have that happen from the root instead - if (cmd.format === 'eslint-formatter-friendly') { + if (opts.format === 'eslint-formatter-friendly') { process.chdir(paths.targetRoot); } const resultText = formatter.format(results); diff --git a/packages/cli/src/commands/oldBuild.ts b/packages/cli/src/commands/oldBuild.ts index 86ab5c4300..c0899d4d02 100644 --- a/packages/cli/src/commands/oldBuild.ts +++ b/packages/cli/src/commands/oldBuild.ts @@ -15,12 +15,12 @@ */ import { buildPackage, Output } from '../lib/builder'; -import { Command } from 'commander'; +import { OptionValues } from 'commander'; -export default async (cmd: Command) => { +export default async (opts: OptionValues) => { let outputs = new Set(); - const { outputs: outputsStr } = cmd as { outputs?: string }; + const { outputs: outputsStr } = opts as { outputs?: string }; if (outputsStr) { for (const output of outputsStr.split(',') as (keyof typeof Output)[]) { if (output in Output) { @@ -35,7 +35,7 @@ export default async (cmd: Command) => { await buildPackage({ outputs, - minify: cmd.minify, - useApiExtractor: cmd.experimentalTypeBuild, + minify: opts.minify, + useApiExtractor: opts.experimentalTypeBuild, }); }; diff --git a/packages/cli/src/commands/plugin/build.ts b/packages/cli/src/commands/plugin/build.ts index 56f99f59b1..671aece818 100644 --- a/packages/cli/src/commands/plugin/build.ts +++ b/packages/cli/src/commands/plugin/build.ts @@ -14,13 +14,13 @@ * limitations under the License. */ -import { Command } from 'commander'; +import { OptionValues } from 'commander'; import { buildPackage, Output } from '../../lib/builder'; -export default async (cmd: Command) => { +export default async (opts: OptionValues) => { await buildPackage({ outputs: new Set([Output.esm, Output.types]), - minify: cmd.minify, - useApiExtractor: cmd.experimentalTypeBuild, + minify: opts.minify, + useApiExtractor: opts.experimentalTypeBuild, }); }; diff --git a/packages/cli/src/commands/plugin/diff.ts b/packages/cli/src/commands/plugin/diff.ts index 9a2a3b2e3e..07f2a94ea8 100644 --- a/packages/cli/src/commands/plugin/diff.ts +++ b/packages/cli/src/commands/plugin/diff.ts @@ -15,7 +15,7 @@ */ import fs from 'fs-extra'; -import { Command } from 'commander'; +import { OptionValues } from 'commander'; import { diffTemplateFiles, handlers, @@ -50,13 +50,13 @@ const fileHandlers = [ }, ]; -export default async (cmd: Command) => { +export default async (opts: OptionValues) => { let promptFunc = inquirerPromptFunc; let finalize = () => {}; - if (cmd.check) { + if (opts.check) { [promptFunc, finalize] = makeCheckPromptFunc(); - } else if (cmd.yes) { + } else if (opts.yes) { promptFunc = yesPromptFunc; } diff --git a/packages/cli/src/commands/plugin/serve.ts b/packages/cli/src/commands/plugin/serve.ts index a0200b7ce8..891db190e0 100644 --- a/packages/cli/src/commands/plugin/serve.ts +++ b/packages/cli/src/commands/plugin/serve.ts @@ -15,18 +15,18 @@ */ import fs from 'fs-extra'; -import { Command } from 'commander'; +import { OptionValues } from 'commander'; import { serveBundle } from '../../lib/bundler'; import { loadCliConfig } from '../../lib/config'; import { paths } from '../../lib/paths'; -export default async (cmd: Command) => { +export default async (opts: OptionValues) => { const { name } = await fs.readJson(paths.resolveTarget('package.json')); const waitForExit = await serveBundle({ entry: 'dev/index', - checksEnabled: cmd.check, + checksEnabled: opts.check, ...(await loadCliConfig({ - args: cmd.config, + args: opts.config, fromPackage: name, withFilteredKeys: true, })), diff --git a/packages/cli/src/commands/plugin/testCommand.ts b/packages/cli/src/commands/plugin/test.ts similarity index 85% rename from packages/cli/src/commands/plugin/testCommand.ts rename to packages/cli/src/commands/plugin/test.ts index e1ff0f36f9..ca076ae6fc 100644 --- a/packages/cli/src/commands/plugin/testCommand.ts +++ b/packages/cli/src/commands/plugin/test.ts @@ -14,16 +14,16 @@ * limitations under the License. */ -import { Command } from 'commander'; +import { OptionValues } from 'commander'; import { run } from '../../lib/run'; -export default async (cmd: Command) => { +export default async (opts: OptionValues) => { const args = ['test']; - if (cmd.watch) { + if (opts.watch) { args.push('--watch'); } - if (cmd.coverage) { + if (opts.coverage) { args.push('--coverage'); } diff --git a/packages/cli/src/commands/repo/build.ts b/packages/cli/src/commands/repo/build.ts index fe50bee84f..21b1580cb9 100644 --- a/packages/cli/src/commands/repo/build.ts +++ b/packages/cli/src/commands/repo/build.ts @@ -15,7 +15,7 @@ */ import chalk from 'chalk'; -import { Command } from 'commander'; +import { Command, OptionValues } from 'commander'; import { relative as relativePath } from 'path'; import { buildPackages, getOutputsForRole } from '../../lib/builder'; import { PackageGraph } from '../../lib/monorepo'; @@ -60,29 +60,31 @@ function createScriptOptionsParser(anyCmd: Command, commandPath: string[]) { // Can't clone or copy or even use commands as prototype, so we mutate // the necessary members instead, and then reset them once we're done - const currentOpts = cmd._optionValues; - const currentStore = cmd._storeOptionsAsProperties; + const currentOpts = (cmd as any)._optionValues; + const currentStore = (cmd as any)._storeOptionsAsProperties; const result: Record = {}; - cmd._storeOptionsAsProperties = false; - cmd._optionValues = result; + (cmd as any)._storeOptionsAsProperties = false; + (cmd as any)._optionValues = result; // Triggers the writing of options to the result object cmd.parseOptions(argsStr.split(' ')); - cmd._storeOptionsAsProperties = currentOpts; - cmd._optionValues = currentStore; + (cmd as any)._storeOptionsAsProperties = currentOpts; + (cmd as any)._optionValues = currentStore; return result; }; } -export async function command(cmd: Command): Promise { +export async function command(opts: OptionValues, cmd: Command): Promise { let packages = await PackageGraph.listTargetPackages(); - if (cmd.since) { + if (opts.since) { const graph = PackageGraph.fromPackages(packages); - const changedPackages = await graph.listChangedPackages({ ref: cmd.since }); + const changedPackages = await graph.listChangedPackages({ + ref: opts.since, + }); const withDevDependents = graph.collectPackageNames( changedPackages.map(pkg => pkg.name), pkg => pkg.localDevDependents.keys(), @@ -137,7 +139,7 @@ export async function command(cmd: Command): Promise { console.log('Building packages'); await buildPackages(options); - if (cmd.all) { + if (opts.all) { console.log('Building apps'); await runParallelWorkers({ items: apps, diff --git a/packages/cli/src/commands/repo/lint.ts b/packages/cli/src/commands/repo/lint.ts index b054dabe34..19e034aa7d 100644 --- a/packages/cli/src/commands/repo/lint.ts +++ b/packages/cli/src/commands/repo/lint.ts @@ -15,7 +15,7 @@ */ import chalk from 'chalk'; -import { Command } from 'commander'; +import { OptionValues } from 'commander'; import { relative as relativePath } from 'path'; import { PackageGraph, ExtendedPackageJSON } from '../../lib/monorepo'; import { runWorkerQueueThreads } from '../../lib/parallel'; @@ -29,12 +29,12 @@ function depCount(pkg: ExtendedPackageJSON) { return deps + devDeps; } -export async function command(cmd: Command): Promise { +export async function command(opts: OptionValues): Promise { let packages = await PackageGraph.listTargetPackages(); - if (cmd.since) { + if (opts.since) { const graph = PackageGraph.fromPackages(packages); - packages = await graph.listChangedPackages({ ref: cmd.since }); + packages = await graph.listChangedPackages({ ref: opts.since }); } // Packages are ordered from most to least number of dependencies, as a @@ -42,7 +42,7 @@ export async function command(cmd: Command): Promise { packages.sort((a, b) => depCount(b.packageJson) - depCount(a.packageJson)); // This formatter uses the cwd to format file paths, so let's have that happen from the root instead - if (cmd.format === 'eslint-formatter-friendly') { + if (opts.format === 'eslint-formatter-friendly') { process.chdir(paths.targetRoot); } @@ -57,8 +57,8 @@ export async function command(cmd: Command): Promise { relativeDir: relativePath(paths.targetRoot, pkg.dir), })), workerData: { - fix: Boolean(cmd.fix), - format: cmd.format as string | undefined, + fix: Boolean(opts.fix), + format: opts.format as string | undefined, }, workerFactory: async ({ fix, format }) => { const { ESLint } = require('eslint'); diff --git a/packages/cli/src/commands/repo/list-deprecations.ts b/packages/cli/src/commands/repo/list-deprecations.ts index b53118cc40..97fa384561 100644 --- a/packages/cli/src/commands/repo/list-deprecations.ts +++ b/packages/cli/src/commands/repo/list-deprecations.ts @@ -16,12 +16,12 @@ import chalk from 'chalk'; import { ESLint } from 'eslint'; -import { Command } from 'commander'; +import { OptionValues } from 'commander'; import { join as joinPath, relative as relativePath } from 'path'; import { paths } from '../../lib/paths'; import { PackageGraph } from '../../lib/monorepo'; -export async function command(cmd: Command) { +export async function command(opts: OptionValues) { const packages = await PackageGraph.listTargetPackages(); const eslint = new ESLint({ @@ -74,7 +74,7 @@ export async function command(cmd: Command) { stderr.cursorTo(0); } - if (cmd.json) { + if (opts.json) { console.log(JSON.stringify(deprecations, null, 2)); } else { for (const d of deprecations) { diff --git a/packages/cli/src/commands/start/command.ts b/packages/cli/src/commands/start/command.ts index 7a11028800..9306ab247c 100644 --- a/packages/cli/src/commands/start/command.ts +++ b/packages/cli/src/commands/start/command.ts @@ -14,19 +14,19 @@ * limitations under the License. */ -import { Command } from 'commander'; +import { OptionValues } from 'commander'; import { startBackend } from './startBackend'; import { startFrontend } from './startFrontend'; import { findRoleFromCommand } from '../../lib/role'; -export async function command(cmd: Command): Promise { - const role = await findRoleFromCommand(cmd); +export async function command(opts: OptionValues): Promise { + const role = await findRoleFromCommand(opts); const options = { - configPaths: cmd.config as string[], - checksEnabled: Boolean(cmd.check), - inspectEnabled: Boolean(cmd.inspect), - inspectBrkEnabled: Boolean(cmd.inspectBrk), + configPaths: opts.config as string[], + checksEnabled: Boolean(opts.check), + inspectEnabled: Boolean(opts.inspect), + inspectBrkEnabled: Boolean(opts.inspectBrk), }; switch (role) { diff --git a/packages/cli/src/commands/testCommand.ts b/packages/cli/src/commands/test.ts similarity index 92% rename from packages/cli/src/commands/testCommand.ts rename to packages/cli/src/commands/test.ts index 7165b20925..f1bfcc356b 100644 --- a/packages/cli/src/commands/testCommand.ts +++ b/packages/cli/src/commands/test.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { Command } from 'commander'; +import { Command, OptionValues } from 'commander'; import { paths } from '../lib/paths'; import { runCheck } from '../lib/run'; @@ -27,14 +27,14 @@ function includesAnyOf(hayStack: string[], ...needles: string[]) { return false; } -export default async (cmd: Command) => { +export default async (_opts: OptionValues, cmd: Command) => { // all args are forwarded to jest let parent = cmd; while (parent.parent) { parent = parent.parent; } - const rawArgs = parent.rawArgs as string[]; - const args = rawArgs.slice(rawArgs.indexOf('test') + 1); + const allArgs = parent.args as string[]; + const args = allArgs.slice(allArgs.indexOf('test') + 1); // Only include our config if caller isn't passing their own config if (!includesAnyOf(args, '-c', '--config')) { diff --git a/packages/cli/src/commands/versions/bump.ts b/packages/cli/src/commands/versions/bump.ts index b9d318bccc..f50f8ef195 100644 --- a/packages/cli/src/commands/versions/bump.ts +++ b/packages/cli/src/commands/versions/bump.ts @@ -19,7 +19,7 @@ import chalk from 'chalk'; import ora from 'ora'; import semver from 'semver'; import minimatch from 'minimatch'; -import { Command } from 'commander'; +import { OptionValues } from 'commander'; import { isError, NotFoundError } from '@backstage/errors'; import { resolve as resolvePath } from 'path'; import { run } from '../../lib/run'; @@ -55,10 +55,10 @@ type PkgVersionInfo = { location: string; }; -export default async (cmd: Command) => { +export default async (opts: OptionValues) => { const lockfilePath = paths.resolveTargetRoot('yarn.lock'); const lockfile = await Lockfile.load(lockfilePath); - let pattern = cmd.pattern; + let pattern = opts.pattern; if (!pattern) { console.log(`Using default pattern glob ${DEFAULT_PATTERN_GLOB}`); @@ -70,14 +70,14 @@ export default async (cmd: Command) => { let findTargetVersion: (name: string) => Promise; let releaseManifest: ReleaseManifest; // Specific release specified. Be strict when resolving versions - if (semver.valid(cmd.release)) { - releaseManifest = await getManifestByVersion({ version: cmd.release }); + if (semver.valid(opts.release)) { + releaseManifest = await getManifestByVersion({ version: opts.release }); findTargetVersion = createStrictVersionFinder({ releaseManifest, }); } else { // Release line specified. Be lenient when resolving versions. - if (cmd.release === 'next') { + if (opts.release === 'next') { const next = await getManifestByReleaseLine({ releaseLine: 'next', }); @@ -90,11 +90,11 @@ export default async (cmd: Command) => { : main; } else { releaseManifest = await getManifestByReleaseLine({ - releaseLine: cmd.release, + releaseLine: opts.release, }); } findTargetVersion = createVersionFinder({ - releaseLine: cmd.releaseLine, + releaseLine: opts.releaseLine, releaseManifest, }); } diff --git a/packages/cli/src/commands/versions/lint.ts b/packages/cli/src/commands/versions/lint.ts index 22f7961db6..9939b2ba51 100644 --- a/packages/cli/src/commands/versions/lint.ts +++ b/packages/cli/src/commands/versions/lint.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { Command } from 'commander'; +import { OptionValues } from 'commander'; import { Lockfile } from '../../lib/versioning'; import { paths } from '../../lib/paths'; import partition from 'lodash/partition'; @@ -47,7 +47,7 @@ export const forbiddenDuplicatesFilter = (name: string) => FORBID_DUPLICATES.some(pattern => pattern.test(name)) && !ALLOW_DUPLICATES.some(pattern => pattern.test(name)); -export default async (cmd: Command) => { +export default async (cmd: OptionValues) => { const fix = Boolean(cmd.fix); let success = true; diff --git a/packages/cli/src/index.ts b/packages/cli/src/index.ts index 286ce6f4d6..d1ca1bcd04 100644 --- a/packages/cli/src/index.ts +++ b/packages/cli/src/index.ts @@ -20,7 +20,7 @@ * @packageDocumentation */ -import program from 'commander'; +import { program } from 'commander'; import chalk from 'chalk'; import { exitWithError } from './lib/errors'; import { version } from './lib/version'; diff --git a/packages/cli/src/lib/role/packageRoles.test.ts b/packages/cli/src/lib/role/packageRoles.test.ts index 2772d263f1..2cd1e29368 100644 --- a/packages/cli/src/lib/role/packageRoles.test.ts +++ b/packages/cli/src/lib/role/packageRoles.test.ts @@ -79,9 +79,10 @@ describe('getRoleFromPackage', () => { describe('findRoleFromCommand', () => { function mkCommand(args: string) { - return new Command() + const parsed = new Command() .option('--role ', 'test role') .parse(['node', 'entry.js', ...args.split(' ')]) as Command; + return parsed.opts(); } beforeEach(() => { diff --git a/packages/cli/src/lib/role/packageRoles.ts b/packages/cli/src/lib/role/packageRoles.ts index a33a7d715a..685848fd26 100644 --- a/packages/cli/src/lib/role/packageRoles.ts +++ b/packages/cli/src/lib/role/packageRoles.ts @@ -16,7 +16,7 @@ import { z } from 'zod'; import fs from 'fs-extra'; -import { Command } from 'commander'; +import { OptionValues } from 'commander'; import { paths } from '../paths'; import { PackageRole, PackageRoleInfo } from './types'; @@ -108,9 +108,11 @@ export function getRoleFromPackage(pkgJson: unknown): PackageRole | undefined { return undefined; } -export async function findRoleFromCommand(cmd: Command): Promise { - if (cmd.role) { - return getRoleInfo(cmd.role)?.role; +export async function findRoleFromCommand( + opts: OptionValues, +): Promise { + if (opts.role) { + return getRoleInfo(opts.role)?.role; } const pkg = await fs.readJson(paths.resolveTarget('package.json')); diff --git a/packages/codemods/package.json b/packages/codemods/package.json index bee26c5f53..681fc527a2 100644 --- a/packages/codemods/package.json +++ b/packages/codemods/package.json @@ -42,7 +42,7 @@ "devDependencies": { "@types/jscodeshift": "^0.11.0", "@types/node": "^16.11.26", - "commander": "^6.1.0", + "commander": "^9.1.0", "ts-node": "^10.0.0" }, "nodemonConfig": { diff --git a/packages/codemods/src/action.ts b/packages/codemods/src/action.ts index bc9104425e..b955ab17ea 100644 --- a/packages/codemods/src/action.ts +++ b/packages/codemods/src/action.ts @@ -16,7 +16,7 @@ import { relative as relativePath } from 'path'; import { spawn } from 'child_process'; -import { Command } from 'commander'; +import { OptionValues } from 'commander'; import { findPaths } from '@backstage/cli-common'; import { platform } from 'os'; import { ExitCodeError } from './errors'; @@ -25,7 +25,7 @@ import { ExitCodeError } from './errors'; const paths = findPaths(__dirname); export function createCodemodAction(name: string) { - return async (_: unknown, cmd: Command) => { + return async (dirs: string[], opts: OptionValues) => { const transformPath = relativePath( process.cwd(), paths.resolveOwn('transforms', `${name}.js`), @@ -39,12 +39,12 @@ export function createCodemodAction(name: string) { '--ignore-pattern=**/node_modules/**', ]; - if (cmd.dry) { + if (opts.dry) { args.push('--dry'); } - if (cmd.args.length) { - args.push(...cmd.args); + if (dirs.length) { + args.push(...dirs); } else { args.push('.'); } diff --git a/packages/codemods/src/index.ts b/packages/codemods/src/index.ts index 8eb8840cf0..ef408e5053 100644 --- a/packages/codemods/src/index.ts +++ b/packages/codemods/src/index.ts @@ -20,7 +20,7 @@ * @packageDocumentation */ -import program from 'commander'; +import { program } from 'commander'; import chalk from 'chalk'; import { codemods } from './codemods'; import { exitWithError } from './errors'; @@ -31,14 +31,14 @@ async function main(argv: string[]) { program.name('backstage-codemods').version(version); const applyCommand = program - .command('apply []') + .command('apply [target-dirs...]') .description( 'Apply a codemod to target directories, defaulting to the current directory', ); for (const codemod of codemods) { applyCommand - .command(`${codemod.name} []`) + .command(`${codemod.name} [target-dirs...]`) .description(codemod.description) .option('-d, --dry', 'Dry run, no changes written to files') .action(createCodemodAction(codemod.name)); diff --git a/packages/create-app/package.json b/packages/create-app/package.json index 502409b8e1..549d0ab0c9 100644 --- a/packages/create-app/package.json +++ b/packages/create-app/package.json @@ -35,7 +35,7 @@ "dependencies": { "@backstage/cli-common": "^0.1.8", "chalk": "^4.0.0", - "commander": "^6.1.0", + "commander": "^9.1.0", "fs-extra": "10.0.1", "handlebars": "^4.7.3", "inquirer": "^8.2.0", diff --git a/packages/create-app/src/createApp.ts b/packages/create-app/src/createApp.ts index 36143a4172..83584445b0 100644 --- a/packages/create-app/src/createApp.ts +++ b/packages/create-app/src/createApp.ts @@ -15,7 +15,7 @@ */ import chalk from 'chalk'; -import { Command } from 'commander'; +import { OptionValues } from 'commander'; import inquirer, { Answers } from 'inquirer'; import { resolve as resolvePath } from 'path'; import { findPaths } from '@backstage/cli-common'; @@ -30,7 +30,7 @@ import { templatingTask, } from './lib/tasks'; -export default async (cmd: Command): Promise => { +export default async (opts: OptionValues): Promise => { /* eslint-disable-next-line no-restricted-syntax */ const paths = findPaths(__dirname); @@ -65,22 +65,22 @@ export default async (cmd: Command): Promise => { // Use `--path` argument as application directory when specified, otherwise // create a directory using `answers.name` - const appDir = cmd.path - ? resolvePath(paths.targetDir, cmd.path) + const appDir = opts.path + ? resolvePath(paths.targetDir, opts.path) : resolvePath(paths.targetDir, answers.name); Task.log(); Task.log('Creating the app...'); try { - if (cmd.path) { + if (opts.path) { // Template directly to specified path Task.section('Checking that supplied path exists'); await checkPathExistsTask(appDir); Task.section('Preparing files'); - await templatingTask(templateDir, cmd.path, answers); + await templatingTask(templateDir, opts.path, answers); } else { // Template to temporary location, and then move files @@ -97,7 +97,7 @@ export default async (cmd: Command): Promise => { await moveAppTask(tempDir, appDir, answers.name); } - if (!cmd.skipInstall) { + if (!opts.skipInstall) { Task.section('Building the app'); await buildAppTask(appDir); } diff --git a/packages/create-app/src/index.ts b/packages/create-app/src/index.ts index a8ff3dc9b9..adb8560f31 100644 --- a/packages/create-app/src/index.ts +++ b/packages/create-app/src/index.ts @@ -20,7 +20,7 @@ * @packageDocumentation */ -import program from 'commander'; +import { program } from 'commander'; import { exitWithError } from './lib/errors'; import { version } from '../package.json'; import createApp from './createApp'; diff --git a/packages/e2e-test/package.json b/packages/e2e-test/package.json index 95bc79b7f1..8d9c91b91d 100644 --- a/packages/e2e-test/package.json +++ b/packages/e2e-test/package.json @@ -35,7 +35,7 @@ "@types/node": "^16.11.26", "@types/puppeteer": "^5.4.4", "chalk": "^4.0.0", - "commander": "^6.1.0", + "commander": "^9.1.0", "cross-fetch": "^3.1.5", "fs-extra": "10.0.1", "handlebars": "^4.7.3", diff --git a/packages/e2e-test/src/commands/index.ts b/packages/e2e-test/src/commands/index.ts index 51066293bf..95d311427c 100644 --- a/packages/e2e-test/src/commands/index.ts +++ b/packages/e2e-test/src/commands/index.ts @@ -14,9 +14,9 @@ * limitations under the License. */ -import { CommanderStatic } from 'commander'; +import { Command } from 'commander'; import { run } from './run'; -export function registerCommands(program: CommanderStatic) { +export function registerCommands(program: Command) { program.command('run').description('Run e2e tests').action(run); } diff --git a/packages/e2e-test/src/index.ts b/packages/e2e-test/src/index.ts index a66d6bb57d..92adc24b1e 100644 --- a/packages/e2e-test/src/index.ts +++ b/packages/e2e-test/src/index.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import program from 'commander'; +import { program } from 'commander'; import chalk from 'chalk'; import { registerCommands } from './commands'; import { version } from '../package.json'; diff --git a/packages/techdocs-cli/package.json b/packages/techdocs-cli/package.json index 28d4b64ebb..5ba1b9c842 100644 --- a/packages/techdocs-cli/package.json +++ b/packages/techdocs-cli/package.json @@ -68,7 +68,7 @@ "@backstage/config": "^1.0.0", "@backstage/plugin-techdocs-node": "^1.0.1-next.1", "@types/dockerode": "^3.3.0", - "commander": "^6.1.0", + "commander": "^9.1.0", "dockerode": "^3.3.1", "fs-extra": "^10.0.1", "http-proxy": "^1.18.1", diff --git a/packages/techdocs-cli/src/commands/generate/generate.ts b/packages/techdocs-cli/src/commands/generate/generate.ts index d192e7a2f9..309b9c7969 100644 --- a/packages/techdocs-cli/src/commands/generate/generate.ts +++ b/packages/techdocs-cli/src/commands/generate/generate.ts @@ -15,7 +15,7 @@ */ import { resolve } from 'path'; -import { Command } from 'commander'; +import { OptionValues } from 'commander'; import fs from 'fs-extra'; import Docker from 'dockerode'; import { @@ -30,19 +30,19 @@ import { } from '../../lib/utility'; import { stdout } from 'process'; -export default async function generate(cmd: Command) { +export default async function generate(opts: OptionValues) { // Use techdocs-node package to generate docs. Keep consistency between Backstage and CI generating docs. // Docs can be prepared using actions/checkout or git clone, or similar paradigms on CI. The TechDocs CI workflow // will run on the CI pipeline containing the documentation files. - const logger = createLogger({ verbose: cmd.verbose }); + const logger = createLogger({ verbose: opts.verbose }); - const sourceDir = resolve(cmd.sourceDir); - const outputDir = resolve(cmd.outputDir); - const omitTechdocsCorePlugin = cmd.omitTechdocsCoreMkdocsPlugin; - const dockerImage = cmd.dockerImage; - const pullImage = cmd.pull; - const legacyCopyReadmeMdToIndexMd = cmd.legacyCopyReadmeMdToIndexMd; + const sourceDir = resolve(opts.sourceDir); + const outputDir = resolve(opts.outputDir); + const omitTechdocsCorePlugin = opts.omitTechdocsCoreMkdocsPlugin; + const dockerImage = opts.dockerImage; + const pullImage = opts.pull; + const legacyCopyReadmeMdToIndexMd = opts.legacyCopyReadmeMdToIndexMd; logger.info(`Using source dir ${sourceDir}`); logger.info(`Will output generated files in ${outputDir}`); @@ -54,7 +54,7 @@ export default async function generate(cmd: Command) { const config = new ConfigReader({ techdocs: { generator: { - runIn: cmd.docker ? 'docker' : 'local', + runIn: opts.docker ? 'docker' : 'local', dockerImage, pullImage, legacyCopyReadmeMdToIndexMd, @@ -70,10 +70,10 @@ export default async function generate(cmd: Command) { const containerRunner = new DockerContainerRunner({ dockerClient }); let parsedLocationAnnotation = {} as ParsedLocationAnnotation; - if (cmd.techdocsRef) { + if (opts.techdocsRef) { try { parsedLocationAnnotation = convertTechDocsRefToLocationAnnotation( - cmd.techdocsRef, + opts.techdocsRef, ); } catch (err) { logger.error(err.message); @@ -91,13 +91,13 @@ export default async function generate(cmd: Command) { await techdocsGenerator.run({ inputDir: sourceDir, outputDir, - ...(cmd.techdocsRef + ...(opts.techdocsRef ? { parsedLocationAnnotation, } : {}), logger, - etag: cmd.etag, + etag: opts.etag, ...(process.env.LOG_LEVEL === 'debug' ? { logStream: stdout } : {}), }); diff --git a/packages/techdocs-cli/src/commands/index.ts b/packages/techdocs-cli/src/commands/index.ts index bad2f195ef..85a218eb54 100644 --- a/packages/techdocs-cli/src/commands/index.ts +++ b/packages/techdocs-cli/src/commands/index.ts @@ -14,12 +14,12 @@ * limitations under the License. */ -import { CommanderStatic } from 'commander'; +import { Command } from 'commander'; import { TechdocsGenerator } from '@backstage/plugin-techdocs-node'; const defaultDockerImage = TechdocsGenerator.defaultDockerImage; -export function registerCommands(program: CommanderStatic) { +export function registerCommands(program: Command) { program .command('generate') .description('Generate TechDocs documentation site using MkDocs.') diff --git a/packages/techdocs-cli/src/commands/migrate/migrate.ts b/packages/techdocs-cli/src/commands/migrate/migrate.ts index 067bf1f173..a086073cda 100644 --- a/packages/techdocs-cli/src/commands/migrate/migrate.ts +++ b/packages/techdocs-cli/src/commands/migrate/migrate.ts @@ -16,19 +16,19 @@ import { SingleHostDiscovery } from '@backstage/backend-common'; import { Publisher } from '@backstage/plugin-techdocs-node'; -import { Command } from 'commander'; +import { OptionValues } from 'commander'; import { createLogger } from '../../lib/utility'; import { PublisherConfig } from '../../lib/PublisherConfig'; -export default async function migrate(cmd: Command) { - const logger = createLogger({ verbose: cmd.verbose }); +export default async function migrate(opts: OptionValues) { + const logger = createLogger({ verbose: opts.verbose }); - const config = PublisherConfig.getValidConfig(cmd); + const config = PublisherConfig.getValidConfig(opts); const discovery = SingleHostDiscovery.fromConfig(config); const publisher = await Publisher.fromConfig(config, { logger, discovery }); if (!publisher.migrateDocsCase) { - throw new Error(`Migration not implemented for ${cmd.publisherType}`); + throw new Error(`Migration not implemented for ${opts.publisherType}`); } // Check that the publisher's underlying storage is ready and available. @@ -39,12 +39,12 @@ export default async function migrate(cmd: Command) { } // Validate and parse migration arguments. - const removeOriginal = cmd.removeOriginal; - const numericConcurrency = parseInt(cmd.concurrency, 10); + const removeOriginal = opts.removeOriginal; + const numericConcurrency = parseInt(opts.concurrency, 10); if (!Number.isInteger(numericConcurrency) || numericConcurrency <= 0) { throw new Error( - `Concurrency must be a number greater than 1. ${cmd.concurrency} provided.`, + `Concurrency must be a number greater than 1. ${opts.concurrency} provided.`, ); } diff --git a/packages/techdocs-cli/src/commands/publish/publish.ts b/packages/techdocs-cli/src/commands/publish/publish.ts index c84180b032..f4e78b57a4 100644 --- a/packages/techdocs-cli/src/commands/publish/publish.ts +++ b/packages/techdocs-cli/src/commands/publish/publish.ts @@ -15,17 +15,17 @@ */ import { resolve } from 'path'; -import { Command } from 'commander'; +import { OptionValues } from 'commander'; import { createLogger } from '../../lib/utility'; import { SingleHostDiscovery } from '@backstage/backend-common'; import { Publisher } from '@backstage/plugin-techdocs-node'; import { Entity } from '@backstage/catalog-model'; import { PublisherConfig } from '../../lib/PublisherConfig'; -export default async function publish(cmd: Command): Promise { - const logger = createLogger({ verbose: cmd.verbose }); +export default async function publish(opts: OptionValues): Promise { + const logger = createLogger({ verbose: opts.verbose }); - const config = PublisherConfig.getValidConfig(cmd); + const config = PublisherConfig.getValidConfig(opts); const discovery = SingleHostDiscovery.fromConfig(config); const publisher = await Publisher.fromConfig(config, { logger, discovery }); @@ -36,7 +36,7 @@ export default async function publish(cmd: Command): Promise { return Promise.reject(new Error('')); } - const [namespace, kind, name] = cmd.entity.split('/'); + const [namespace, kind, name] = opts.entity.split('/'); const entity = { kind, metadata: { @@ -45,7 +45,7 @@ export default async function publish(cmd: Command): Promise { }, } as Entity; - const directory = resolve(cmd.directory); + const directory = resolve(opts.directory); await publisher.publish({ entity, directory }); return true; diff --git a/packages/techdocs-cli/src/commands/serve/mkdocs.ts b/packages/techdocs-cli/src/commands/serve/mkdocs.ts index 6a0952b945..511df00a17 100644 --- a/packages/techdocs-cli/src/commands/serve/mkdocs.ts +++ b/packages/techdocs-cli/src/commands/serve/mkdocs.ts @@ -14,25 +14,25 @@ * limitations under the License. */ -import { Command } from 'commander'; +import { OptionValues } from 'commander'; import openBrowser from 'react-dev-utils/openBrowser'; import { createLogger } from '../../lib/utility'; import { runMkdocsServer } from '../../lib/mkdocsServer'; import { LogFunc, waitForSignal } from '../../lib/run'; -export default async function serveMkdocs(cmd: Command) { - const logger = createLogger({ verbose: cmd.verbose }); +export default async function serveMkdocs(opts: OptionValues) { + const logger = createLogger({ verbose: opts.verbose }); - const dockerAddr = `http://0.0.0.0:${cmd.port}`; - const localAddr = `http://127.0.0.1:${cmd.port}`; - const expectedDevAddr = cmd.docker ? dockerAddr : localAddr; + const dockerAddr = `http://0.0.0.0:${opts.port}`; + const localAddr = `http://127.0.0.1:${opts.port}`; + const expectedDevAddr = opts.docker ? dockerAddr : localAddr; // We want to open browser only once based on a log. let boolOpenBrowserTriggered = false; const logFunc: LogFunc = data => { // Sometimes the lines contain an unnecessary extra new line in between const logLines = data.toString().split('\n'); - const logPrefix = cmd.docker ? '[docker/mkdocs]' : '[mkdocs]'; + const logPrefix = opts.docker ? '[docker/mkdocs]' : '[mkdocs]'; logLines.forEach(line => { if (line === '') { return; @@ -59,10 +59,10 @@ export default async function serveMkdocs(cmd: Command) { // Commander stores --no-docker in cmd.docker variable const childProcess = await runMkdocsServer({ - port: cmd.port, - dockerImage: cmd.dockerImage, - dockerEntrypoint: cmd.dockerEntrypoint, - useDocker: cmd.docker, + port: opts.port, + dockerImage: opts.dockerImage, + dockerEntrypoint: opts.dockerEntrypoint, + useDocker: opts.docker, stdoutLogFunc: logFunc, stderrLogFunc: logFunc, }); diff --git a/packages/techdocs-cli/src/commands/serve/serve.ts b/packages/techdocs-cli/src/commands/serve/serve.ts index c2ac6d8105..454e9ffa55 100644 --- a/packages/techdocs-cli/src/commands/serve/serve.ts +++ b/packages/techdocs-cli/src/commands/serve/serve.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { Command } from 'commander'; +import { OptionValues } from 'commander'; import path from 'path'; import openBrowser from 'react-dev-utils/openBrowser'; import { findPaths } from '@backstage/cli-common'; @@ -42,8 +42,8 @@ function findPreviewBundlePath(): string { } } -export default async function serve(cmd: Command) { - const logger = createLogger({ verbose: cmd.verbose }); +export default async function serve(opts: OptionValues) { + const logger = createLogger({ verbose: opts.verbose }); // Determine if we want to run in local dev mode or not // This will run the backstage http server on a different port and only used @@ -58,15 +58,17 @@ export default async function serve(cmd: Command) { const backstagePort = 3000; const backstageBackendPort = 7007; - const mkdocsDockerAddr = `http://0.0.0.0:${cmd.mkdocsPort}`; - const mkdocsLocalAddr = `http://127.0.0.1:${cmd.mkdocsPort}`; - const mkdocsExpectedDevAddr = cmd.docker ? mkdocsDockerAddr : mkdocsLocalAddr; + const mkdocsDockerAddr = `http://0.0.0.0:${opts.mkdocsPort}`; + const mkdocsLocalAddr = `http://127.0.0.1:${opts.mkdocsPort}`; + const mkdocsExpectedDevAddr = opts.docker + ? mkdocsDockerAddr + : mkdocsLocalAddr; let mkdocsServerHasStarted = false; const mkdocsLogFunc: LogFunc = data => { // Sometimes the lines contain an unnecessary extra new line const logLines = data.toString().split('\n'); - const logPrefix = cmd.docker ? '[docker/mkdocs]' : '[mkdocs]'; + const logPrefix = opts.docker ? '[docker/mkdocs]' : '[mkdocs]'; logLines.forEach(line => { if (line === '') { return; @@ -88,10 +90,10 @@ export default async function serve(cmd: Command) { // Had me questioning this whole implementation for half an hour. logger.info('Starting mkdocs server.'); const mkdocsChildProcess = await runMkdocsServer({ - port: cmd.mkdocsPort, - dockerImage: cmd.dockerImage, - dockerEntrypoint: cmd.dockerEntrypoint, - useDocker: cmd.docker, + port: opts.mkdocsPort, + dockerImage: opts.dockerImage, + dockerEntrypoint: opts.dockerEntrypoint, + useDocker: opts.docker, stdoutLogFunc: mkdocsLogFunc, stderrLogFunc: mkdocsLogFunc, }); @@ -116,8 +118,8 @@ export default async function serve(cmd: Command) { const httpServer = new HTTPServer( findPreviewBundlePath(), port, - cmd.mkdocsPort, - cmd.verbose, + opts.mkdocsPort, + opts.verbose, ); httpServer diff --git a/packages/techdocs-cli/src/index.ts b/packages/techdocs-cli/src/index.ts index 6f4437cbce..ff93dada85 100644 --- a/packages/techdocs-cli/src/index.ts +++ b/packages/techdocs-cli/src/index.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import program from 'commander'; +import { program } from 'commander'; import { registerCommands } from './commands'; import { version } from '../package.json'; diff --git a/packages/techdocs-cli/src/lib/PublisherConfig.test.ts b/packages/techdocs-cli/src/lib/PublisherConfig.test.ts index 88f542c049..24cad332ac 100644 --- a/packages/techdocs-cli/src/lib/PublisherConfig.test.ts +++ b/packages/techdocs-cli/src/lib/PublisherConfig.test.ts @@ -14,14 +14,14 @@ * limitations under the License. */ -import { Command } from 'commander'; +import { OptionValues } from 'commander'; import { PublisherConfig } from './PublisherConfig'; describe('getValidPublisherConfig', () => { it('should not allow unknown publisher types', () => { const invalidConfig = { publisherType: 'unknown publisher', - } as unknown as Command; + } as unknown as OptionValues; expect(() => PublisherConfig.getValidConfig(invalidConfig)).toThrowError( `Unknown publisher type ${invalidConfig.publisherType}`, @@ -32,7 +32,7 @@ describe('getValidPublisherConfig', () => { it('should require --azureAccountName', () => { const config = { publisherType: 'azureBlobStorage', - } as unknown as Command; + } as unknown as OptionValues; expect(() => PublisherConfig.getValidConfig(config)).toThrowError( 'azureBlobStorage requires --azureAccountName to be specified', @@ -44,7 +44,7 @@ describe('getValidPublisherConfig', () => { publisherType: 'azureBlobStorage', azureAccountName: 'someAccountName', storageName: 'someContainer', - } as unknown as Command; + } as unknown as OptionValues; const actualConfig = PublisherConfig.getValidConfig(config); expect(actualConfig.getString('techdocs.publisher.type')).toBe( @@ -69,7 +69,7 @@ describe('getValidPublisherConfig', () => { publisherType: 'awsS3', storageName: 'someStorageName', awsBucketRootPath: 'backstage-data/techdocs', - } as unknown as Command; + } as unknown as OptionValues; const actualConfig = PublisherConfig.getValidConfig(config); expect(actualConfig.getString('techdocs.publisher.type')).toBe('awsS3'); @@ -86,7 +86,7 @@ describe('getValidPublisherConfig', () => { publisherType: 'awsS3', storageName: 'someStorageName', awsS3sse: 'aws:kms', - } as unknown as Command; + } as unknown as OptionValues; const actualConfig = PublisherConfig.getValidConfig(config); expect(actualConfig.getString('techdocs.publisher.type')).toBe('awsS3'); @@ -102,7 +102,7 @@ describe('getValidPublisherConfig', () => { publisherType: 'openStackSwift', osCredentialId: 'someCredentialId', osSecret: 'someSecret', - } as unknown as Command; + } as unknown as OptionValues; expect(() => PublisherConfig.getValidConfig(config)).toThrowError( `openStackSwift requires the following params to be specified: ${[ @@ -120,7 +120,7 @@ describe('getValidPublisherConfig', () => { osSecret: 'someSecret', osAuthUrl: 'someAuthUrl', osSwiftUrl: 'someSwiftUrl', - } as unknown as Command; + } as unknown as OptionValues; const actualConfig = PublisherConfig.getValidConfig(config); expect(actualConfig.getString('techdocs.publisher.type')).toBe( @@ -146,7 +146,7 @@ describe('getValidPublisherConfig', () => { publisherType: 'googleGcs', storageName: 'someStorageName', gcsBucketRootPath: 'backstage-data/techdocs', - } as unknown as Command; + } as unknown as OptionValues; const actualConfig = PublisherConfig.getValidConfig(config); expect(actualConfig.getString('techdocs.publisher.type')).toBe( diff --git a/packages/techdocs-cli/src/lib/PublisherConfig.ts b/packages/techdocs-cli/src/lib/PublisherConfig.ts index c18b9ff588..0d1c8fc8a9 100644 --- a/packages/techdocs-cli/src/lib/PublisherConfig.ts +++ b/packages/techdocs-cli/src/lib/PublisherConfig.ts @@ -15,7 +15,7 @@ */ import { ConfigReader } from '@backstage/config'; -import { Command } from 'commander'; +import { OptionValues } from 'commander'; type Publisher = keyof typeof PublisherConfig['configFactories']; type PublisherConfiguration = { @@ -45,11 +45,11 @@ export class PublisherConfig { * Note: This assumes that proper credentials are set in Environment * variables for the respective GCS/AWS clients to work. */ - static getValidConfig(cmd: Command): ConfigReader { - const publisherType = cmd.publisherType; + static getValidConfig(opts: OptionValues): ConfigReader { + const publisherType = opts.publisherType; if (!PublisherConfig.isKnownPublisher(publisherType)) { - throw new Error(`Unknown publisher type ${cmd.publisherType}`); + throw new Error(`Unknown publisher type ${opts.publisherType}`); } return new ConfigReader({ @@ -61,9 +61,9 @@ export class PublisherConfig { }, }, techdocs: { - publisher: PublisherConfig.configFactories[publisherType](cmd), + publisher: PublisherConfig.configFactories[publisherType](opts), legacyUseCaseSensitiveTripletPaths: - cmd.legacyUseCaseSensitiveTripletPaths, + opts.legacyUseCaseSensitiveTripletPaths, }, }); } @@ -80,16 +80,20 @@ export class PublisherConfig { /** * Retrieve valid AWS S3 configuration based on the command. */ - private static getValidAwsS3Config(cmd: Command): PublisherConfiguration { + private static getValidAwsS3Config( + opts: OptionValues, + ): PublisherConfiguration { return { type: 'awsS3', awsS3: { - bucketName: cmd.storageName, - ...(cmd.awsBucketRootPath && { bucketRootPath: cmd.awsBucketRootPath }), - ...(cmd.awsRoleArn && { credentials: { roleArn: cmd.awsRoleArn } }), - ...(cmd.awsEndpoint && { endpoint: cmd.awsEndpoint }), - ...(cmd.awsS3ForcePathStyle && { s3ForcePathStyle: true }), - ...(cmd.awsS3sse && { sse: cmd.awsS3sse }), + bucketName: opts.storageName, + ...(opts.awsBucketRootPath && { + bucketRootPath: opts.awsBucketRootPath, + }), + ...(opts.awsRoleArn && { credentials: { roleArn: opts.awsRoleArn } }), + ...(opts.awsEndpoint && { endpoint: opts.awsEndpoint }), + ...(opts.awsS3ForcePathStyle && { s3ForcePathStyle: true }), + ...(opts.awsS3sse && { sse: opts.awsS3sse }), }, }; } @@ -97,8 +101,10 @@ export class PublisherConfig { /** * Retrieve valid Azure Blob Storage configuration based on the command. */ - private static getValidAzureConfig(cmd: Command): PublisherConfiguration { - if (!cmd.azureAccountName) { + private static getValidAzureConfig( + opts: OptionValues, + ): PublisherConfiguration { + if (!opts.azureAccountName) { throw new Error( `azureBlobStorage requires --azureAccountName to be specified`, ); @@ -107,10 +113,10 @@ export class PublisherConfig { return { type: 'azureBlobStorage', azureBlobStorage: { - containerName: cmd.storageName, + containerName: opts.storageName, credentials: { - accountName: cmd.azureAccountName, - accountKey: cmd.azureAccountKey, + accountName: opts.azureAccountName, + accountKey: opts.azureAccountKey, }, }, }; @@ -119,12 +125,16 @@ export class PublisherConfig { /** * Retrieve valid GCS configuration based on the command. */ - private static getValidGoogleGcsConfig(cmd: Command): PublisherConfiguration { + private static getValidGoogleGcsConfig( + opts: OptionValues, + ): PublisherConfiguration { return { type: 'googleGcs', googleGcs: { - bucketName: cmd.storageName, - ...(cmd.gcsBucketRootPath && { bucketRootPath: cmd.gcsBucketRootPath }), + bucketName: opts.storageName, + ...(opts.gcsBucketRootPath && { + bucketRootPath: opts.gcsBucketRootPath, + }), }, }; } @@ -133,14 +143,14 @@ export class PublisherConfig { * Retrieves valid OpenStack Swift configuration based on the command. */ private static getValidOpenStackSwiftConfig( - cmd: Command, + opts: OptionValues, ): PublisherConfiguration { const missingParams = [ 'osCredentialId', 'osSecret', 'osAuthUrl', 'osSwiftUrl', - ].filter((param: string) => !cmd[param]); + ].filter((param: string) => !opts[param]); if (missingParams.length) { throw new Error( @@ -153,13 +163,13 @@ export class PublisherConfig { return { type: 'openStackSwift', openStackSwift: { - containerName: cmd.storageName, + containerName: opts.storageName, credentials: { - id: cmd.osCredentialId, - secret: cmd.osSecret, + id: opts.osCredentialId, + secret: opts.osSecret, }, - authUrl: cmd.osAuthUrl, - swiftUrl: cmd.osSwiftUrl, + authUrl: opts.osAuthUrl, + swiftUrl: opts.osSwiftUrl, }, }; } diff --git a/yarn.lock b/yarn.lock index e469f8432b..2f03a3fc44 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9575,16 +9575,16 @@ commander@^5.1.0: resolved "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz#46abbd1652f8e059bddaef99bbdcb2ad9cf179ae" integrity sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg== -commander@^6.1.0: - version "6.2.1" - resolved "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz#0792eb682dfbc325999bb2b84fddddba110ac73c" - integrity sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA== - commander@^7.2.0: version "7.2.0" resolved "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7" integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== +commander@^9.1.0: + version "9.1.0" + resolved "https://registry.npmjs.org/commander/-/commander-9.1.0.tgz#a6b263b2327f2e188c6402c42623327909f2dbec" + integrity sha512-i0/MaqBtdbnJ4XQs4Pmyb+oFQl+q0lsAmokVUH92SlSw4fkeAcG3bVon+Qt7hmtF+u3Het6o4VgrcY3qAoEB6w== + common-ancestor-path@^1.0.1: version "1.0.1" resolved "https://registry.npmjs.org/common-ancestor-path/-/common-ancestor-path-1.0.1.tgz#4f7d2d1394d91b7abdf51871c62f71eadb0182a7"