diff --git a/.changeset/migrate-cli-commands-to-cleye.md b/.changeset/migrate-cli-commands-to-cleye.md index 34b595e1a5..45f76fb6af 100644 --- a/.changeset/migrate-cli-commands-to-cleye.md +++ b/.changeset/migrate-cli-commands-to-cleye.md @@ -2,12 +2,4 @@ '@backstage/cli': patch --- -Migrated remaining CLI command handlers from `commander` to `cleye` for argument parsing. The following CLI flags have been renamed from camelCase to kebab-case to match standard CLI conventions: - -- `--baseVersion` → `--base-version` -- `--successCache` → `--success-cache` -- `--successCacheDir` → `--success-cache-dir` -- `--alwaysPack` → `--always-pack` -- `--alwaysYarnPack` → `--always-pack` (hidden legacy alias preserved) - -The old camelCase flag names still work but will print a deprecation warning. Please update any scripts or CI configurations to use the new kebab-case spelling. +Migrated remaining CLI command handlers from `commander` to `cleye` for argument parsing. CLI flags are now displayed in kebab-case in help output (e.g. `--success-cache` instead of `--successCache`), but both forms are accepted transparently — no changes needed in existing scripts or CI configurations. diff --git a/packages/cli/src/modules/build/commands/buildWorkspace.ts b/packages/cli/src/modules/build/commands/buildWorkspace.ts index 6641734a2a..649171d7d8 100644 --- a/packages/cli/src/modules/build/commands/buildWorkspace.ts +++ b/packages/cli/src/modules/build/commands/buildWorkspace.ts @@ -20,15 +20,14 @@ import { createDistWorkspace } from '../lib/packager'; import type { CommandContext } from '../../../wiring/types'; export default async ({ args, info }: CommandContext) => { - // Support legacy --alwaysYarnPack and --alwaysPack aliases (including =value form) + // Normalize legacy --alwaysYarnPack alias (a genuinely different name, not + // just a casing variant — type-flag handles camelCase/kebab-case natively) const normalizedArgs = args.map(a => { - for (const old of ['--alwaysYarnPack', '--alwaysPack']) { - if (a === old || a.startsWith(`${old}=`)) { - process.stderr.write( - `DEPRECATION WARNING: ${old} has been renamed to --always-pack\n`, - ); - return `--always-pack${a.substring(old.length)}`; - } + if (a === '--alwaysYarnPack') { + return '--always-pack'; + } + if (a.startsWith('--alwaysYarnPack=')) { + return `--always-pack${a.substring('--alwaysYarnPack'.length)}`; } return a; }); diff --git a/packages/cli/src/modules/lint/commands/repo/lint.ts b/packages/cli/src/modules/lint/commands/repo/lint.ts index ea7b183ba8..513c76e0a5 100644 --- a/packages/cli/src/modules/lint/commands/repo/lint.ts +++ b/packages/cli/src/modules/lint/commands/repo/lint.ts @@ -40,54 +40,6 @@ function depCount(pkg: BackstagePackageJson) { } export default async ({ args, info }: CommandContext) => { - const flagDefs = { - fix: { - type: Boolean, - description: 'Attempt to automatically fix violations', - }, - format: { - type: String, - description: 'Lint report output format', - default: 'eslint-formatter-friendly', - }, - outputFile: { - type: String, - description: 'Write the lint report to a file instead of stdout', - }, - successCache: { - type: Boolean, - description: - 'Enable success caching, which skips running tests for unchanged packages that were successful in the previous run', - }, - successCacheDir: { - type: String, - description: - 'Set the success cache location, (default: node_modules/.cache/backstage-cli)', - }, - since: { - type: String, - description: 'Only lint packages that changed since the specified ref', - }, - maxWarnings: { - type: String, - description: - 'Fail if more than this number of warnings. -1 allows warnings. (default: -1)', - }, - }; - - for (const [old, replacement] of Object.entries({ - '--outputFile': '--output-file', - '--successCache': '--success-cache', - '--successCacheDir': '--success-cache-dir', - '--maxWarnings': '--max-warnings', - })) { - if (args.some(a => a === old || a.startsWith(`${old}=`))) { - process.stderr.write( - `DEPRECATION WARNING: ${old} has been renamed to ${replacement}\n`, - ); - } - } - const { flags: { fix, @@ -98,7 +50,48 @@ export default async ({ args, info }: CommandContext) => { since, maxWarnings, }, - } = cli({ help: info, flags: flagDefs }, undefined, args); + } = cli( + { + help: info, + flags: { + fix: { + type: Boolean, + description: 'Attempt to automatically fix violations', + }, + format: { + type: String, + description: 'Lint report output format', + default: 'eslint-formatter-friendly', + }, + outputFile: { + type: String, + description: 'Write the lint report to a file instead of stdout', + }, + successCache: { + type: Boolean, + description: + 'Enable success caching, which skips running tests for unchanged packages that were successful in the previous run', + }, + successCacheDir: { + type: String, + description: + 'Set the success cache location, (default: node_modules/.cache/backstage-cli)', + }, + since: { + type: String, + description: + 'Only lint packages that changed since the specified ref', + }, + maxWarnings: { + type: String, + description: + 'Fail if more than this number of warnings. -1 allows warnings. (default: -1)', + }, + }, + }, + undefined, + args, + ); let packages = await PackageGraph.listTargetPackages(); diff --git a/packages/cli/src/modules/new/commands/new.ts b/packages/cli/src/modules/new/commands/new.ts index 0fb49e6b29..a4899cf509 100644 --- a/packages/cli/src/modules/new/commands/new.ts +++ b/packages/cli/src/modules/new/commands/new.ts @@ -19,56 +19,6 @@ import { createNewPackage } from '../lib/createNewPackage'; import type { CommandContext } from '../../../wiring/types'; export default async ({ args, info }: CommandContext) => { - const flagDefs = { - select: { - type: String, - description: 'Select the thing you want to be creating upfront', - }, - option: { - type: [String] as const, - description: 'Pre-fill options for the creation process', - default: [] as string[], - }, - skipInstall: { - type: Boolean, - description: `Skips running 'yarn install' and 'yarn lint --fix'`, - }, - scope: { - type: String, - description: 'The scope to use for new packages', - }, - npmRegistry: { - type: String, - description: 'The package registry to use for new packages', - }, - baseVersion: { - type: String, - description: 'The version to use for any new packages (default: 0.1.0)', - }, - license: { - type: String, - description: - 'The license to use for any new packages (default: Apache-2.0)', - }, - private: { - type: Boolean, - description: 'Mark new packages as private', - default: true, - }, - }; - - for (const [old, replacement] of Object.entries({ - '--skipInstall': '--skip-install', - '--npmRegistry': '--npm-registry', - '--baseVersion': '--base-version', - })) { - if (args.some(a => a === old || a.startsWith(`${old}=`))) { - process.stderr.write( - `DEPRECATION WARNING: ${old} has been renamed to ${replacement}\n`, - ); - } - } - const { flags: { select, @@ -80,7 +30,51 @@ export default async ({ args, info }: CommandContext) => { license, private: isPrivate, }, - } = cli({ help: info, flags: flagDefs }, undefined, args); + } = cli( + { + help: info, + flags: { + select: { + type: String, + description: 'Select the thing you want to be creating upfront', + }, + option: { + type: [String] as const, + description: 'Pre-fill options for the creation process', + default: [] as string[], + }, + skipInstall: { + type: Boolean, + description: `Skips running 'yarn install' and 'yarn lint --fix'`, + }, + scope: { + type: String, + description: 'The scope to use for new packages', + }, + npmRegistry: { + type: String, + description: 'The package registry to use for new packages', + }, + baseVersion: { + type: String, + description: + 'The version to use for any new packages (default: 0.1.0)', + }, + license: { + type: String, + description: + 'The license to use for any new packages (default: Apache-2.0)', + }, + private: { + type: Boolean, + description: 'Mark new packages as private', + default: true, + }, + }, + }, + undefined, + args, + ); const prefilledParams = parseParams(rawArgOptions); diff --git a/packages/cli/src/modules/test/commands/repo/test.ts b/packages/cli/src/modules/test/commands/repo/test.ts index 8d6287676e..743aa87c3d 100644 --- a/packages/cli/src/modules/test/commands/repo/test.ts +++ b/packages/cli/src/modules/test/commands/repo/test.ts @@ -136,41 +136,28 @@ export default async ({ args, info }: CommandContext) => { // Parse Backstage-specific flags; unknown flags and arguments are left in // args so they can be forwarded to Jest. - const flagDefs = { - since: { - type: String, - description: 'Only include test packages changed since the specified ref', - }, - successCache: { - type: Boolean, - description: 'Cache and skip tests for unchanged packages', - }, - successCacheDir: { - type: String, - description: 'Directory for the success cache', - }, - jestHelp: { - type: Boolean, - description: "Show Jest's own help output", - }, - }; - - for (const [old, replacement] of Object.entries({ - '--successCache': '--success-cache', - '--successCacheDir': '--success-cache-dir', - '--jestHelp': '--jest-help', - })) { - if (args.some(a => a === old || a.startsWith(`${old}=`))) { - process.stderr.write( - `DEPRECATION WARNING: ${old} has been renamed to ${replacement}\n`, - ); - } - } - const { flags: opts } = cli( { help: info, - flags: flagDefs, + flags: { + since: { + type: String, + description: + 'Only include test packages changed since the specified ref', + }, + successCache: { + type: Boolean, + description: 'Cache and skip tests for unchanged packages', + }, + successCacheDir: { + type: String, + description: 'Directory for the success cache', + }, + jestHelp: { + type: Boolean, + description: "Show Jest's own help output", + }, + }, ignoreArgv: type => type === 'unknown-flag' || type === 'argument', }, undefined,