From 10a12c7a173866e5b2a34be587554fc266b120bd Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Fri, 7 Feb 2025 13:01:08 +0100 Subject: [PATCH] cli/new: refactor template loading Signed-off-by: Patrik Oldsberg --- packages/cli/src/lib/new/createNewPackage.ts | 10 ++- .../src/lib/new/loader/NewTemplateLoader.ts | 69 +++++++++++++++++++ packages/cli/src/lib/new/templateSelector.ts | 47 ------------- packages/cli/src/lib/new/types.ts | 3 +- 4 files changed, 74 insertions(+), 55 deletions(-) delete mode 100644 packages/cli/src/lib/new/templateSelector.ts diff --git a/packages/cli/src/lib/new/createNewPackage.ts b/packages/cli/src/lib/new/createNewPackage.ts index b5cc85f1ec..19208f4c6b 100644 --- a/packages/cli/src/lib/new/createNewPackage.ts +++ b/packages/cli/src/lib/new/createNewPackage.ts @@ -23,7 +23,6 @@ import { paths } from '../paths'; import { Task } from '../tasks'; import { addCodeownersEntry, getCodeownersFilePath } from '../codeowners'; -import { verifyTemplate } from './templateSelector'; import { promptOptions } from './prompts'; import { populateOptions, createDirName, resolvePackageName } from './utils'; import { runAdditionalActions } from './additionalActions'; @@ -47,12 +46,11 @@ export type CreateNewPackageOptions = { export async function createNewPackage(options: CreateNewPackageOptions) { const newConfig = await loadNewConfig(); - const template = verifyTemplate( - await NewTemplateLoader.selectTemplateInteractively( - newConfig, - options.preselectedTemplateId, - ), + const selectedTemplate = await NewTemplateLoader.selectTemplateInteractively( + newConfig, + options.preselectedTemplateId, ); + const template = await NewTemplateLoader.loadTemplate(selectedTemplate); const codeOwnersFilePath = await getCodeownersFilePath(paths.targetRoot); diff --git a/packages/cli/src/lib/new/loader/NewTemplateLoader.ts b/packages/cli/src/lib/new/loader/NewTemplateLoader.ts index 27a250ed84..c4bb873971 100644 --- a/packages/cli/src/lib/new/loader/NewTemplateLoader.ts +++ b/packages/cli/src/lib/new/loader/NewTemplateLoader.ts @@ -14,8 +14,41 @@ * limitations under the License. */ +import { z } from 'zod'; +import fs from 'fs-extra'; import inquirer from 'inquirer'; +import { dirname } from 'node:path'; +import { parse as parseYaml } from 'yaml'; +import { paths } from '../../paths'; import { NewConfig, NewTemplatePointer } from '../config/types'; +import { Template } from '../types'; +import { ForwardedError } from '@backstage/errors'; +import { fromZodError } from 'zod-validation-error'; + +const templateDefinitionSchema = z + .object({ + description: z.string().optional(), + template: z.string(), + targetPath: z.string(), + plugin: z.boolean().optional(), + backendModulePrefix: z.boolean().optional(), + suffix: z.string().optional(), + prompts: z + .array( + z.union([ + z.string(), + z.object({ + id: z.string(), + prompt: z.string(), + validate: z.string().optional(), + default: z.union([z.string(), z.boolean(), z.number()]).optional(), + }), + ]), + ) + .optional(), + additionalActions: z.array(z.string()).optional(), + }) + .strict(); export class NewTemplateLoader { static async selectTemplateInteractively( @@ -49,4 +82,40 @@ export class NewTemplateLoader { } return template; } + + static async loadTemplate({ + id, + target, + }: NewTemplatePointer): Promise