cli/new: merge parameters and templateValues

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
Patrik Oldsberg
2025-02-11 11:26:32 +01:00
parent 82107cd9a5
commit 10c419cc0c
8 changed files with 110 additions and 41 deletions
+2 -3
View File
@@ -106,7 +106,7 @@ Your first step in creating your own CLI template is composing your yaml file:
name: custom-plugin
role: frontend-plugin
description: Description of my CLI template # optional
templateValues: # optional
values: # optional
pluginVar: '{{ camelCase pluginId }}Plugin'
```
@@ -115,8 +115,7 @@ The following properties are supported:
- `name` **(required)** - The name of your template, used by the user to select it.
- `role` **(required)** - The role of the template, similar to package role. See [Template Roles](#template-roles) for more details.
- `description` - A description of the type of package that this template produces.
- `parameters` - A map of pre-filled parameters that will be used instead of prompting the user for input.
- `templateValues` - A map of additional values that will be present during templating. The values are themselves templated and can reference other values.
- `values` - A map of additional values that will be present during templating. The values are themselves templated and can reference other values. If the key matches any of the user prompts, such as `pluginId`, the value will be used directly instead of prompting the user.
Once you have your composed template yaml file, [add your new template](#installing-custom-templates) to the CLI config in your root `package.json`:
@@ -42,8 +42,7 @@ describe('writeTemplateContents', () => {
name: 'test',
files: [],
role: 'frontend-plugin',
parameters: {},
templateValues: {},
values: {},
},
{
...baseConfig,
@@ -77,8 +76,7 @@ describe('writeTemplateContents', () => {
},
],
role: 'frontend-plugin',
parameters: {},
templateValues: {},
values: {},
},
{
...baseConfig,
@@ -43,7 +43,7 @@ export async function writeTemplateContents(
...roleValues,
packageName: input.packageName,
},
templatedValues: template.templateValues,
templatedValues: template.values,
});
if (!isMonoRepo) {
@@ -17,6 +17,7 @@
import inquirer from 'inquirer';
import { PortableTemplateConfig } from '../types';
import { collectPortableTemplateInput } from './collectPortableTemplateInput';
import { withLogCollector } from '@backstage/test-utils';
describe('collectTemplateParams', () => {
const baseOptions = {
@@ -33,28 +34,13 @@ describe('collectTemplateParams', () => {
name: 'test',
role: 'frontend-plugin' as const,
files: [],
parameters: {},
templateValues: {},
},
prefilledParams: {
pluginId: 'test',
owner: 'me',
values: {},
},
prefilledParams: {},
};
it('should return default values if not provided', async () => {
await expect(collectPortableTemplateInput(baseOptions)).resolves.toEqual({
roleParams: {
role: 'frontend-plugin',
pluginId: 'test',
},
owner: 'me',
version: '0.1.0',
license: 'Apache-2.0',
private: true,
packageName: '@internal/plugin-test',
packagePath: 'plugins/test',
});
beforeEach(() => {
jest.resetAllMocks();
});
it('should prompt for missing parameters', async () => {
@@ -78,4 +64,89 @@ describe('collectTemplateParams', () => {
packagePath: 'plugins/other',
});
});
it('should pick up prefilled parameters', async () => {
await expect(
collectPortableTemplateInput({
...baseOptions,
prefilledParams: {
pluginId: 'test1',
owner: 'me',
},
}),
).resolves.toEqual({
roleParams: {
role: 'frontend-plugin',
pluginId: 'test1',
},
owner: 'me',
version: '0.1.0',
license: 'Apache-2.0',
private: true,
packageName: '@internal/plugin-test1',
packagePath: 'plugins/test1',
});
});
it('should pick up template values', async () => {
await expect(
collectPortableTemplateInput({
...baseOptions,
template: {
...baseOptions.template,
values: {
pluginId: 'test2',
owner: 'me',
},
},
}),
).resolves.toEqual({
roleParams: {
role: 'frontend-plugin',
pluginId: 'test2',
},
owner: 'me',
version: '0.1.0',
license: 'Apache-2.0',
private: true,
packageName: '@internal/plugin-test2',
packagePath: 'plugins/test2',
});
});
it('should map deprecated id param to pluginId', async () => {
const logs = await withLogCollector(async () => {
await expect(
collectPortableTemplateInput({
...baseOptions,
config: {
...baseOptions.config,
isUsingDefaultTemplates: true,
},
prefilledParams: {
id: 'test3',
owner: 'me',
},
}),
).resolves.toEqual({
roleParams: {
role: 'frontend-plugin',
pluginId: 'test3',
},
owner: 'me',
version: '0.1.0',
license: 'Apache-2.0',
private: true,
packageName: '@internal/plugin-test3',
packagePath: 'plugins/test3',
});
});
expect(logs).toEqual({
error: [],
log: [],
warn: [
`DEPRECATION WARNING: The 'id' parameter is deprecated, use 'pluginId' instead`,
],
});
});
});
@@ -46,15 +46,20 @@ export async function collectPortableTemplateInput(
prompts.push(ownerPrompt());
}
const parameters = { ...template.parameters, ...prefilledParams };
if (config.isUsingDefaultTemplates && parameters.id) {
const deprecatedParams: PortableTemplateParams = {};
if (config.isUsingDefaultTemplates && prefilledParams.id) {
console.warn(
`DEPRECATION WARNING: The 'id' parameter is deprecated, use 'pluginId' instead`,
);
parameters.pluginId = parameters.id;
deprecatedParams.pluginId = prefilledParams.id;
}
const parameters = {
...template.values,
...prefilledParams,
...deprecatedParams,
};
const needsAnswer = [];
const prefilledAnswers = {} as PortableTemplateParams;
for (const prompt of prompts) {
@@ -29,7 +29,7 @@ describe('loadTemplate', () => {
'path/to/template.yaml': `
name: template1
role: frontend-plugin
parameters:
values:
foo: bar
`,
'path/to/hello.txt': 'hello world',
@@ -44,8 +44,7 @@ describe('loadTemplate', () => {
name: 'template1',
role: 'frontend-plugin',
files: [{ path: 'hello.txt', content: 'hello world' }],
parameters: { foo: 'bar' },
templateValues: {},
values: { foo: 'bar' },
});
});
@@ -35,8 +35,7 @@ const templateDefinitionSchema = z
name: z.string(),
role: z.enum(TEMPLATE_ROLES),
description: z.string().optional(),
parameters: z.record(z.string()).optional(),
templateValues: z.record(z.string()).optional(),
values: z.record(z.string()).optional(),
})
.strict();
@@ -64,7 +63,7 @@ export async function loadPortableTemplate(
);
}
const { role, parameters = {}, templateValues = {} } = parsed.data;
const { role, values = {} } = parsed.data;
const templatePath = resolvePath(dirname(pointer.target));
const filePaths = await recursiveReaddir(templatePath).catch(error => {
@@ -104,7 +103,6 @@ export async function loadPortableTemplate(
name: pointer.name,
role,
files: loadedFiles,
parameters,
templateValues,
values,
};
}
+1 -2
View File
@@ -69,8 +69,7 @@ export type PortableTemplate = {
name: string;
role: PortableTemplateRole;
files: PortableTemplateFile[];
parameters: Record<string, string>;
templateValues: Record<string, string>;
values: Record<string, string>;
};
export type PortableTemplateParams = {