From 97ebb9b0bf7e69f9370490133e2d68858fdb2e52 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Fri, 7 Feb 2025 12:11:46 +0100 Subject: [PATCH] cli/new: refactor template selection Signed-off-by: Patrik Oldsberg --- packages/cli/src/lib/new/createNewPackage.ts | 7 +-- .../src/lib/new/loader/NewTemplateLoader.ts | 52 +++++++++++++++++++ packages/cli/src/lib/new/templateSelector.ts | 38 +------------- 3 files changed, 57 insertions(+), 40 deletions(-) create mode 100644 packages/cli/src/lib/new/loader/NewTemplateLoader.ts diff --git a/packages/cli/src/lib/new/createNewPackage.ts b/packages/cli/src/lib/new/createNewPackage.ts index d3f3f58ec7..b5cc85f1ec 100644 --- a/packages/cli/src/lib/new/createNewPackage.ts +++ b/packages/cli/src/lib/new/createNewPackage.ts @@ -23,13 +23,14 @@ import { paths } from '../paths'; import { Task } from '../tasks'; import { addCodeownersEntry, getCodeownersFilePath } from '../codeowners'; -import { templateSelector, verifyTemplate } from './templateSelector'; +import { verifyTemplate } from './templateSelector'; import { promptOptions } from './prompts'; import { populateOptions, createDirName, resolvePackageName } from './utils'; import { runAdditionalActions } from './additionalActions'; import { executePluginPackageTemplate } from './executeTemplate'; import { TemporaryDirectoryManager } from './TemporaryDirectoryManager'; import { loadNewConfig } from './config/loadNewConfig'; +import { NewTemplateLoader } from './loader/NewTemplateLoader'; export type CreateNewPackageOptions = { preselectedTemplateId?: string; @@ -47,8 +48,8 @@ export async function createNewPackage(options: CreateNewPackageOptions) { const newConfig = await loadNewConfig(); const template = verifyTemplate( - await templateSelector( - newConfig.templatePointers, + await NewTemplateLoader.selectTemplateInteractively( + newConfig, options.preselectedTemplateId, ), ); diff --git a/packages/cli/src/lib/new/loader/NewTemplateLoader.ts b/packages/cli/src/lib/new/loader/NewTemplateLoader.ts new file mode 100644 index 0000000000..27a250ed84 --- /dev/null +++ b/packages/cli/src/lib/new/loader/NewTemplateLoader.ts @@ -0,0 +1,52 @@ +/* + * Copyright 2025 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 inquirer from 'inquirer'; +import { NewConfig, NewTemplatePointer } from '../config/types'; + +export class NewTemplateLoader { + static async selectTemplateInteractively( + config: NewConfig, + preselectedTemplateId?: string, + ): Promise { + let selectedId = preselectedTemplateId; + + if (config.isUsingDefaultTemplates && selectedId === 'plugin') { + console.warn( + `DEPRECATION WARNING: The 'plugin' template is deprecated, use 'frontend-plugin' instead`, + ); + selectedId = 'frontend-plugin'; + } + + if (!selectedId) { + const answers = await inquirer.prompt<{ id: string }>([ + { + type: 'list', + name: 'id', + message: 'What do you want to create?', + choices: config.templatePointers.map(t => t.id), + }, + ]); + selectedId = answers.id; + } + + const template = config.templatePointers.find(t => t.id === selectedId); + if (!template) { + throw new Error(`Template '${selectedId}' not found`); + } + return template; + } +} diff --git a/packages/cli/src/lib/new/templateSelector.ts b/packages/cli/src/lib/new/templateSelector.ts index 9be7c144c2..d735ad2a66 100644 --- a/packages/cli/src/lib/new/templateSelector.ts +++ b/packages/cli/src/lib/new/templateSelector.ts @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import inquirer from 'inquirer'; + import { dirname } from 'path'; import { parse } from 'yaml'; import fs from 'fs-extra'; @@ -21,42 +21,6 @@ import fs from 'fs-extra'; import { paths } from '../paths'; import { Template, TemplateLocation } from './types'; -import { defaultTemplates } from './defaultTemplates'; - -export async function templateSelector( - templates: TemplateLocation[], - selected?: string, -): Promise { - if (selected) { - let selectedId = selected; - if (templates === defaultTemplates && selectedId === 'plugin') { - console.warn( - `DEPRECATION WARNING: The 'plugin' template is deprecated, use 'frontend-plugin' instead`, - ); - selectedId = 'frontend-plugin'; - } - const template = templates.find(t => t.id === selectedId); - if (!template) { - throw new Error(`Template '${selected}' not found`); - } - return template; - } - const answer = await inquirer.prompt<{ name: TemplateLocation }>([ - { - type: 'list', - name: 'name', - message: 'What do you want to create?', - choices: templates.map(template => { - return { - name: template.id, - value: template, - }; - }), - }, - ]); - return answer.name; -} - export function verifyTemplate({ id, target }: TemplateLocation): Template { if (target.startsWith('http')) { throw new Error('Remote templates are not supported yet');