diff --git a/packages/cli/src/commands/build/buildFrontend.ts b/packages/cli/src/commands/build/buildFrontend.ts index 59f3225738..0ba0669c32 100644 --- a/packages/cli/src/commands/build/buildFrontend.ts +++ b/packages/cli/src/commands/build/buildFrontend.ts @@ -18,7 +18,7 @@ import fs from 'fs-extra'; import { resolve as resolvePath } from 'path'; import { buildBundle, getModuleFederationOptions } from '../../lib/bundler'; import { getEnvironmentParallelism } from '../../lib/parallel'; -import { loadCliConfig } from '../../lib/config'; +import { loadCliConfig } from '../../modules/config/lib/config'; interface BuildAppOptions { targetDir: string; diff --git a/packages/cli/src/commands/index.ts b/packages/cli/src/commands/index.ts index 2a77d527c1..f249563a34 100644 --- a/packages/cli/src/commands/index.ts +++ b/packages/cli/src/commands/index.ts @@ -15,15 +15,11 @@ */ import { Command, Option } from 'commander'; -import { assertError } from '@backstage/errors'; -import { exitWithError } from '../lib/errors'; - -const configOption = [ - '--config ', - 'Config files to load instead of app-config.yaml', - (opt: string, opts: string[]) => (opts ? [...opts, opt] : [opt]), - Array(), -] as const; +import { lazy } from '../lib/lazy'; +import { + configOption, + registerCommands as registerConfigCommands, +} from '../modules/config'; export function registerRepoCommand(program: Command) { const command = program @@ -279,66 +275,7 @@ export function registerCommands(program: Command) { .option('--no-private', 'Do not mark new packages as private') .action(lazy(() => import('./new/new').then(m => m.default))); - program - .command('config:docs') - .option( - '--package ', - 'Only include the schema that applies to the given package', - ) - .description('Browse the configuration reference documentation') - .action(lazy(() => import('./config/docs').then(m => m.default))); - - program - .command('config:print') - .option( - '--package ', - 'Only load config schema that applies to the given package', - ) - .option('--lax', 'Do not require environment variables to be set') - .option('--frontend', 'Print only the frontend configuration') - .option('--with-secrets', 'Include secrets in the printed configuration') - .option( - '--format ', - 'Format to print the configuration in, either json or yaml [yaml]', - ) - .option(...configOption) - .description('Print the app configuration for the current package') - .action(lazy(() => import('./config/print').then(m => m.default))); - - program - .command('config:check') - .option( - '--package ', - 'Only load config schema that applies to the given package', - ) - .option('--lax', 'Do not require environment variables to be set') - .option('--frontend', 'Only validate the frontend configuration') - .option('--deprecated', 'Output deprecated configuration settings') - .option( - '--strict', - 'Enable strict config validation, forbidding errors and unknown keys', - ) - .option(...configOption) - .description( - 'Validate that the given configuration loads and matches schema', - ) - .action(lazy(() => import('./config/validate').then(m => m.default))); - - program - .command('config:schema') - .option( - '--package ', - 'Only output config schema that applies to the given package', - ) - .option( - '--format ', - 'Format to print the schema in, either json or yaml [yaml]', - ) - .option('--merge', 'Print the config schemas merged', true) - .option('--no-merge', 'Print the config schemas not merged') - .description('Print configuration schema') - .action(lazy(() => import('./config/schema').then(m => m.default))); - + registerConfigCommands(program); registerRepoCommand(program); registerScriptCommand(program); registerMigrateCommand(program); @@ -444,20 +381,3 @@ function removed(message?: string) { process.exit(1); }; } - -// Wraps an action function so that it always exits and handles errors -function lazy( - getActionFunc: () => Promise<(...args: any[]) => Promise>, -): (...args: any[]) => Promise { - return async (...args: any[]) => { - try { - const actionFunc = await getActionFunc(); - await actionFunc(...args); - - process.exit(0); - } catch (error) { - assertError(error); - exitWithError(error); - } - }; -} diff --git a/packages/cli/src/lib/bundler/server.ts b/packages/cli/src/lib/bundler/server.ts index 44d6d54379..f3863283e0 100644 --- a/packages/cli/src/lib/bundler/server.ts +++ b/packages/cli/src/lib/bundler/server.ts @@ -22,7 +22,7 @@ import webpack from 'webpack'; import WebpackDevServer from 'webpack-dev-server'; import { paths as libPaths } from '../../lib/paths'; -import { loadCliConfig } from '../config'; +import { loadCliConfig } from '../../modules/config/lib/config'; import { createConfig, resolveBaseUrl, resolveEndpoint } from './config'; import { createDetectedModulesEntryPoint } from './packageDetection'; import { resolveBundlingPaths, resolveOptionalBundlingPaths } from './paths'; diff --git a/packages/cli/src/lib/lazy.ts b/packages/cli/src/lib/lazy.ts new file mode 100644 index 0000000000..6d2cb1cd4f --- /dev/null +++ b/packages/cli/src/lib/lazy.ts @@ -0,0 +1,35 @@ +/* + * Copyright 2024 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. + */ + +import { assertError } from '@backstage/errors'; +import { exitWithError } from '../lib/errors'; + +// Wraps an action function so that it always exits and handles errors +export function lazy( + getActionFunc: () => Promise<(...args: any[]) => Promise>, +): (...args: any[]) => Promise { + return async (...args: any[]) => { + try { + const actionFunc = await getActionFunc(); + await actionFunc(...args); + + process.exit(0); + } catch (error) { + assertError(error); + exitWithError(error); + } + }; +} diff --git a/packages/cli/src/commands/config/docs.ts b/packages/cli/src/modules/config/commands/docs.ts similarity index 96% rename from packages/cli/src/commands/config/docs.ts rename to packages/cli/src/modules/config/commands/docs.ts index 98e683e87c..25e3a864f4 100644 --- a/packages/cli/src/commands/config/docs.ts +++ b/packages/cli/src/modules/config/commands/docs.ts @@ -19,7 +19,7 @@ import { mergeConfigSchemas } from '@backstage/config-loader'; import { OptionValues } from 'commander'; import { JSONSchema7 as JSONSchema } from 'json-schema'; import openBrowser from 'react-dev-utils/openBrowser'; -import { loadCliConfig } from '../../lib/config'; +import { loadCliConfig } from '../lib/config'; const DOCS_URL = 'https://config.backstage.io'; diff --git a/packages/cli/src/commands/config/print.ts b/packages/cli/src/modules/config/commands/print.ts similarity index 97% rename from packages/cli/src/commands/config/print.ts rename to packages/cli/src/modules/config/commands/print.ts index 9ef725ebf8..98833a7946 100644 --- a/packages/cli/src/commands/config/print.ts +++ b/packages/cli/src/modules/config/commands/print.ts @@ -17,7 +17,7 @@ import { OptionValues } from 'commander'; import { stringify as stringifyYaml } from 'yaml'; import { AppConfig, ConfigReader } from '@backstage/config'; -import { loadCliConfig } from '../../lib/config'; +import { loadCliConfig } from '../lib/config'; import { ConfigSchema, ConfigVisibility } from '@backstage/config-loader'; export default async (opts: OptionValues) => { diff --git a/packages/cli/src/commands/config/schema.ts b/packages/cli/src/modules/config/commands/schema.ts similarity index 97% rename from packages/cli/src/commands/config/schema.ts rename to packages/cli/src/modules/config/commands/schema.ts index 08bc46d1cc..73eb487d60 100644 --- a/packages/cli/src/commands/config/schema.ts +++ b/packages/cli/src/modules/config/commands/schema.ts @@ -17,7 +17,7 @@ import { OptionValues } from 'commander'; import { JSONSchema7 as JSONSchema } from 'json-schema'; import { stringify as stringifyYaml } from 'yaml'; -import { loadCliConfig } from '../../lib/config'; +import { loadCliConfig } from '../lib/config'; import { JsonObject } from '@backstage/types'; import { mergeConfigSchemas } from '@backstage/config-loader'; diff --git a/packages/cli/src/commands/config/validate.ts b/packages/cli/src/modules/config/commands/validate.ts similarity index 94% rename from packages/cli/src/commands/config/validate.ts rename to packages/cli/src/modules/config/commands/validate.ts index c81d82832e..ac0b9d15e0 100644 --- a/packages/cli/src/commands/config/validate.ts +++ b/packages/cli/src/modules/config/commands/validate.ts @@ -15,7 +15,7 @@ */ import { OptionValues } from 'commander'; -import { loadCliConfig } from '../../lib/config'; +import { loadCliConfig } from '../lib/config'; export default async (opts: OptionValues) => { await loadCliConfig({ diff --git a/packages/cli/src/modules/config/index.ts b/packages/cli/src/modules/config/index.ts new file mode 100644 index 0000000000..0c6a79577d --- /dev/null +++ b/packages/cli/src/modules/config/index.ts @@ -0,0 +1,87 @@ +/* + * Copyright 2024 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. + */ + +import { Command } from 'commander'; +import { lazy } from '../../lib/lazy'; + +export const configOption = [ + '--config ', + 'Config files to load instead of app-config.yaml', + (opt: string, opts: string[]) => (opts ? [...opts, opt] : [opt]), + Array(), +] as const; + +export function registerCommands(program: Command) { + program + .command('config:docs') + .option( + '--package ', + 'Only include the schema that applies to the given package', + ) + .description('Browse the configuration reference documentation') + .action(lazy(() => import('./commands/docs').then(m => m.default))); + + program + .command('config:print') + .option( + '--package ', + 'Only load config schema that applies to the given package', + ) + .option('--lax', 'Do not require environment variables to be set') + .option('--frontend', 'Print only the frontend configuration') + .option('--with-secrets', 'Include secrets in the printed configuration') + .option( + '--format ', + 'Format to print the configuration in, either json or yaml [yaml]', + ) + .option(...configOption) + .description('Print the app configuration for the current package') + .action(lazy(() => import('./commands/print').then(m => m.default))); + + program + .command('config:check') + .option( + '--package ', + 'Only load config schema that applies to the given package', + ) + .option('--lax', 'Do not require environment variables to be set') + .option('--frontend', 'Only validate the frontend configuration') + .option('--deprecated', 'Output deprecated configuration settings') + .option( + '--strict', + 'Enable strict config validation, forbidding errors and unknown keys', + ) + .option(...configOption) + .description( + 'Validate that the given configuration loads and matches schema', + ) + .action(lazy(() => import('./commands/validate').then(m => m.default))); + + program + .command('config:schema') + .option( + '--package ', + 'Only output config schema that applies to the given package', + ) + .option( + '--format ', + 'Format to print the schema in, either json or yaml [yaml]', + ) + .option('--merge', 'Print the config schemas merged', true) + .option('--no-merge', 'Print the config schemas not merged') + .description('Print configuration schema') + .action(lazy(() => import('./commands/schema').then(m => m.default))); +} diff --git a/packages/cli/src/lib/config.ts b/packages/cli/src/modules/config/lib/config.ts similarity index 99% rename from packages/cli/src/lib/config.ts rename to packages/cli/src/modules/config/lib/config.ts index aab16a8670..afed53af6f 100644 --- a/packages/cli/src/lib/config.ts +++ b/packages/cli/src/modules/config/lib/config.ts @@ -16,7 +16,7 @@ import { ConfigSources, loadConfigSchema } from '@backstage/config-loader'; import { AppConfig, ConfigReader } from '@backstage/config'; -import { paths } from './paths'; +import { paths } from '../../../lib/paths'; import { getPackages } from '@manypkg/get-packages'; import { PackageGraph } from '@backstage/cli-node';