cli: add utility for passing explicit role option

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
Patrik Oldsberg
2022-01-22 16:39:48 +01:00
parent 17a9f90efc
commit f0ee50cfab
5 changed files with 68 additions and 10 deletions
+2 -8
View File
@@ -14,19 +14,13 @@
* limitations under the License.
*/
import fs from 'fs-extra';
import { Command } from 'commander';
import { paths } from '../../lib/paths';
import { readPackageRole } from '../../lib/role/packageRoles';
import { bundleApp } from './bundleApp';
import { bundleBackend } from './bundleBackend';
import { readRoleForCommand } from '../../lib/role';
export async function command(cmd: Command): Promise<void> {
const pkg = await fs.readJson(paths.resolveTarget('package.json'));
const roleInfo = readPackageRole(pkg);
if (!roleInfo) {
throw new Error(`Target package must have 'backstage.role' set`);
}
const roleInfo = await readRoleForCommand(cmd);
const options = {
configPaths: cmd.config as string[],
+2 -1
View File
@@ -136,6 +136,8 @@ export function registerCommands(program: CommanderStatic) {
program
.command('bundle')
.description('Bundle a package for deployment')
.option(...configOption)
.option('--role <name>', 'Run the command with an explicit package role')
.option(
'--skip-build-dependencies',
'Skip the automatic building of local dependencies',
@@ -144,7 +146,6 @@ export function registerCommands(program: CommanderStatic) {
'--stats',
'If bundle stats are available, write them to the output directory',
)
.option(...configOption)
.action(lazy(() => import('./bundle').then(m => m.command)));
program
+2 -1
View File
@@ -21,6 +21,7 @@ export type {
} from './types';
export {
getRoleInfo,
detectPackageRole,
readPackageRole,
readRoleForCommand,
detectPackageRole,
} from './packageRoles';
@@ -14,9 +14,12 @@
* limitations under the License.
*/
import mockFs from 'mock-fs';
import { Command } from 'commander';
import {
getRoleInfo,
readPackageRole,
readRoleForCommand,
detectPackageRole,
} from './packageRoles';
@@ -78,6 +81,47 @@ describe('readPackageRole', () => {
});
});
describe('readRoleForCommand', () => {
function mkCommand(args: string) {
return new Command()
.option('--role <role>', 'test role')
.parse(['node', 'entry.js', ...args.split(' ')]) as Command;
}
beforeEach(() => {
mockFs({
'package.json': JSON.stringify({
name: 'test',
backstage: {
role: 'web-library',
},
}),
});
});
afterEach(() => {
mockFs.restore();
});
it('provides role info by role', async () => {
await expect(readRoleForCommand(mkCommand(''))).resolves.toEqual({
role: 'web-library',
platform: 'web',
});
await expect(
readRoleForCommand(mkCommand('--role node-library')),
).resolves.toEqual({
role: 'node-library',
platform: 'node',
});
await expect(
readRoleForCommand(mkCommand('--role invalid')),
).rejects.toThrow(`Unknown package role 'invalid'`);
});
});
describe('detectPackageRole', () => {
it('detects the role of example-app', () => {
expect(
+18
View File
@@ -15,6 +15,9 @@
*/
import { z } from 'zod';
import fs from 'fs-extra';
import { Command } from 'commander';
import { paths } from '../paths';
import { PackageRoleInfo } from './types';
const packageRoles: PackageRoleInfo[] = [
@@ -66,6 +69,21 @@ export function readPackageRole(pkgJson: unknown): PackageRoleInfo | undefined {
return undefined;
}
export async function readRoleForCommand(
cmd: Command,
): Promise<PackageRoleInfo> {
if (cmd.role) {
return getRoleInfo(cmd.role);
}
const pkg = await fs.readJson(paths.resolveTarget('package.json'));
const info = readPackageRole(pkg);
if (!info) {
throw new Error(`Target package must have 'backstage.role' set`);
}
return info;
}
const detectionSchema = z.object({
name: z.string().optional(),
scripts: z