From 142cd41b7e351c20f23a6a9f611586b28bcf81ce Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Fri, 12 Nov 2021 16:08:32 +0100 Subject: [PATCH] cli: refactor create factories to use common prompts Signed-off-by: Patrik Oldsberg --- .../src/lib/create/factories/backendPlugin.ts | 35 +---------- .../lib/create/factories/common/prompts.ts | 58 +++++++++++++++++++ .../lib/create/factories/frontendPlugin.ts | 35 +---------- packages/cli/src/lib/create/types.ts | 14 +++-- 4 files changed, 70 insertions(+), 72 deletions(-) create mode 100644 packages/cli/src/lib/create/factories/common/prompts.ts diff --git a/packages/cli/src/lib/create/factories/backendPlugin.ts b/packages/cli/src/lib/create/factories/backendPlugin.ts index 9cf78900a7..d7855d5d68 100644 --- a/packages/cli/src/lib/create/factories/backendPlugin.ts +++ b/packages/cli/src/lib/create/factories/backendPlugin.ts @@ -28,6 +28,7 @@ import { createFactory, CreateContext } from '../types'; import { Lockfile } from '../../versioning'; import { addPackageDependency, Task, templatingTask } from '../../tasks'; import { createPackageVersionProvider } from '../../version'; +import { ownerPrompt, pluginIdPrompt } from './common/prompts'; type Options = { id: string; @@ -41,39 +42,7 @@ export const backendPlugin = createFactory({ optionsDiscovery: async () => ({ codeOwnersPath: await getCodeownersFilePath(paths.targetRoot), }), - optionsPrompts: [ - { - type: 'input', - name: 'id', - message: 'Enter an ID for the plugin [required]', - validate: (value: string) => { - if (!value) { - return 'Please enter an ID for the plugin'; - } else if (!/^[a-z0-9]+(-[a-z0-9]+)*$/.test(value)) { - return 'Plugin IDs must be lowercase and contain only letters, digits, and dashes.'; - } - return true; - }, - }, - { - type: 'input', - name: 'owner', - message: 'Enter an owner of the plugin to add to CODEOWNERS [optional]', - when: opts => Boolean(opts.codeOwnersPath), - validate: (value: string) => { - if (!value) { - return true; - } - - const ownerIds = parseOwnerIds(value); - if (!ownerIds) { - return 'The owner must be a space separated list of team names (e.g. @org/team-name), usernames (e.g. @username), or the email addresses (e.g. user@example.com).'; - } - - return true; - }, - }, - ], + optionsPrompts: [pluginIdPrompt(), ownerPrompt()], async create(options: Options, ctx: CreateContext) { const id = `${options.id}-backend`; const name = ctx.scope ? `@${ctx.scope}/plugin-${id}` : `plugin-${id}`; diff --git a/packages/cli/src/lib/create/factories/common/prompts.ts b/packages/cli/src/lib/create/factories/common/prompts.ts new file mode 100644 index 0000000000..9c7672ddfb --- /dev/null +++ b/packages/cli/src/lib/create/factories/common/prompts.ts @@ -0,0 +1,58 @@ +/* + * Copyright 2021 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 { Prompt } from '../../types'; +import { parseOwnerIds } from '../../../codeowners'; + +export function pluginIdPrompt(): Prompt<{ id: string }> { + return { + type: 'input', + name: 'id', + message: 'Enter the ID of the plugin [required]', + validate: (value: string) => { + if (!value) { + return 'Please enter the ID of the plugin'; + } else if (!/^[a-z0-9]+(-[a-z0-9]+)*$/.test(value)) { + return 'Plugin IDs must be lowercase and contain only letters, digits, and dashes.'; + } + return true; + }, + }; +} + +export function ownerPrompt(): Prompt<{ + owner?: string; + codeOwnersPath?: string; +}> { + return { + type: 'input', + name: 'owner', + message: 'Enter an owner to add to CODEOWNERS [optional]', + when: opts => Boolean(opts.codeOwnersPath), + validate: (value: string) => { + if (!value) { + return true; + } + + const ownerIds = parseOwnerIds(value); + if (!ownerIds) { + return 'The owner must be a space separated list of team names (e.g. @org/team-name), usernames (e.g. @username), or the email addresses (e.g. user@example.com).'; + } + + return true; + }, + }; +} diff --git a/packages/cli/src/lib/create/factories/frontendPlugin.ts b/packages/cli/src/lib/create/factories/frontendPlugin.ts index a85403e8ed..3fe01b7325 100644 --- a/packages/cli/src/lib/create/factories/frontendPlugin.ts +++ b/packages/cli/src/lib/create/factories/frontendPlugin.ts @@ -28,6 +28,7 @@ import { createFactory, CreateContext } from '../types'; import { Lockfile } from '../../versioning'; import { addPackageDependency, Task, templatingTask } from '../../tasks'; import { createPackageVersionProvider } from '../../version'; +import { ownerPrompt, pluginIdPrompt } from './common/prompts'; type Options = { id: string; @@ -41,39 +42,7 @@ export const frontendPlugin = createFactory({ optionsDiscovery: async () => ({ codeOwnersPath: await getCodeownersFilePath(paths.targetRoot), }), - optionsPrompts: [ - { - type: 'input', - name: 'id', - message: 'Enter an ID for the plugin [required]', - validate: (value: string) => { - if (!value) { - return 'Please enter an ID for the plugin'; - } else if (!/^[a-z0-9]+(-[a-z0-9]+)*$/.test(value)) { - return 'Plugin IDs must be lowercase and contain only letters, digits, and dashes.'; - } - return true; - }, - }, - { - type: 'input', - name: 'owner', - message: 'Enter an owner of the plugin to add to CODEOWNERS [optional]', - when: opts => Boolean(opts.codeOwnersPath), - validate: (value: string) => { - if (!value) { - return true; - } - - const ownerIds = parseOwnerIds(value); - if (!ownerIds) { - return 'The owner must be a space separated list of team names (e.g. @org/team-name), usernames (e.g. @username), or the email addresses (e.g. user@example.com).'; - } - - return true; - }, - }, - ], + optionsPrompts: [pluginIdPrompt(), ownerPrompt()], async create(options: Options, ctx: CreateContext) { const { id } = options; diff --git a/packages/cli/src/lib/create/types.ts b/packages/cli/src/lib/create/types.ts index 6a45067e9b..fd2e684e11 100644 --- a/packages/cli/src/lib/create/types.ts +++ b/packages/cli/src/lib/create/types.ts @@ -37,18 +37,20 @@ export interface CreateContext { export type AnyOptions = Record; -export interface Factory { +export type Prompt = DistinctQuestion & { name: string }; + +export interface Factory { name: string; description: string; - optionsDiscovery?(): Promise>; - optionsPrompts?: ReadonlyArray & { name: string }>; - create(options: Options, context?: CreateContext): Promise; + optionsDiscovery?(): Promise>; + optionsPrompts?: ReadonlyArray>; + create(options: TOptions, context?: CreateContext): Promise; } export type AnyFactory = Factory; -export function createFactory( - config: Factory, +export function createFactory( + config: Factory, ): AnyFactory { return config as AnyFactory; }