diff --git a/.changeset/cli-discover-modules.md b/.changeset/cli-discover-modules.md index 751facdf1d..dac5f73f75 100644 --- a/.changeset/cli-discover-modules.md +++ b/.changeset/cli-discover-modules.md @@ -28,7 +28,7 @@ For fine-grained control you can instead install individual CLI modules: "@backstage/cli-module-auth": "backstage:^", "@backstage/cli-module-build": "backstage:^", "@backstage/cli-module-config": "backstage:^", - "@backstage/cli-module-create-github-app": "backstage:^", + "@backstage/cli-module-github": "backstage:^", "@backstage/cli-module-info": "backstage:^", "@backstage/cli-module-lint": "backstage:^", "@backstage/cli-module-maintenance": "backstage:^", diff --git a/.changeset/introduce-cli-modules.md b/.changeset/introduce-cli-modules.md index a69df9164b..7381742621 100644 --- a/.changeset/introduce-cli-modules.md +++ b/.changeset/introduce-cli-modules.md @@ -2,7 +2,7 @@ '@backstage/cli-module-auth': minor '@backstage/cli-module-build': minor '@backstage/cli-module-config': minor -'@backstage/cli-module-create-github-app': minor +'@backstage/cli-module-github': minor '@backstage/cli-module-info': minor '@backstage/cli-module-lint': minor '@backstage/cli-module-maintenance': minor diff --git a/package.json b/package.json index c443b8aa81..c89dcefce6 100644 --- a/package.json +++ b/package.json @@ -125,17 +125,7 @@ }, "devDependencies": { "@backstage/cli": "workspace:*", - "@backstage/cli-module-auth": "workspace:*", - "@backstage/cli-module-build": "workspace:*", - "@backstage/cli-module-config": "workspace:*", - "@backstage/cli-module-create-github-app": "workspace:*", - "@backstage/cli-module-info": "workspace:*", - "@backstage/cli-module-lint": "workspace:*", - "@backstage/cli-module-maintenance": "workspace:*", - "@backstage/cli-module-migrate": "workspace:*", - "@backstage/cli-module-new": "workspace:*", - "@backstage/cli-module-test-jest": "workspace:*", - "@backstage/cli-module-translations": "workspace:*", + "@backstage/cli-defaults": "workspace:*", "@backstage/codemods": "workspace:*", "@backstage/create-app": "workspace:*", "@backstage/e2e-test-utils": "workspace:*", diff --git a/packages/cli-defaults/README.md b/packages/cli-defaults/README.md index fa75c322df..2066aa1e35 100644 --- a/packages/cli-defaults/README.md +++ b/packages/cli-defaults/README.md @@ -4,19 +4,19 @@ The default set of CLI modules for the Backstage CLI. Installing this single pac ## Included Modules -| Module | Description | -| :--------------------------------------------------------------------------- | :--------------------------------------- | -| [`@backstage/cli-module-auth`](../cli-module-auth) | Authentication commands | -| [`@backstage/cli-module-build`](../cli-module-build) | Build, start, and packaging commands | -| [`@backstage/cli-module-config`](../cli-module-config) | Configuration inspection commands | -| [`@backstage/cli-module-create-github-app`](../cli-module-create-github-app) | GitHub App creation | -| [`@backstage/cli-module-info`](../cli-module-info) | Environment and dependency info | -| [`@backstage/cli-module-lint`](../cli-module-lint) | Linting commands | -| [`@backstage/cli-module-maintenance`](../cli-module-maintenance) | Repository maintenance commands | -| [`@backstage/cli-module-migrate`](../cli-module-migrate) | Migration and version management | -| [`@backstage/cli-module-new`](../cli-module-new) | Scaffolding for new plugins and packages | -| [`@backstage/cli-module-test-jest`](../cli-module-test-jest) | Jest-based testing commands | -| [`@backstage/cli-module-translations`](../cli-module-translations) | Translation management commands | +| Module | Description | +| :----------------------------------------------------------------- | :--------------------------------------- | +| [`@backstage/cli-module-auth`](../cli-module-auth) | Authentication commands | +| [`@backstage/cli-module-build`](../cli-module-build) | Build, start, and packaging commands | +| [`@backstage/cli-module-config`](../cli-module-config) | Configuration inspection commands | +| [`@backstage/cli-module-github`](../cli-module-github) | GitHub App creation | +| [`@backstage/cli-module-info`](../cli-module-info) | Environment and dependency info | +| [`@backstage/cli-module-lint`](../cli-module-lint) | Linting commands | +| [`@backstage/cli-module-maintenance`](../cli-module-maintenance) | Repository maintenance commands | +| [`@backstage/cli-module-migrate`](../cli-module-migrate) | Migration and version management | +| [`@backstage/cli-module-new`](../cli-module-new) | Scaffolding for new plugins and packages | +| [`@backstage/cli-module-test-jest`](../cli-module-test-jest) | Jest-based testing commands | +| [`@backstage/cli-module-translations`](../cli-module-translations) | Translation management commands | For fine-grained control over which CLI commands are available, you can install individual modules instead. diff --git a/packages/cli-defaults/package.json b/packages/cli-defaults/package.json index 587e54cfe9..8a065fd4d7 100644 --- a/packages/cli-defaults/package.json +++ b/packages/cli-defaults/package.json @@ -33,7 +33,7 @@ "@backstage/cli-module-auth": "workspace:^", "@backstage/cli-module-build": "workspace:^", "@backstage/cli-module-config": "workspace:^", - "@backstage/cli-module-create-github-app": "workspace:^", + "@backstage/cli-module-github": "workspace:^", "@backstage/cli-module-info": "workspace:^", "@backstage/cli-module-lint": "workspace:^", "@backstage/cli-module-maintenance": "workspace:^", diff --git a/packages/cli-defaults/src/index.ts b/packages/cli-defaults/src/index.ts index 0126d0c074..dd7aed0c70 100644 --- a/packages/cli-defaults/src/index.ts +++ b/packages/cli-defaults/src/index.ts @@ -16,7 +16,7 @@ import auth from '@backstage/cli-module-auth'; import build from '@backstage/cli-module-build'; import config from '@backstage/cli-module-config'; -import createGithubApp from '@backstage/cli-module-create-github-app'; +import github from '@backstage/cli-module-github'; import info from '@backstage/cli-module-info'; import lint from '@backstage/cli-module-lint'; import maintenance from '@backstage/cli-module-maintenance'; @@ -34,7 +34,7 @@ export default [ auth, build, config, - createGithubApp, + github, info, lint, maintenance, diff --git a/packages/cli-internal/src/InternalCommandNode.ts b/packages/cli-internal/src/InternalCommandNode.ts index bfa1f90baa..233e9128cb 100644 --- a/packages/cli-internal/src/InternalCommandNode.ts +++ b/packages/cli-internal/src/InternalCommandNode.ts @@ -53,3 +53,17 @@ export const OpaqueCommandLeafNode = OpaqueType.create<{ type: '@backstage/CommandLeafNode', versions: ['v1'], }); + +/** + * Checks whether a command node should be hidden from help output. + * Leaf nodes are hidden if they are deprecated or experimental. + * Tree nodes are hidden if all of their children are hidden. + */ +export function isCommandNodeHidden(node: CommandNode): boolean { + if (OpaqueCommandLeafNode.isType(node)) { + const { command } = OpaqueCommandLeafNode.toInternal(node); + return !!command.deprecated || !!command.experimental; + } + const { children } = OpaqueCommandTreeNode.toInternal(node); + return children.every(child => isCommandNodeHidden(child)); +} diff --git a/packages/cli-internal/src/index.ts b/packages/cli-internal/src/index.ts index 68b5affe64..0e69d45032 100644 --- a/packages/cli-internal/src/index.ts +++ b/packages/cli-internal/src/index.ts @@ -23,4 +23,5 @@ export type { export { OpaqueCommandTreeNode, OpaqueCommandLeafNode, + isCommandNodeHidden, } from './InternalCommandNode'; diff --git a/packages/cli-module-auth/bin/backstage-cli-module-auth b/packages/cli-module-auth/bin/backstage-cli-module-auth index 533974f6a9..885c06db9f 100755 --- a/packages/cli-module-auth/bin/backstage-cli-module-auth +++ b/packages/cli-module-auth/bin/backstage-cli-module-auth @@ -28,6 +28,6 @@ if (!isLocal) { const pkg = require('../package.json'); runCliModule({ module: cliModule, name: pkg.name, version: pkg.version }); } else { - require('@backstage/cli/config/nodeTransform.cjs'); + require('@backstage/cli-node/config/nodeTransform.cjs'); require('../src/cli'); } diff --git a/packages/cli-module-build/bin/backstage-cli-module-build b/packages/cli-module-build/bin/backstage-cli-module-build index 533974f6a9..885c06db9f 100755 --- a/packages/cli-module-build/bin/backstage-cli-module-build +++ b/packages/cli-module-build/bin/backstage-cli-module-build @@ -28,6 +28,6 @@ if (!isLocal) { const pkg = require('../package.json'); runCliModule({ module: cliModule, name: pkg.name, version: pkg.version }); } else { - require('@backstage/cli/config/nodeTransform.cjs'); + require('@backstage/cli-node/config/nodeTransform.cjs'); require('../src/cli'); } diff --git a/packages/cli-module-build/package.json b/packages/cli-module-build/package.json index 27f4fd3903..d13fa4bac0 100644 --- a/packages/cli-module-build/package.json +++ b/packages/cli-module-build/package.json @@ -72,7 +72,6 @@ "node-stdlib-browser": "^1.3.1", "npm-packlist": "^5.0.0", "p-queue": "^6.6.2", - "pirates": "^4.0.6", "postcss": "^8.1.0", "postcss-import": "^16.1.0", "process": "^0.11.10", diff --git a/packages/cli-module-build/src/lib/runner/runBackend.ts b/packages/cli-module-build/src/lib/runner/runBackend.ts index 73c3fe08c7..86c249e8be 100644 --- a/packages/cli-module-build/src/lib/runner/runBackend.ts +++ b/packages/cli-module-build/src/lib/runner/runBackend.ts @@ -21,16 +21,15 @@ import { IpcServer, ServerDataStore } from '../ipc'; import debounce from 'lodash/debounce'; import { fileURLToPath } from 'node:url'; import { isAbsolute as isAbsolutePath } from 'node:path'; -import { findOwnPaths, targetPaths } from '@backstage/cli-common'; +import { targetPaths } from '@backstage/cli-common'; import spawn from 'cross-spawn'; const loaderArgs = [ '--enable-source-maps', '--require', - /* eslint-disable-next-line no-restricted-syntax */ - findOwnPaths(__dirname).resolve('config/nodeTransform.cjs'), - // TODO: Support modules, although there's currently no way to load them since import() is transpiled tp require() + require.resolve('@backstage/cli-node/config/nodeTransform.cjs'), + // TODO: Support modules, although there's currently no way to load them since import() is transpiled to require() ]; export type RunBackendOptions = { diff --git a/packages/cli-module-build/src/tests/transforms/transforms.test.ts b/packages/cli-module-build/src/tests/transforms/transforms.test.ts index 40f40fac2d..71ee03df76 100644 --- a/packages/cli-module-build/src/tests/transforms/transforms.test.ts +++ b/packages/cli-module-build/src/tests/transforms/transforms.test.ts @@ -16,7 +16,6 @@ import { execFileSync } from 'node:child_process'; import { resolve as resolvePath } from 'node:path'; -import { findOwnPaths } from '@backstage/cli-common'; import { Output, buildPackage } from '../../lib/builder'; const exportValues = { @@ -56,8 +55,7 @@ function loadFixture(fixture: string) { 'node', [ '--import', - /* eslint-disable-next-line no-restricted-syntax */ - findOwnPaths(__dirname).resolve('config/nodeTransform.cjs'), + require.resolve('@backstage/cli-node/config/nodeTransform.cjs'), resolvePath(__dirname, `__fixtures__/${fixture}`), ], { encoding: 'utf8' }, diff --git a/packages/cli-module-config/bin/backstage-cli-module-config b/packages/cli-module-config/bin/backstage-cli-module-config index 533974f6a9..885c06db9f 100755 --- a/packages/cli-module-config/bin/backstage-cli-module-config +++ b/packages/cli-module-config/bin/backstage-cli-module-config @@ -28,6 +28,6 @@ if (!isLocal) { const pkg = require('../package.json'); runCliModule({ module: cliModule, name: pkg.name, version: pkg.version }); } else { - require('@backstage/cli/config/nodeTransform.cjs'); + require('@backstage/cli-node/config/nodeTransform.cjs'); require('../src/cli'); } diff --git a/packages/cli-module-create-github-app/cli-report.md b/packages/cli-module-create-github-app/cli-report.md deleted file mode 100644 index 7a7f7bb3a2..0000000000 --- a/packages/cli-module-create-github-app/cli-report.md +++ /dev/null @@ -1,26 +0,0 @@ -## CLI Report file for "@backstage/cli-module-create-github-app" - -> Do not edit this file. It is a report generated by `yarn build:api-reports` - -### `backstage-cli-module-create-github-app` - -``` -Usage: @backstage/cli-module-create-github-app [options] [command] - -Options: - -V, --version - -h, --help - -Commands: - create-github-app - help [command] -``` - -### `backstage-cli-module-create-github-app create-github-app` - -``` -Usage: @backstage/cli-module-create-github-app create-github-app - -Options: - -h, --help -``` diff --git a/packages/cli-module-create-github-app/.eslintrc.js b/packages/cli-module-github/.eslintrc.js similarity index 100% rename from packages/cli-module-create-github-app/.eslintrc.js rename to packages/cli-module-github/.eslintrc.js diff --git a/packages/cli-module-create-github-app/README.md b/packages/cli-module-github/README.md similarity index 92% rename from packages/cli-module-create-github-app/README.md rename to packages/cli-module-github/README.md index b10272ab02..6c38376901 100644 --- a/packages/cli-module-create-github-app/README.md +++ b/packages/cli-module-github/README.md @@ -1,4 +1,4 @@ -# @backstage/cli-module-create-github-app +# @backstage/cli-module-github CLI module that provides the `create-github-app` command for the Backstage CLI, used to create a new GitHub App in your organization for use with Backstage. diff --git a/packages/cli-module-create-github-app/bin/backstage-cli-module-create-github-app b/packages/cli-module-github/bin/backstage-cli-module-github similarity index 94% rename from packages/cli-module-create-github-app/bin/backstage-cli-module-create-github-app rename to packages/cli-module-github/bin/backstage-cli-module-github index 533974f6a9..885c06db9f 100755 --- a/packages/cli-module-create-github-app/bin/backstage-cli-module-create-github-app +++ b/packages/cli-module-github/bin/backstage-cli-module-github @@ -28,6 +28,6 @@ if (!isLocal) { const pkg = require('../package.json'); runCliModule({ module: cliModule, name: pkg.name, version: pkg.version }); } else { - require('@backstage/cli/config/nodeTransform.cjs'); + require('@backstage/cli-node/config/nodeTransform.cjs'); require('../src/cli'); } diff --git a/packages/cli-module-create-github-app/catalog-info.yaml b/packages/cli-module-github/catalog-info.yaml similarity index 66% rename from packages/cli-module-create-github-app/catalog-info.yaml rename to packages/cli-module-github/catalog-info.yaml index 66e59c5a27..b694da6f17 100644 --- a/packages/cli-module-create-github-app/catalog-info.yaml +++ b/packages/cli-module-github/catalog-info.yaml @@ -1,8 +1,8 @@ apiVersion: backstage.io/v1alpha1 kind: Component metadata: - name: backstage-cli-module-create-github-app - title: '@backstage/cli-module-create-github-app' + name: backstage-cli-module-github + title: '@backstage/cli-module-github' description: CLI module for Backstage CLI spec: lifecycle: experimental diff --git a/packages/cli-module-github/cli-report.md b/packages/cli-module-github/cli-report.md new file mode 100644 index 0000000000..c606ac5988 --- /dev/null +++ b/packages/cli-module-github/cli-report.md @@ -0,0 +1,26 @@ +## CLI Report file for "@backstage/cli-module-github" + +> Do not edit this file. It is a report generated by `yarn build:api-reports` + +### `backstage-cli-module-github` + +``` +Usage: @backstage/cli-module-github [options] [command] + +Options: + -V, --version + -h, --help + +Commands: + create-github-app + help [command] +``` + +### `backstage-cli-module-github create-github-app` + +``` +Usage: @backstage/cli-module-github create-github-app + +Options: + -h, --help +``` diff --git a/packages/cli-module-create-github-app/package.json b/packages/cli-module-github/package.json similarity index 88% rename from packages/cli-module-create-github-app/package.json rename to packages/cli-module-github/package.json index 2196abc62e..1e8ca4fe6a 100644 --- a/packages/cli-module-create-github-app/package.json +++ b/packages/cli-module-github/package.json @@ -1,5 +1,5 @@ { - "name": "@backstage/cli-module-create-github-app", + "name": "@backstage/cli-module-github", "version": "0.0.0", "description": "CLI module for Backstage CLI", "backstage": { @@ -14,7 +14,7 @@ "repository": { "type": "git", "url": "https://github.com/backstage/backstage", - "directory": "packages/cli-module-create-github-app" + "directory": "packages/cli-module-github" }, "license": "Apache-2.0", "main": "src/index.ts", @@ -48,5 +48,5 @@ "@types/express": "^4.17.6", "@types/fs-extra": "^11.0.0" }, - "bin": "bin/backstage-cli-module-create-github-app" + "bin": "bin/backstage-cli-module-github" } diff --git a/packages/cli-module-create-github-app/report.api.md b/packages/cli-module-github/report.api.md similarity index 81% rename from packages/cli-module-create-github-app/report.api.md rename to packages/cli-module-github/report.api.md index 16ff642c69..c389a88b5f 100644 --- a/packages/cli-module-create-github-app/report.api.md +++ b/packages/cli-module-github/report.api.md @@ -1,4 +1,4 @@ -## API Report File for "@backstage/cli-module-create-github-app" +## API Report File for "@backstage/cli-module-github" > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). diff --git a/packages/cli-module-create-github-app/src/cli.ts b/packages/cli-module-github/src/cli.ts similarity index 100% rename from packages/cli-module-create-github-app/src/cli.ts rename to packages/cli-module-github/src/cli.ts diff --git a/packages/cli-module-create-github-app/src/commands/create-github-app/GithubCreateAppServer.ts b/packages/cli-module-github/src/commands/create-github-app/GithubCreateAppServer.ts similarity index 100% rename from packages/cli-module-create-github-app/src/commands/create-github-app/GithubCreateAppServer.ts rename to packages/cli-module-github/src/commands/create-github-app/GithubCreateAppServer.ts diff --git a/packages/cli-module-create-github-app/src/commands/create-github-app/index.ts b/packages/cli-module-github/src/commands/create-github-app/index.ts similarity index 100% rename from packages/cli-module-create-github-app/src/commands/create-github-app/index.ts rename to packages/cli-module-github/src/commands/create-github-app/index.ts diff --git a/packages/cli-module-create-github-app/src/index.ts b/packages/cli-module-github/src/index.ts similarity index 100% rename from packages/cli-module-create-github-app/src/index.ts rename to packages/cli-module-github/src/index.ts diff --git a/packages/cli-module-info/bin/backstage-cli-module-info b/packages/cli-module-info/bin/backstage-cli-module-info index 533974f6a9..885c06db9f 100755 --- a/packages/cli-module-info/bin/backstage-cli-module-info +++ b/packages/cli-module-info/bin/backstage-cli-module-info @@ -28,6 +28,6 @@ if (!isLocal) { const pkg = require('../package.json'); runCliModule({ module: cliModule, name: pkg.name, version: pkg.version }); } else { - require('@backstage/cli/config/nodeTransform.cjs'); + require('@backstage/cli-node/config/nodeTransform.cjs'); require('../src/cli'); } diff --git a/packages/cli-module-lint/bin/backstage-cli-module-lint b/packages/cli-module-lint/bin/backstage-cli-module-lint index 533974f6a9..885c06db9f 100755 --- a/packages/cli-module-lint/bin/backstage-cli-module-lint +++ b/packages/cli-module-lint/bin/backstage-cli-module-lint @@ -28,6 +28,6 @@ if (!isLocal) { const pkg = require('../package.json'); runCliModule({ module: cliModule, name: pkg.name, version: pkg.version }); } else { - require('@backstage/cli/config/nodeTransform.cjs'); + require('@backstage/cli-node/config/nodeTransform.cjs'); require('../src/cli'); } diff --git a/packages/cli-module-maintenance/bin/backstage-cli-module-maintenance b/packages/cli-module-maintenance/bin/backstage-cli-module-maintenance index 533974f6a9..885c06db9f 100755 --- a/packages/cli-module-maintenance/bin/backstage-cli-module-maintenance +++ b/packages/cli-module-maintenance/bin/backstage-cli-module-maintenance @@ -28,6 +28,6 @@ if (!isLocal) { const pkg = require('../package.json'); runCliModule({ module: cliModule, name: pkg.name, version: pkg.version }); } else { - require('@backstage/cli/config/nodeTransform.cjs'); + require('@backstage/cli-node/config/nodeTransform.cjs'); require('../src/cli'); } diff --git a/packages/cli-module-migrate/bin/backstage-cli-module-migrate b/packages/cli-module-migrate/bin/backstage-cli-module-migrate index 533974f6a9..885c06db9f 100755 --- a/packages/cli-module-migrate/bin/backstage-cli-module-migrate +++ b/packages/cli-module-migrate/bin/backstage-cli-module-migrate @@ -28,6 +28,6 @@ if (!isLocal) { const pkg = require('../package.json'); runCliModule({ module: cliModule, name: pkg.name, version: pkg.version }); } else { - require('@backstage/cli/config/nodeTransform.cjs'); + require('@backstage/cli-node/config/nodeTransform.cjs'); require('../src/cli'); } diff --git a/packages/cli-module-new/bin/backstage-cli-module-new b/packages/cli-module-new/bin/backstage-cli-module-new index 533974f6a9..885c06db9f 100755 --- a/packages/cli-module-new/bin/backstage-cli-module-new +++ b/packages/cli-module-new/bin/backstage-cli-module-new @@ -28,6 +28,6 @@ if (!isLocal) { const pkg = require('../package.json'); runCliModule({ module: cliModule, name: pkg.name, version: pkg.version }); } else { - require('@backstage/cli/config/nodeTransform.cjs'); + require('@backstage/cli-node/config/nodeTransform.cjs'); require('../src/cli'); } diff --git a/packages/cli-module-test-jest/bin/backstage-cli-module-test-jest b/packages/cli-module-test-jest/bin/backstage-cli-module-test-jest index 533974f6a9..885c06db9f 100755 --- a/packages/cli-module-test-jest/bin/backstage-cli-module-test-jest +++ b/packages/cli-module-test-jest/bin/backstage-cli-module-test-jest @@ -28,6 +28,6 @@ if (!isLocal) { const pkg = require('../package.json'); runCliModule({ module: cliModule, name: pkg.name, version: pkg.version }); } else { - require('@backstage/cli/config/nodeTransform.cjs'); + require('@backstage/cli-node/config/nodeTransform.cjs'); require('../src/cli'); } diff --git a/packages/cli-module-translations/bin/backstage-cli-module-translations b/packages/cli-module-translations/bin/backstage-cli-module-translations index 533974f6a9..885c06db9f 100755 --- a/packages/cli-module-translations/bin/backstage-cli-module-translations +++ b/packages/cli-module-translations/bin/backstage-cli-module-translations @@ -28,6 +28,6 @@ if (!isLocal) { const pkg = require('../package.json'); runCliModule({ module: cliModule, name: pkg.name, version: pkg.version }); } else { - require('@backstage/cli/config/nodeTransform.cjs'); + require('@backstage/cli-node/config/nodeTransform.cjs'); require('../src/cli'); } diff --git a/packages/cli-node/.eslintrc.js b/packages/cli-node/.eslintrc.js index e2a53a6ad2..7e7c302633 100644 --- a/packages/cli-node/.eslintrc.js +++ b/packages/cli-node/.eslintrc.js @@ -1 +1,19 @@ -module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); +/* + * Copyright 2026 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +module.exports = { + ...require('@backstage/cli/config/eslint-factory')(__dirname), + ignorePatterns: ['config/**'], +}; diff --git a/packages/cli-module-build/config/nodeTransform.cjs b/packages/cli-node/config/nodeTransform.cjs similarity index 100% rename from packages/cli-module-build/config/nodeTransform.cjs rename to packages/cli-node/config/nodeTransform.cjs diff --git a/packages/cli-module-build/config/nodeTransformHooks.mjs b/packages/cli-node/config/nodeTransformHooks.mjs similarity index 100% rename from packages/cli-module-build/config/nodeTransformHooks.mjs rename to packages/cli-node/config/nodeTransformHooks.mjs diff --git a/packages/cli-node/package.json b/packages/cli-node/package.json index 95322ad2f0..e266088176 100644 --- a/packages/cli-node/package.json +++ b/packages/cli-node/package.json @@ -20,7 +20,8 @@ "main": "src/index.ts", "types": "src/index.ts", "files": [ - "dist" + "dist", + "config" ], "scripts": { "build": "backstage-cli package build", @@ -35,11 +36,13 @@ "@backstage/errors": "workspace:^", "@backstage/types": "workspace:^", "@manypkg/get-packages": "^1.1.3", + "@swc/core": "^1.15.6", "@yarnpkg/lockfile": "^1.1.0", "@yarnpkg/parsers": "^3.0.0", "chalk": "^4.0.0", "commander": "^12.0.0", "fs-extra": "^11.2.0", + "pirates": "^4.0.6", "semver": "^7.5.3", "yaml": "^2.0.0", "zod": "^3.25.76" diff --git a/packages/cli-node/src/cli-module/createCliModule.ts b/packages/cli-node/src/cli-module/createCliModule.ts index 7d52e9bf43..b2facc3a67 100644 --- a/packages/cli-node/src/cli-module/createCliModule.ts +++ b/packages/cli-node/src/cli-module/createCliModule.ts @@ -62,8 +62,8 @@ export function createCliModule(options: { } const commands: CliCommand[] = []; - const commandsPromise = options - .init({ addCommand: command => commands.push(command) }) + const commandsPromise = Promise.resolve() + .then(() => options.init({ addCommand: command => commands.push(command) })) .then(() => commands); return OpaqueCliModule.createInstance('v1', { diff --git a/packages/cli-node/src/cli-module/runCliModule.ts b/packages/cli-node/src/cli-module/runCliModule.ts index 84893f0cac..0dc40e4c33 100644 --- a/packages/cli-node/src/cli-module/runCliModule.ts +++ b/packages/cli-node/src/cli-module/runCliModule.ts @@ -18,6 +18,7 @@ import { OpaqueCliModule, OpaqueCommandTreeNode, OpaqueCommandLeafNode, + isCommandNodeHidden, } from '@internal/cli'; import type { CommandNode } from '@internal/cli'; import { Command } from 'commander'; @@ -25,15 +26,6 @@ import chalk from 'chalk'; import { isError, stringifyError } from '@backstage/errors'; import type { CliModule, CliCommand } from './types'; -function isCommandHidden(node: CommandNode): boolean { - if (OpaqueCommandLeafNode.isType(node)) { - const { command } = OpaqueCommandLeafNode.toInternal(node); - return !!command.deprecated || !!command.experimental; - } - const { children } = OpaqueCommandTreeNode.toInternal(node); - return children.every(child => isCommandHidden(child)); -} - function buildCommandGraph(commands: ReadonlyArray): CommandNode[] { const graph: CommandNode[] = []; @@ -70,13 +62,11 @@ function buildCommandGraph(commands: ReadonlyArray): CommandNode[] { } function exitWithError(error: unknown): never { - if (!isError(error)) { - process.stderr.write(`\n${chalk.red(stringifyError(error))}\n\n`); - process.exit(1); - } process.stderr.write(`\n${chalk.red(stringifyError(error))}\n\n`); process.exit( - 'code' in error && typeof error.code === 'number' ? error.code : 1, + isError(error) && 'code' in error && typeof error.code === 'number' + ? error.code + : 1, ); } @@ -94,7 +84,7 @@ function registerCommands( const internal = OpaqueCommandTreeNode.toInternal(node); const treeParser = argParser .command(`${internal.name} [command]`, { - hidden: isCommandHidden(node), + hidden: isCommandNodeHidden(node), }) .description(internal.name); diff --git a/packages/cli/config/nodeTransform.cjs b/packages/cli/config/nodeTransform.cjs index 83815ebea9..c6866b2964 100644 --- a/packages/cli/config/nodeTransform.cjs +++ b/packages/cli/config/nodeTransform.cjs @@ -15,11 +15,11 @@ */ try { - require('@backstage/cli-module-build/config/nodeTransform.cjs'); + require('@backstage/cli-node/config/nodeTransform.cjs'); } catch (e) { if (e.code === 'MODULE_NOT_FOUND') { throw new Error( - '@backstage/cli-module-build is required to use the node transform. ' + + '@backstage/cli-node is required to use the node transform. ' + 'Please install it as a dependency.', ); } diff --git a/packages/cli/config/nodeTransformHooks.mjs b/packages/cli/config/nodeTransformHooks.mjs index 9fe9b327b5..274e24ed39 100644 --- a/packages/cli/config/nodeTransformHooks.mjs +++ b/packages/cli/config/nodeTransformHooks.mjs @@ -17,4 +17,4 @@ export { resolve, load, -} from '@backstage/cli-module-build/config/nodeTransformHooks.mjs'; +} from '@backstage/cli-node/config/nodeTransformHooks.mjs'; diff --git a/packages/cli/src/wiring/CliInitializer.ts b/packages/cli/src/wiring/CliInitializer.ts index e2c46cf99b..adbdfbe517 100644 --- a/packages/cli/src/wiring/CliInitializer.ts +++ b/packages/cli/src/wiring/CliInitializer.ts @@ -19,8 +19,8 @@ import { OpaqueCliModule, OpaqueCommandTreeNode, OpaqueCommandLeafNode, + isCommandNodeHidden, } from '@internal/cli'; -import type { CommandNode } from '@internal/cli'; import type { CliModule } from '@backstage/cli-node'; import { Command } from 'commander'; import { version } from './version'; @@ -29,15 +29,6 @@ import { exitWithError } from './errors'; import { ForwardedError } from '@backstage/errors'; import { isPromise } from 'node:util/types'; -function isNodeHidden(node: CommandNode): boolean { - if (OpaqueCommandLeafNode.isType(node)) { - const { command } = OpaqueCommandLeafNode.toInternal(node); - return !!command.deprecated || !!command.experimental; - } - const { children } = OpaqueCommandTreeNode.toInternal(node); - return children.every(child => isNodeHidden(child)); -} - type UninitializedFeature = | CliModule | CliModule[] @@ -45,6 +36,12 @@ type UninitializedFeature = interface TaggedFeature { feature: CliModule; + /** + * Whether this module was sourced from an array (e.g. cli-defaults). + * Array-sourced modules are silently skipped when any of their commands + * overlap with an individually-added module, allowing explicit module + * additions to take precedence without causing conflicts. + */ fromArray: boolean; } @@ -136,7 +133,7 @@ export class CliInitializer { const internal = OpaqueCommandTreeNode.toInternal(node); const treeParser = argParser .command(`${internal.name} [command]`, { - hidden: isNodeHidden(node), + hidden: isCommandNodeHidden(node), }) .description(internal.name); diff --git a/packages/create-app/src/lib/tasks.test.ts b/packages/create-app/src/lib/tasks.test.ts index ff2f3eb4d6..6416681b27 100644 --- a/packages/create-app/src/lib/tasks.test.ts +++ b/packages/create-app/src/lib/tasks.test.ts @@ -51,17 +51,6 @@ jest.mock('./versions', () => ({ root: '1.2.3', '@backstage/cli': '1.0.0', '@backstage/cli-defaults': '1.0.0', - '@backstage/cli-module-auth': '1.0.0', - '@backstage/cli-module-build': '1.0.0', - '@backstage/cli-module-config': '1.0.0', - '@backstage/cli-module-create-github-app': '1.0.0', - '@backstage/cli-module-info': '1.0.0', - '@backstage/cli-module-lint': '1.0.0', - '@backstage/cli-module-maintenance': '1.0.0', - '@backstage/cli-module-migrate': '1.0.0', - '@backstage/cli-module-new': '1.0.0', - '@backstage/cli-module-test-jest': '1.0.0', - '@backstage/cli-module-translations': '1.0.0', '@backstage/backend-defaults': '1.0.0', '@backstage/backend-tasks': '1.0.0', '@backstage/catalog-model': '1.0.0', diff --git a/packages/create-app/src/lib/versions.ts b/packages/create-app/src/lib/versions.ts index e770b88f3f..006dd6d7b8 100644 --- a/packages/create-app/src/lib/versions.ts +++ b/packages/create-app/src/lib/versions.ts @@ -39,17 +39,6 @@ import { version as catalogClient } from '../../../catalog-client/package.json'; import { version as catalogModel } from '../../../catalog-model/package.json'; import { version as cli } from '../../../cli/package.json'; import { version as cliDefaults } from '../../../cli-defaults/package.json'; -import { version as cliModuleAuth } from '../../../cli-module-auth/package.json'; -import { version as cliModuleBuild } from '../../../cli-module-build/package.json'; -import { version as cliModuleConfig } from '../../../cli-module-config/package.json'; -import { version as cliModuleCreateGithubApp } from '../../../cli-module-create-github-app/package.json'; -import { version as cliModuleInfo } from '../../../cli-module-info/package.json'; -import { version as cliModuleLint } from '../../../cli-module-lint/package.json'; -import { version as cliModuleMaintenance } from '../../../cli-module-maintenance/package.json'; -import { version as cliModuleMigrate } from '../../../cli-module-migrate/package.json'; -import { version as cliModuleNew } from '../../../cli-module-new/package.json'; -import { version as cliModuleTestJest } from '../../../cli-module-test-jest/package.json'; -import { version as cliModuleTranslations } from '../../../cli-module-translations/package.json'; import { version as config } from '../../../config/package.json'; import { version as coreAppApi } from '../../../core-app-api/package.json'; import { version as coreCompatApi } from '../../../core-compat-api/package.json'; @@ -120,17 +109,6 @@ export const packageVersions = { '@backstage/catalog-model': catalogModel, '@backstage/cli': cli, '@backstage/cli-defaults': cliDefaults, - '@backstage/cli-module-auth': cliModuleAuth, - '@backstage/cli-module-build': cliModuleBuild, - '@backstage/cli-module-config': cliModuleConfig, - '@backstage/cli-module-create-github-app': cliModuleCreateGithubApp, - '@backstage/cli-module-info': cliModuleInfo, - '@backstage/cli-module-lint': cliModuleLint, - '@backstage/cli-module-maintenance': cliModuleMaintenance, - '@backstage/cli-module-migrate': cliModuleMigrate, - '@backstage/cli-module-new': cliModuleNew, - '@backstage/cli-module-test-jest': cliModuleTestJest, - '@backstage/cli-module-translations': cliModuleTranslations, '@backstage/config': config, '@backstage/core-app-api': coreAppApi, '@backstage/core-compat-api': coreCompatApi, diff --git a/packages/create-app/templates/next-app/package.json.hbs b/packages/create-app/templates/next-app/package.json.hbs index 110ebc160c..49436f5fcf 100644 --- a/packages/create-app/templates/next-app/package.json.hbs +++ b/packages/create-app/templates/next-app/package.json.hbs @@ -50,17 +50,7 @@ ], "devDependencies": { "@backstage/cli": "^{{version '@backstage/cli'}}", - "@backstage/cli-module-auth": "^{{version '@backstage/cli-module-auth'}}", - "@backstage/cli-module-build": "^{{version '@backstage/cli-module-build'}}", - "@backstage/cli-module-config": "^{{version '@backstage/cli-module-config'}}", - "@backstage/cli-module-create-github-app": "^{{version '@backstage/cli-module-create-github-app'}}", - "@backstage/cli-module-info": "^{{version '@backstage/cli-module-info'}}", - "@backstage/cli-module-lint": "^{{version '@backstage/cli-module-lint'}}", - "@backstage/cli-module-maintenance": "^{{version '@backstage/cli-module-maintenance'}}", - "@backstage/cli-module-migrate": "^{{version '@backstage/cli-module-migrate'}}", - "@backstage/cli-module-new": "^{{version '@backstage/cli-module-new'}}", - "@backstage/cli-module-test-jest": "^{{version '@backstage/cli-module-test-jest'}}", - "@backstage/cli-module-translations": "^{{version '@backstage/cli-module-translations'}}", + "@backstage/cli-defaults": "^{{version '@backstage/cli-defaults'}}", "@backstage/e2e-test-utils": "^{{version '@backstage/e2e-test-utils'}}", "@jest/environment-jsdom-abstract": "^30.0.0", "@playwright/test": "^1.32.3", 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 7dfbba51ec..ce207489a7 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 @@ -132,6 +132,11 @@ export async function runCliExtraction({ const pkgJson = await fs.readJson(resolvePath(fullDir, 'package.json')); if (!pkgJson.bin) { + if (pkgJson.backstage?.role === 'cli') { + throw new Error( + `CLI package ${pkgJson.name} is missing a "bin" field in its package.json`, + ); + } continue; } diff --git a/yarn.lock b/yarn.lock index 1c4ba53f5e..ff47745d26 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2801,7 +2801,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/cli-defaults@workspace:^, @backstage/cli-defaults@workspace:packages/cli-defaults": +"@backstage/cli-defaults@workspace:*, @backstage/cli-defaults@workspace:^, @backstage/cli-defaults@workspace:packages/cli-defaults": version: 0.0.0-use.local resolution: "@backstage/cli-defaults@workspace:packages/cli-defaults" dependencies: @@ -2809,7 +2809,7 @@ __metadata: "@backstage/cli-module-auth": "workspace:^" "@backstage/cli-module-build": "workspace:^" "@backstage/cli-module-config": "workspace:^" - "@backstage/cli-module-create-github-app": "workspace:^" + "@backstage/cli-module-github": "workspace:^" "@backstage/cli-module-info": "workspace:^" "@backstage/cli-module-lint": "workspace:^" "@backstage/cli-module-maintenance": "workspace:^" @@ -2820,7 +2820,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/cli-module-auth@workspace:*, @backstage/cli-module-auth@workspace:^, @backstage/cli-module-auth@workspace:packages/cli-module-auth": +"@backstage/cli-module-auth@workspace:^, @backstage/cli-module-auth@workspace:packages/cli-module-auth": version: 0.0.0-use.local resolution: "@backstage/cli-module-auth@workspace:packages/cli-module-auth" dependencies: @@ -2847,7 +2847,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/cli-module-build@workspace:*, @backstage/cli-module-build@workspace:^, @backstage/cli-module-build@workspace:packages/cli-module-build": +"@backstage/cli-module-build@workspace:^, @backstage/cli-module-build@workspace:packages/cli-module-build": version: 0.0.0-use.local resolution: "@backstage/cli-module-build@workspace:packages/cli-module-build" dependencies: @@ -2894,7 +2894,6 @@ __metadata: node-stdlib-browser: "npm:^1.3.1" npm-packlist: "npm:^5.0.0" p-queue: "npm:^6.6.2" - pirates: "npm:^4.0.6" postcss: "npm:^8.1.0" postcss-import: "npm:^16.1.0" process: "npm:^0.11.10" @@ -2922,7 +2921,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/cli-module-config@workspace:*, @backstage/cli-module-config@workspace:^, @backstage/cli-module-config@workspace:packages/cli-module-config": +"@backstage/cli-module-config@workspace:^, @backstage/cli-module-config@workspace:packages/cli-module-config": version: 0.0.0-use.local resolution: "@backstage/cli-module-config@workspace:packages/cli-module-config" dependencies: @@ -2944,9 +2943,9 @@ __metadata: languageName: unknown linkType: soft -"@backstage/cli-module-create-github-app@workspace:*, @backstage/cli-module-create-github-app@workspace:^, @backstage/cli-module-create-github-app@workspace:packages/cli-module-create-github-app": +"@backstage/cli-module-github@workspace:^, @backstage/cli-module-github@workspace:packages/cli-module-github": version: 0.0.0-use.local - resolution: "@backstage/cli-module-create-github-app@workspace:packages/cli-module-create-github-app" + resolution: "@backstage/cli-module-github@workspace:packages/cli-module-github" dependencies: "@backstage/cli": "workspace:^" "@backstage/cli-common": "workspace:^" @@ -2962,11 +2961,11 @@ __metadata: react-dev-utils: "npm:^12.0.0-next.60" yaml: "npm:^2.0.0" bin: - cli-module-create-github-app: bin/backstage-cli-module-create-github-app + cli-module-github: bin/backstage-cli-module-github languageName: unknown linkType: soft -"@backstage/cli-module-info@workspace:*, @backstage/cli-module-info@workspace:^, @backstage/cli-module-info@workspace:packages/cli-module-info": +"@backstage/cli-module-info@workspace:^, @backstage/cli-module-info@workspace:packages/cli-module-info": version: 0.0.0-use.local resolution: "@backstage/cli-module-info@workspace:packages/cli-module-info" dependencies: @@ -2982,7 +2981,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/cli-module-lint@workspace:*, @backstage/cli-module-lint@workspace:^, @backstage/cli-module-lint@workspace:packages/cli-module-lint": +"@backstage/cli-module-lint@workspace:^, @backstage/cli-module-lint@workspace:packages/cli-module-lint": version: 0.0.0-use.local resolution: "@backstage/cli-module-lint@workspace:packages/cli-module-lint" dependencies: @@ -3003,7 +3002,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/cli-module-maintenance@workspace:*, @backstage/cli-module-maintenance@workspace:^, @backstage/cli-module-maintenance@workspace:packages/cli-module-maintenance": +"@backstage/cli-module-maintenance@workspace:^, @backstage/cli-module-maintenance@workspace:packages/cli-module-maintenance": version: 0.0.0-use.local resolution: "@backstage/cli-module-maintenance@workspace:packages/cli-module-maintenance" dependencies: @@ -3020,7 +3019,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/cli-module-migrate@workspace:*, @backstage/cli-module-migrate@workspace:^, @backstage/cli-module-migrate@workspace:packages/cli-module-migrate": +"@backstage/cli-module-migrate@workspace:^, @backstage/cli-module-migrate@workspace:packages/cli-module-migrate": version: 0.0.0-use.local resolution: "@backstage/cli-module-migrate@workspace:packages/cli-module-migrate" dependencies: @@ -3047,7 +3046,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/cli-module-new@workspace:*, @backstage/cli-module-new@workspace:^, @backstage/cli-module-new@workspace:packages/cli-module-new": +"@backstage/cli-module-new@workspace:^, @backstage/cli-module-new@workspace:packages/cli-module-new": version: 0.0.0-use.local resolution: "@backstage/cli-module-new@workspace:packages/cli-module-new" dependencies: @@ -3079,7 +3078,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/cli-module-test-jest@workspace:*, @backstage/cli-module-test-jest@workspace:^, @backstage/cli-module-test-jest@workspace:packages/cli-module-test-jest": +"@backstage/cli-module-test-jest@workspace:^, @backstage/cli-module-test-jest@workspace:packages/cli-module-test-jest": version: 0.0.0-use.local resolution: "@backstage/cli-module-test-jest@workspace:packages/cli-module-test-jest" dependencies: @@ -3112,7 +3111,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/cli-module-translations@workspace:*, @backstage/cli-module-translations@workspace:^, @backstage/cli-module-translations@workspace:packages/cli-module-translations": +"@backstage/cli-module-translations@workspace:^, @backstage/cli-module-translations@workspace:packages/cli-module-translations": version: 0.0.0-use.local resolution: "@backstage/cli-module-translations@workspace:packages/cli-module-translations" dependencies: @@ -3139,12 +3138,14 @@ __metadata: "@backstage/test-utils": "workspace:^" "@backstage/types": "workspace:^" "@manypkg/get-packages": "npm:^1.1.3" + "@swc/core": "npm:^1.15.6" "@types/yarnpkg__lockfile": "npm:^1.1.4" "@yarnpkg/lockfile": "npm:^1.1.0" "@yarnpkg/parsers": "npm:^3.0.0" chalk: "npm:^4.0.0" commander: "npm:^12.0.0" fs-extra: "npm:^11.2.0" + pirates: "npm:^4.0.6" semver: "npm:^7.5.3" yaml: "npm:^2.0.0" zod: "npm:^3.25.76" @@ -45365,17 +45366,7 @@ __metadata: resolution: "root@workspace:." dependencies: "@backstage/cli": "workspace:*" - "@backstage/cli-module-auth": "workspace:*" - "@backstage/cli-module-build": "workspace:*" - "@backstage/cli-module-config": "workspace:*" - "@backstage/cli-module-create-github-app": "workspace:*" - "@backstage/cli-module-info": "workspace:*" - "@backstage/cli-module-lint": "workspace:*" - "@backstage/cli-module-maintenance": "workspace:*" - "@backstage/cli-module-migrate": "workspace:*" - "@backstage/cli-module-new": "workspace:*" - "@backstage/cli-module-test-jest": "workspace:*" - "@backstage/cli-module-translations": "workspace:*" + "@backstage/cli-defaults": "workspace:*" "@backstage/codemods": "workspace:*" "@backstage/create-app": "workspace:*" "@backstage/e2e-test-utils": "workspace:*"