cli: cmd options and discovery for additional creation context

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
Patrik Oldsberg
2021-11-12 12:03:23 +01:00
parent 3ca0d3368e
commit 84936dbcbe
4 changed files with 59 additions and 7 deletions
+34 -3
View File
@@ -14,8 +14,11 @@
* limitations under the License.
*/
import fs from 'fs-extra';
import { Command } from 'commander';
import { FactoryRegistry } from '../../lib/create/FactoryRegistry';
import { paths } from '../../lib/paths';
import { assertError } from '@backstage/errors';
function parseOptions(optionStrings: string[]): Record<string, string> {
const options: Record<string, string> = {};
@@ -35,13 +38,41 @@ function parseOptions(optionStrings: string[]): Record<string, string> {
}
export default async (cmd: Command) => {
const factory = await FactoryRegistry.interactiveSelect(cmd.opts().select);
const cmdOpts = cmd.opts();
const providedOptions = parseOptions(cmd.opts().option);
const factory = await FactoryRegistry.interactiveSelect(cmdOpts.select);
const providedOptions = parseOptions(cmdOpts.option);
const options = await FactoryRegistry.populateOptions(
factory,
providedOptions,
);
await factory.create(options);
const rootPackageJson = await fs.readJson(
paths.resolveTargetRoot('package.json'),
);
const isMonoRepo = Boolean(rootPackageJson.workspaces);
let defaultVersion = '0.1.0';
try {
const rootLernaJson = await fs.readJson(
paths.resolveTargetRoot('lerna.json'),
);
if (rootLernaJson.version) {
defaultVersion = rootLernaJson.version;
}
} catch (error) {
assertError(error);
if (error.code !== 'ENOENT') {
throw error;
}
}
await factory.create(options, {
isMonoRepo,
defaultVersion,
scope: cmdOpts.scope.replace(/^@/, ''),
npmRegistry: cmdOpts.npmRegistry,
private: Boolean(cmdOpts.private),
});
};
+6
View File
@@ -91,6 +91,12 @@ export function registerCommands(program: CommanderStatic) {
(opt, arr: string[]) => [...arr, opt],
[],
)
.option('--scope <scope>', 'The scope to use for new packages')
.option(
'--npm-registry <URL>',
'The package registry to use for new packages',
)
.option('--no-private', 'Do not mark new packages as private')
.action(lazy(() => import('./create/create').then(m => m.default)));
program
@@ -16,7 +16,7 @@
import { paths } from '../../../lib/paths';
import { getCodeownersFilePath, parseOwnerIds } from '../../../lib/codeowners';
import { createFactory } from '../types';
import { createFactory, CreateContext } from '../types';
type Options = {
id: string;
@@ -63,9 +63,11 @@ export const frontendPlugin = createFactory<Options>({
},
},
],
async create(options: Options) {
async create(options: Options, context: CreateContext) {
console.log(
`Creating ${this.name} with options ${JSON.stringify(options)}`,
`Creating ${this.name} with options ${JSON.stringify(
options,
)} and context ${JSON.stringify(context)}`,
);
},
});
+14 -1
View File
@@ -16,6 +16,19 @@
import { DistinctQuestion } from 'inquirer';
export interface CreateContext {
/** The package scope to use for new packages */
scope?: string;
/** The NPM registry to use for new packages */
npmRegistry?: string;
/** Whether new packages should be marked as private */
private: boolean;
/** Whether we are creating something in a monorepo or not */
isMonoRepo: boolean;
/** The default version to use for new packages */
defaultVersion: string;
}
export type AnyOptions = Record<string, string>;
export interface Factory<Options extends AnyOptions> {
@@ -23,7 +36,7 @@ export interface Factory<Options extends AnyOptions> {
description: string;
optionsDiscovery?(): Promise<Partial<Options>>;
optionsPrompts?: ReadonlyArray<DistinctQuestion<Options> & { name: string }>;
create(options: Options): Promise<void>;
create(options: Options, context?: CreateContext): Promise<void>;
}
export type AnyFactory = Factory<AnyOptions>;