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 <poldsberg@gmail.com>
Made-with: Cursor
This commit is contained in:
Patrik Oldsberg
2026-03-06 14:52:11 +01:00
parent 8da1817584
commit c28e6a7b1c
5 changed files with 114 additions and 149 deletions
+1 -9
View File
@@ -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.
@@ -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;
});
@@ -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();
+45 -51
View File
@@ -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);
@@ -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,