From 336b3101519c32428e73599ec4f41f91fe8ef31a Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Sat, 29 Jan 2022 12:43:51 +0100 Subject: [PATCH] cli: add initial experimental repo sub-command with build Signed-off-by: Patrik Oldsberg --- packages/cli/src/commands/index.ts | 16 ++++++ packages/cli/src/commands/repo/build.ts | 75 +++++++++++++++++++++++++ 2 files changed, 91 insertions(+) create mode 100644 packages/cli/src/commands/repo/build.ts diff --git a/packages/cli/src/commands/index.ts b/packages/cli/src/commands/index.ts index a33e7d4afe..b7de9ced14 100644 --- a/packages/cli/src/commands/index.ts +++ b/packages/cli/src/commands/index.ts @@ -25,6 +25,21 @@ const configOption = [ Array(), ] as const; +export function registerRepoCommand(program: CommanderStatic) { + const command = program + .command('repo [command]', { hidden: true }) + .description( + 'Command that run across an entire Backstage project [EXPERIMENTAL]', + ); + + command + .command('build') + .description( + 'Build all packages in the project that use the standard backstage build script', + ) + .action(lazy(() => import('./repo/build').then(m => m.command))); +} + export function registerScriptCommand(program: CommanderStatic) { const command = program .command('script [command]', { hidden: true }) @@ -312,6 +327,7 @@ export function registerCommands(program: CommanderStatic) { .description('Print configuration schema') .action(lazy(() => import('./config/schema').then(m => m.default))); + registerRepoCommand(program); registerScriptCommand(program); registerMigrateCommand(program); diff --git a/packages/cli/src/commands/repo/build.ts b/packages/cli/src/commands/repo/build.ts new file mode 100644 index 0000000000..50198772d7 --- /dev/null +++ b/packages/cli/src/commands/repo/build.ts @@ -0,0 +1,75 @@ +/* + * Copyright 2020 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 chalk from 'chalk'; +import { relative as relativePath } from 'path'; +import { buildPackages, Output } from '../../lib/builder'; +import { PackageGraph } from '../../lib/monorepo'; +import { paths } from '../../lib/paths'; +import { getRoleInfo } from '../../lib/role'; + +const outputMap = { + esm: Output.esm, + cjs: Output.cjs, + types: Output.types, + bundle: undefined, +}; + +export async function command(): Promise { + const packages = await PackageGraph.listTargetPackages(); + + const options = packages.flatMap(pkg => { + const role = pkg.packageJson.backstage?.role; + if (!role) { + console.warn(`Ignored ${pkg.packageJson.name} because it has no role`); + return []; + } + + const roleInfo = getRoleInfo(role); + const outputs = roleInfo.output + .map(output => outputMap[output]) + .filter((x): x is Output => Boolean(x)); + if (outputs.length === 0) { + console.warn(`Ignored ${pkg.packageJson.name} because it has no output`); + return []; + } + + const buildScript = pkg.packageJson.scripts?.build; + if (!buildScript) { + console.warn( + `Ignored ${pkg.packageJson.name} because it has no build script`, + ); + return []; + } + if (!buildScript.startsWith('backstage-cli script build')) { + console.warn( + `Ignored ${pkg.packageJson.name} because it has a custom build script, '${buildScript}'`, + ); + return []; + } + + return { + targetDir: pkg.dir, + outputs: new Set(outputs), + logPrefix: `${chalk.cyan(relativePath(paths.targetRoot, pkg.dir))}: `, + // TODO(Rugvip): Use commander to parse the script and grab these instead + minify: buildScript.includes('--minify'), + useApiExtractor: buildScript.includes('--experimental-type-build'), + }; + }); + + await buildPackages(options); +}