cli: Add pluginPackage support to backend-plugin-module template
Signed-off-by: Vincenzo Scamporlino <vincenzos@spotify.com>
This commit is contained in:
committed by
Patrik Oldsberg
parent
ef910b05b9
commit
971cc9457a
@@ -149,4 +149,70 @@ describe('collectTemplateParams', () => {
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
describe('backend-plugin-module with pluginPackage', () => {
|
||||
const backendModuleOptions = {
|
||||
...baseOptions,
|
||||
template: {
|
||||
name: 'test-module',
|
||||
role: 'backend-plugin-module' as const,
|
||||
files: [],
|
||||
values: {},
|
||||
},
|
||||
};
|
||||
|
||||
it('should auto-fill pluginPackage for catalog plugin without prompting', async () => {
|
||||
await expect(
|
||||
collectPortableTemplateInput({
|
||||
...backendModuleOptions,
|
||||
prefilledParams: {
|
||||
pluginId: 'catalog',
|
||||
moduleId: 'my-module',
|
||||
},
|
||||
}),
|
||||
).resolves.toEqual({
|
||||
roleParams: {
|
||||
role: 'backend-plugin-module',
|
||||
pluginId: 'catalog',
|
||||
moduleId: 'my-module',
|
||||
pluginPackage: '@backstage/plugin-catalog-backend',
|
||||
},
|
||||
owner: undefined,
|
||||
version: '0.1.0',
|
||||
license: 'Apache-2.0',
|
||||
private: true,
|
||||
packageName: '@internal/plugin-catalog-backend-module-my-module',
|
||||
packagePath: 'plugins/catalog-backend-module-my-module',
|
||||
});
|
||||
});
|
||||
|
||||
it('should prompt for pluginPackage for unknown plugins', async () => {
|
||||
jest.spyOn(inquirer, 'prompt').mockResolvedValueOnce({
|
||||
pluginPackage: '@mycompany/plugin-custom-backend',
|
||||
});
|
||||
|
||||
await expect(
|
||||
collectPortableTemplateInput({
|
||||
...backendModuleOptions,
|
||||
prefilledParams: {
|
||||
pluginId: 'custom',
|
||||
moduleId: 'my-extension',
|
||||
},
|
||||
}),
|
||||
).resolves.toEqual({
|
||||
roleParams: {
|
||||
role: 'backend-plugin-module',
|
||||
pluginId: 'custom',
|
||||
moduleId: 'my-extension',
|
||||
pluginPackage: '@mycompany/plugin-custom-backend',
|
||||
},
|
||||
owner: undefined,
|
||||
version: '0.1.0',
|
||||
license: 'Apache-2.0',
|
||||
private: true,
|
||||
packageName: '@internal/plugin-custom-backend-module-my-extension',
|
||||
packagePath: 'plugins/custom-backend-module-my-extension',
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -28,6 +28,13 @@ import {
|
||||
import { PortableTemplate } from '../types';
|
||||
import { resolvePackageParams } from './resolvePackageParams';
|
||||
|
||||
const knownPluginPackages: Record<string, string> = {
|
||||
auth: '@backstage/plugin-auth-backend',
|
||||
catalog: '@backstage/plugin-catalog-backend',
|
||||
events: '@backstage/plugin-events-backend',
|
||||
scaffolder: '@backstage/plugin-scaffolder-backend',
|
||||
};
|
||||
|
||||
type CollectTemplateParamsOptions = {
|
||||
config: PortableTemplateConfig;
|
||||
template: PortableTemplate;
|
||||
@@ -80,11 +87,16 @@ export async function collectPortableTemplateInput(
|
||||
...promptAnswers,
|
||||
};
|
||||
|
||||
const pluginPackage =
|
||||
knownPluginPackages[answers.pluginId as string] ??
|
||||
(answers.pluginPackage as string);
|
||||
|
||||
const roleParams = {
|
||||
role: template.role,
|
||||
name: answers.name,
|
||||
pluginId: answers.pluginId,
|
||||
moduleId: answers.moduleId,
|
||||
pluginPackage,
|
||||
} as PortableTemplateInputRoleParams;
|
||||
|
||||
const packageParams = resolvePackageParams({
|
||||
@@ -153,6 +165,26 @@ export function moduleIdIdPrompt(): DistinctQuestion {
|
||||
};
|
||||
}
|
||||
|
||||
export function pluginPackagePrompt(): DistinctQuestion {
|
||||
return {
|
||||
type: 'input',
|
||||
name: 'pluginPackage',
|
||||
message:
|
||||
'Enter the package name of the plugin this module extends (e.g. @backstage/plugin-catalog-backend) [required]',
|
||||
validate: (value: string) => {
|
||||
if (!value) {
|
||||
return 'Please enter the package name of the plugin';
|
||||
}
|
||||
if (!isValidNpmPackageName(value)) {
|
||||
return 'Please enter a valid npm package name (e.g. @backstage/plugin-catalog-backend or my-plugin-backend)';
|
||||
}
|
||||
return true;
|
||||
},
|
||||
when: (answers: PortableTemplateParams) =>
|
||||
!knownPluginPackages[answers.pluginId as string],
|
||||
};
|
||||
}
|
||||
|
||||
export function getPromptsForRole(
|
||||
role: PortableTemplateRole,
|
||||
): Array<DistinctQuestion> {
|
||||
@@ -169,8 +201,9 @@ export function getPromptsForRole(
|
||||
case 'backend-plugin':
|
||||
return [pluginIdPrompt()];
|
||||
case 'frontend-plugin-module':
|
||||
case 'backend-plugin-module':
|
||||
return [pluginIdPrompt(), moduleIdIdPrompt()];
|
||||
case 'backend-plugin-module':
|
||||
return [pluginIdPrompt(), moduleIdIdPrompt(), pluginPackagePrompt()];
|
||||
default:
|
||||
return [];
|
||||
}
|
||||
@@ -195,3 +228,13 @@ export function ownerPrompt(): DistinctQuestion {
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
// Reuses the same pattern as namePrompt/pluginIdPrompt but extended to support npm scopes
|
||||
// Matches: @scope/package-name, @scope/package, package-name, package
|
||||
const packageNamePattern = /^[a-z0-9]+(-[a-z0-9]+)*$/;
|
||||
const scopedPackageNamePattern =
|
||||
/^@[a-z0-9]+(-[a-z0-9]+)*\/[a-z0-9]+(-[a-z0-9]+)*$/;
|
||||
|
||||
function isValidNpmPackageName(name: string) {
|
||||
return packageNamePattern.test(name) || scopedPackageNamePattern.test(name);
|
||||
}
|
||||
|
||||
@@ -94,9 +94,15 @@ export type PortableTemplateInputRoleParams =
|
||||
pluginId: string;
|
||||
}
|
||||
| {
|
||||
role: 'frontend-plugin-module' | 'backend-plugin-module';
|
||||
role: 'frontend-plugin-module';
|
||||
pluginId: string;
|
||||
moduleId: string;
|
||||
}
|
||||
| {
|
||||
role: 'backend-plugin-module';
|
||||
pluginId: string;
|
||||
moduleId: string;
|
||||
pluginPackage: string;
|
||||
};
|
||||
|
||||
export type PortableTemplateInput = {
|
||||
|
||||
Reference in New Issue
Block a user