From c28e6a7b1ca3e7dd3c9711646790aac5659abb0a Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Fri, 6 Mar 2026 14:52:11 +0100 Subject: [PATCH] Remove unnecessary deprecation warnings for camelCase flags type-flag natively supports both camelCase and kebab-case for all flags, so no deprecation warnings or normalization are needed for casing variants. Only the --alwaysYarnPack alias (a genuinely different name) still requires normalization in buildWorkspace. Also inlined flagDefs at each call site and updated the changeset to reflect that both flag forms work transparently. Signed-off-by: Patrik Oldsberg Made-with: Cursor --- .changeset/migrate-cli-commands-to-cleye.md | 10 +- .../modules/build/commands/buildWorkspace.ts | 15 ++- .../src/modules/lint/commands/repo/lint.ts | 91 ++++++++---------- packages/cli/src/modules/new/commands/new.ts | 96 +++++++++---------- .../src/modules/test/commands/repo/test.ts | 51 ++++------ 5 files changed, 114 insertions(+), 149 deletions(-) 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,