diff --git a/.changeset/cli-report-parser-cleye.md b/.changeset/cli-report-parser-cleye.md new file mode 100644 index 0000000000..f805aeb5d4 --- /dev/null +++ b/.changeset/cli-report-parser-cleye.md @@ -0,0 +1,5 @@ +--- +'@backstage/repo-tools': patch +--- + +Updated CLI report parser to support cleye-style help output sections (`USAGE:` and `FLAGS:`). diff --git a/packages/cli/cli-report.md b/packages/cli/cli-report.md index ee4b03cbca..591b32ead7 100644 --- a/packages/cli/cli-report.md +++ b/packages/cli/cli-report.md @@ -57,81 +57,75 @@ Commands: ### `backstage-cli config docs` ``` -Usage: backstage-cli config docs [options] +Usage: backstage-cli config docs Options: - --package + --package -h, --help ``` ### `backstage-cli config schema` ``` -Usage: +Usage: backstage-cli config schema Options: - --format - --help + --format --merge - --no-merge - --package - --version + --package + -h, --help ``` ### `backstage-cli config:check` ``` -Usage: +Usage: backstage-cli config:check Options: - --config + --config --deprecated --frontend - --help --lax - --package + --package --strict - --version + -h, --help ``` ### `backstage-cli config:docs` ``` -Usage: program [options] +Usage: backstage-cli config:docs Options: - --package + --package -h, --help ``` ### `backstage-cli config:print` ``` -Usage: +Usage: backstage-cli config:print Options: - --config - --format + --config + --format --frontend - --help --lax - --package - --version + --package --with-secrets + -h, --help ``` ### `backstage-cli config:schema` ``` -Usage: +Usage: backstage-cli config:schema Options: - --format - --help + --format --merge - --no-merge - --package - --version + --package + -h, --help ``` ### `backstage-cli create-github-app` @@ -146,13 +140,12 @@ Options: ### `backstage-cli info` ``` -Usage: +Usage: backstage-cli info Options: - --format - --help - --include - --version + --format + --include + -h, --help ``` ### `backstage-cli migrate` @@ -175,7 +168,7 @@ Commands: ### `backstage-cli migrate package-exports` ``` -Usage: program [options] +Usage: backstage-cli migrate package-exports Options: -h, --help @@ -184,7 +177,7 @@ Options: ### `backstage-cli migrate package-lint-configs` ``` -Usage: program [options] +Usage: backstage-cli migrate package-lint-configs Options: -h, --help @@ -193,7 +186,7 @@ Options: ### `backstage-cli migrate package-roles` ``` -Usage: program [options] +Usage: backstage-cli migrate package-roles Options: -h, --help @@ -202,7 +195,7 @@ Options: ### `backstage-cli migrate package-scripts` ``` -Usage: program [options] +Usage: backstage-cli migrate package-scripts Options: -h, --help @@ -211,7 +204,7 @@ Options: ### `backstage-cli migrate react-router-deps` ``` -Usage: program [options] +Usage: backstage-cli migrate react-router-deps Options: -h, --help @@ -271,7 +264,7 @@ Options: ### `backstage-cli package clean` ``` -Usage: program [options] +Usage: backstage-cli package clean Options: -h, --help @@ -293,7 +286,7 @@ Options: ### `backstage-cli package postpack` ``` -Usage: program [options] +Usage: backstage-cli package postpack Options: -h, --help @@ -302,7 +295,7 @@ Options: ### `backstage-cli package prepack` ``` -Usage: program [options] +Usage: backstage-cli package prepack Options: -h, --help @@ -472,7 +465,7 @@ Options: ### `backstage-cli repo clean` ``` -Usage: program [options] +Usage: backstage-cli repo clean Options: -h, --help @@ -560,25 +553,23 @@ Commands: ### `backstage-cli translations export` ``` -Usage: +Usage: backstage-cli translations export Options: - --help - --output - --pattern - --version + --output + --pattern + -h, --help ``` ### `backstage-cli translations import` ``` -Usage: +Usage: backstage-cli translations import Options: - --help - --input - --output - --version + --input + --output + -h, --help ``` ### `backstage-cli versions:bump` diff --git a/packages/cli/src/modules/build/commands/package/clean.ts b/packages/cli/src/modules/build/commands/package/clean.ts index 70d7ea3771..f222c23666 100644 --- a/packages/cli/src/modules/build/commands/package/clean.ts +++ b/packages/cli/src/modules/build/commands/package/clean.ts @@ -14,11 +14,14 @@ * limitations under the License. */ +import { cli } from 'cleye'; import fs from 'fs-extra'; import { targetPaths } from '@backstage/cli-common'; +import type { CommandContext } from '../../../../wiring/types'; -export default async function clean() { +export default async ({ args, info }: CommandContext) => { + cli({ help: info }, undefined, args); await fs.remove(targetPaths.resolve('dist')); await fs.remove(targetPaths.resolve('dist-types')); await fs.remove(targetPaths.resolve('coverage')); -} +}; diff --git a/packages/cli/src/modules/build/commands/repo/clean.ts b/packages/cli/src/modules/build/commands/repo/clean.ts index a3c6e9cbbd..efafdae510 100644 --- a/packages/cli/src/modules/build/commands/repo/clean.ts +++ b/packages/cli/src/modules/build/commands/repo/clean.ts @@ -14,13 +14,15 @@ * limitations under the License. */ +import { cli } from 'cleye'; import fs from 'fs-extra'; import { resolve as resolvePath } from 'node:path'; import { PackageGraph } from '@backstage/cli-node'; - import { run, targetPaths } from '@backstage/cli-common'; +import type { CommandContext } from '../../../../wiring/types'; -export default async function command(): Promise { +export default async ({ args, info }: CommandContext) => { + cli({ help: info }, undefined, args); const packages = await PackageGraph.listTargetPackages(); await fs.remove(targetPaths.resolveRoot('dist')); @@ -48,4 +50,4 @@ export default async function command(): Promise { } }), ); -} +}; diff --git a/packages/cli/src/modules/build/index.ts b/packages/cli/src/modules/build/index.ts index 7a116f5d8a..fd94cb5db6 100644 --- a/packages/cli/src/modules/build/index.ts +++ b/packages/cli/src/modules/build/index.ts @@ -14,6 +14,7 @@ * limitations under the License. */ +import { cli } from 'cleye'; import { Command, Option } from 'commander'; import { createCliPlugin } from '../../wiring/factory'; import { lazy } from '../../wiring/lazy'; @@ -214,7 +215,8 @@ export const buildPlugin = createCliPlugin({ reg.addCommand({ path: ['package', 'prepack'], description: 'Prepares a package for packaging before publishing', - execute: async () => { + execute: async ({ args, info }) => { + cli({ help: info }, undefined, args); const { pre } = await import('./commands/package/pack'); await pre(); }, @@ -223,7 +225,8 @@ export const buildPlugin = createCliPlugin({ reg.addCommand({ path: ['package', 'postpack'], description: 'Restores the changes made by the prepack command', - execute: async () => { + execute: async ({ args, info }) => { + cli({ help: info }, undefined, args); const { post } = await import('./commands/package/pack'); await post(); }, diff --git a/packages/cli/src/modules/migrate/commands/packageExports.ts b/packages/cli/src/modules/migrate/commands/packageExports.ts index 581c334c6f..3307e55721 100644 --- a/packages/cli/src/modules/migrate/commands/packageExports.ts +++ b/packages/cli/src/modules/migrate/commands/packageExports.ts @@ -14,8 +14,12 @@ * limitations under the License. */ -export default async function command() { +import { cli } from 'cleye'; +import type { CommandContext } from '../../../wiring/types'; + +export default async ({ args, info }: CommandContext) => { + cli({ help: info }, undefined, args); throw new Error( 'The `migrate package-exports` command has been removed, use `repo fix` instead.', ); -} +}; diff --git a/packages/cli/src/modules/migrate/commands/packageLintConfigs.ts b/packages/cli/src/modules/migrate/commands/packageLintConfigs.ts index 4df76a51ac..c6839fe28b 100644 --- a/packages/cli/src/modules/migrate/commands/packageLintConfigs.ts +++ b/packages/cli/src/modules/migrate/commands/packageLintConfigs.ts @@ -14,14 +14,17 @@ * limitations under the License. */ +import { cli } from 'cleye'; import fs from 'fs-extra'; import { resolve as resolvePath } from 'node:path'; import { PackageGraph } from '@backstage/cli-node'; import { runOutput } from '@backstage/cli-common'; +import type { CommandContext } from '../../../wiring/types'; const PREFIX = `module.exports = require('@backstage/cli/config/eslint-factory')`; -export default async function command() { +export default async ({ args, info }: CommandContext) => { + cli({ help: info }, undefined, args); const packages = await PackageGraph.listTargetPackages(); const oldConfigs = [ @@ -86,4 +89,4 @@ export default async function command() { if (hasPrettier) { await runOutput(['prettier', '--write', ...configPaths]); } -} +}; diff --git a/packages/cli/src/modules/migrate/commands/packageRole.ts b/packages/cli/src/modules/migrate/commands/packageRole.ts index 6b422c375e..8d8c04b735 100644 --- a/packages/cli/src/modules/migrate/commands/packageRole.ts +++ b/packages/cli/src/modules/migrate/commands/packageRole.ts @@ -14,13 +14,16 @@ * limitations under the License. */ +import { cli } from 'cleye'; import fs from 'fs-extra'; import { resolve as resolvePath } from 'node:path'; import { getPackages } from '@manypkg/get-packages'; import { PackageRoles } from '@backstage/cli-node'; import { targetPaths } from '@backstage/cli-common'; +import type { CommandContext } from '../../../wiring/types'; -export default async () => { +export default async ({ args, info }: CommandContext) => { + cli({ help: info }, undefined, args); const { packages } = await getPackages(targetPaths.dir); await Promise.all( diff --git a/packages/cli/src/modules/migrate/commands/packageScripts.ts b/packages/cli/src/modules/migrate/commands/packageScripts.ts index f875bf14fc..e76c684a6f 100644 --- a/packages/cli/src/modules/migrate/commands/packageScripts.ts +++ b/packages/cli/src/modules/migrate/commands/packageScripts.ts @@ -14,15 +14,18 @@ * limitations under the License. */ +import { cli } from 'cleye'; import fs from 'fs-extra'; import { resolve as resolvePath } from 'node:path'; import { PackageGraph, PackageRoles, PackageRole } from '@backstage/cli-node'; +import type { CommandContext } from '../../../wiring/types'; const configArgPattern = /--config[=\s][^\s$]+/; const noStartRoles: PackageRole[] = ['cli', 'common-library']; -export default async function command() { +export default async ({ args, info }: CommandContext) => { + cli({ help: info }, undefined, args); const packages = await PackageGraph.listTargetPackages(); await Promise.all( @@ -104,4 +107,4 @@ export default async function command() { } }), ); -} +}; diff --git a/packages/cli/src/modules/migrate/commands/reactRouterDeps.ts b/packages/cli/src/modules/migrate/commands/reactRouterDeps.ts index 3c2cf46560..702593c366 100644 --- a/packages/cli/src/modules/migrate/commands/reactRouterDeps.ts +++ b/packages/cli/src/modules/migrate/commands/reactRouterDeps.ts @@ -14,14 +14,17 @@ * limitations under the License. */ +import { cli } from 'cleye'; import fs from 'fs-extra'; import { resolve as resolvePath } from 'node:path'; import { PackageGraph, PackageRoles } from '@backstage/cli-node'; +import type { CommandContext } from '../../../wiring/types'; const REACT_ROUTER_DEPS = ['react-router', 'react-router-dom']; const REACT_ROUTER_RANGE = '6.0.0-beta.0 || ^6.3.0'; -export default async function command() { +export default async ({ args, info }: CommandContext) => { + cli({ help: info }, undefined, args); const packages = await PackageGraph.listTargetPackages(); await Promise.all( @@ -56,4 +59,4 @@ export default async function command() { } }), ); -} +}; diff --git a/packages/eslint-plugin/package.json b/packages/eslint-plugin/package.json index 2a85462335..89e08206ce 100644 --- a/packages/eslint-plugin/package.json +++ b/packages/eslint-plugin/package.json @@ -5,9 +5,6 @@ "publishConfig": { "access": "public" }, - "backstage": { - "role": "cli" - }, "homepage": "https://backstage.io", "repository": { "type": "git", diff --git a/packages/repo-tools/src/commands/api-reports/cli-reports/runCliExtraction.ts b/packages/repo-tools/src/commands/api-reports/cli-reports/runCliExtraction.ts index 146c83bcfb..ae49c95f39 100644 --- a/packages/repo-tools/src/commands/api-reports/cli-reports/runCliExtraction.ts +++ b/packages/repo-tools/src/commands/api-reports/cli-reports/runCliExtraction.ts @@ -27,7 +27,14 @@ import { generateCliReport } from './generateCliReport'; import { logApiReportInstructions } from '../common'; function parseHelpPage(helpPageContent: string) { - const [, usage] = helpPageContent.match(/^\s*Usage: (.*)$/im) ?? []; + let usage: string | undefined; + + // Commander format: "Usage: backstage-cli ..." + const commanderUsage = helpPageContent.match(/^\s*Usage: (.*)$/im); + if (commanderUsage) { + usage = commanderUsage[1]; + } + const lines = helpPageContent.split(/\r?\n/); let options = new Array(); @@ -39,8 +46,8 @@ function parseHelpPage(helpPageContent: string) { lines.shift(); } if (lines.length > 0) { - // Start of a new section, e.g. "Options:" - const sectionName = lines.shift(); + // Start of a new section, e.g. "Options:" or "FLAGS:" + const sectionName = lines.shift()?.toLocaleLowerCase('en-US'); // Take lines until we hit the next section or the end const sectionEndIndex = lines.findIndex( line => line && !line.match(/^\s/), @@ -53,12 +60,18 @@ function parseHelpPage(helpPageContent: string) { .map(line => line.match(/^\s{1,8}(.*?)\s\s+/)?.[1]) .filter(Boolean) as string[]; - if (sectionName?.toLocaleLowerCase('en-US') === 'options:') { + if (sectionName === 'options:' || sectionName === 'flags:') { options = sectionItems; - } else if (sectionName?.toLocaleLowerCase('en-US') === 'commands:') { + } else if (sectionName === 'commands:') { commands = sectionItems; - } else if (sectionName?.toLocaleLowerCase('en-US') === 'arguments:') { + } else if (sectionName === 'arguments:') { commandArguments = sectionItems; + } else if (sectionName === 'usage:') { + // cleye format: usage line is inside the USAGE: section + const usageLine = sectionLines.find(l => l.trim().length > 0)?.trim(); + if (usageLine) { + usage = usageLine; + } } else { throw new Error(`Unknown CLI section: ${sectionName}`); }