cli: added backend module templating factory
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/cli': patch
|
||||
---
|
||||
|
||||
Added the ability to create a plain backend module with the `new` command.
|
||||
@@ -140,6 +140,8 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/backend-common": "workspace:^",
|
||||
"@backstage/backend-plugin-api": "workspace:^",
|
||||
"@backstage/backend-test-utils": "workspace:^",
|
||||
"@backstage/config": "workspace:^",
|
||||
"@backstage/core-app-api": "workspace:^",
|
||||
"@backstage/core-components": "workspace:^",
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* 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 fs from 'fs-extra';
|
||||
import chalk from 'chalk';
|
||||
import camelCase from 'lodash/camelCase';
|
||||
import { paths } from '../../paths';
|
||||
import { addCodeownersEntry, getCodeownersFilePath } from '../../codeowners';
|
||||
import { createFactory, CreateContext } from '../types';
|
||||
import { addPackageDependency, Task } from '../../tasks';
|
||||
import {
|
||||
moduleIdIdPrompt,
|
||||
ownerPrompt,
|
||||
pluginIdPrompt,
|
||||
} from './common/prompts';
|
||||
import { executePluginPackageTemplate } from './common/tasks';
|
||||
|
||||
type Options = {
|
||||
id: string;
|
||||
moduleId: string;
|
||||
owner?: string;
|
||||
codeOwnersPath?: string;
|
||||
};
|
||||
|
||||
export const backendModule = createFactory<Options>({
|
||||
name: 'backend-module',
|
||||
description: 'A new backend module',
|
||||
optionsDiscovery: async () => ({
|
||||
codeOwnersPath: await getCodeownersFilePath(paths.targetRoot),
|
||||
}),
|
||||
optionsPrompts: [pluginIdPrompt(), moduleIdIdPrompt(), ownerPrompt()],
|
||||
async create(options: Options, ctx: CreateContext) {
|
||||
const { id: pluginId, moduleId } = options;
|
||||
const dirName = `${pluginId}-backend-module-${moduleId}`;
|
||||
const name = ctx.scope
|
||||
? `@${ctx.scope}/plugin-${dirName}`
|
||||
: `backstage-plugin-${dirName}`;
|
||||
|
||||
Task.log();
|
||||
Task.log(`Creating backend module ${chalk.cyan(name)}`);
|
||||
|
||||
const targetDir = ctx.isMonoRepo
|
||||
? paths.resolveTargetRoot('plugins', dirName)
|
||||
: paths.resolveTargetRoot(`backstage-plugin-${dirName}`);
|
||||
|
||||
const moduleCamelCase = camelCase(moduleId);
|
||||
const modulePascalCase =
|
||||
moduleCamelCase[0].toUpperCase() + moduleCamelCase.slice(1);
|
||||
const moduleVar = `${camelCase(pluginId)}Module${modulePascalCase}`;
|
||||
await executePluginPackageTemplate(ctx, {
|
||||
targetDir,
|
||||
templateName: 'default-backend-module',
|
||||
values: {
|
||||
pluginId,
|
||||
moduleId,
|
||||
name,
|
||||
moduleVar,
|
||||
packageVersion: ctx.defaultVersion,
|
||||
privatePackage: ctx.private,
|
||||
npmRegistry: ctx.npmRegistry,
|
||||
},
|
||||
});
|
||||
|
||||
if (await fs.pathExists(paths.resolveTargetRoot('packages/backend'))) {
|
||||
await Task.forItem('backend', 'adding dependency', async () => {
|
||||
await addPackageDependency(
|
||||
paths.resolveTargetRoot('packages/backend/package.json'),
|
||||
{
|
||||
dependencies: {
|
||||
[name]: `^${ctx.defaultVersion}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
if (options.owner) {
|
||||
await addCodeownersEntry(`/plugins/${dirName}`, options.owner);
|
||||
}
|
||||
|
||||
await Task.forCommand('yarn install', { cwd: targetDir, optional: true });
|
||||
await Task.forCommand('yarn lint --fix', {
|
||||
cwd: targetDir,
|
||||
optional: true,
|
||||
});
|
||||
},
|
||||
});
|
||||
@@ -33,6 +33,22 @@ export function pluginIdPrompt(): Prompt<{ id: string }> {
|
||||
};
|
||||
}
|
||||
|
||||
export function moduleIdIdPrompt(): Prompt<{ moduleId: string }> {
|
||||
return {
|
||||
type: 'input',
|
||||
name: 'moduleId',
|
||||
message: 'Enter the ID of the module [required]',
|
||||
validate: (value: string) => {
|
||||
if (!value) {
|
||||
return 'Please enter the ID of the module';
|
||||
} else if (!/^[a-z0-9]+(-[a-z0-9]+)*$/.test(value)) {
|
||||
return 'Module IDs must be lowercase and contain only letters, digits, and dashes.';
|
||||
}
|
||||
return true;
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export function ownerPrompt(): Prompt<{
|
||||
owner?: string;
|
||||
codeOwnersPath?: string;
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
export { frontendPlugin } from './frontendPlugin';
|
||||
export { backendPlugin } from './backendPlugin';
|
||||
export { backendModule } from './backendModule';
|
||||
export { webLibraryPackage } from './webLibraryPackage';
|
||||
export { pluginCommon } from './pluginCommon';
|
||||
export { pluginNode } from './pluginNode';
|
||||
|
||||
@@ -35,6 +35,8 @@ leaving any imports in place.
|
||||
*/
|
||||
|
||||
import { version as backendCommon } from '../../../../packages/backend-common/package.json';
|
||||
import { version as backendPluginApi } from '../../../../packages/backend-plugin-api/package.json';
|
||||
import { version as backendTestUtils } from '../../../../packages/backend-test-utils/package.json';
|
||||
import { version as cli } from '../../../../packages/cli/package.json';
|
||||
import { version as config } from '../../../../packages/config/package.json';
|
||||
import { version as coreAppApi } from '../../../../packages/core-app-api/package.json';
|
||||
@@ -47,6 +49,8 @@ import { version as scaffolderBackend } from '../../../../plugins/scaffolder-bac
|
||||
|
||||
export const packageVersions: Record<string, string> = {
|
||||
'@backstage/backend-common': backendCommon,
|
||||
'@backstage/backend-plugin-api': backendPluginApi,
|
||||
'@backstage/backend-test-utils': backendTestUtils,
|
||||
'@backstage/cli': cli,
|
||||
'@backstage/config': config,
|
||||
'@backstage/core-app-api': coreAppApi,
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
module.exports = require('@backstage/cli/config/eslint-factory')(__dirname);
|
||||
@@ -0,0 +1,5 @@
|
||||
# {{name}}
|
||||
|
||||
The {{moduleId}} backend module for the {{pluginId}} plugin.
|
||||
|
||||
_This plugin was created through the Backstage CLI_
|
||||
@@ -0,0 +1,42 @@
|
||||
{
|
||||
"name": "{{name}}",
|
||||
"description": "The {{moduleId}} backend module for the {{pluginId}} plugin.",
|
||||
"version": "{{packageVersion}}",
|
||||
"main": "src/index.ts",
|
||||
"types": "src/index.ts",
|
||||
"license": "Apache-2.0",
|
||||
{{#if privatePackage}}
|
||||
"private": {{privatePackage}},
|
||||
{{/if}}
|
||||
"publishConfig": {
|
||||
{{#if npmRegistry}}
|
||||
"registry": "{{npmRegistry}}",
|
||||
{{/if}}
|
||||
"access": "public",
|
||||
"main": "dist/index.cjs.js",
|
||||
"types": "dist/index.d.ts"
|
||||
},
|
||||
"backstage": {
|
||||
"role": "backend-plugin-module"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "backstage-cli package start",
|
||||
"build": "backstage-cli package build",
|
||||
"lint": "backstage-cli package lint",
|
||||
"test": "backstage-cli package test",
|
||||
"clean": "backstage-cli package clean",
|
||||
"prepack": "backstage-cli package prepack",
|
||||
"postpack": "backstage-cli package postpack"
|
||||
},
|
||||
"dependencies": {
|
||||
"@backstage/backend-common": "{{versionQuery '@backstage/backend-common'}}",
|
||||
"@backstage/backend-plugin-api": "{{versionQuery '@backstage/backend-plugin-api'}}"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/backend-test-utils": "{{versionQuery '@backstage/backend-test-utils'}}",
|
||||
"@backstage/cli": "{{versionQuery '@backstage/cli'}}"
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
/***/
|
||||
/**
|
||||
* The {{moduleId}} backend module for the {{pluginId}} plugin.
|
||||
*
|
||||
* @packageDocumentation
|
||||
*/
|
||||
|
||||
export { {{moduleVar}} } from './module';
|
||||
@@ -0,0 +1,14 @@
|
||||
import { coreServices, createBackendModule } from '@backstage/backend-plugin-api';
|
||||
|
||||
export const {{moduleVar}} = createBackendModule({
|
||||
pluginId: '{{pluginId}}',
|
||||
moduleId: '{{moduleId}}',
|
||||
register(reg) {
|
||||
reg.registerInit({
|
||||
deps: { logger: coreServices.logger },
|
||||
async init({ logger }) {
|
||||
logger.info('Hello World!')
|
||||
},
|
||||
});
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"extends": "@backstage/cli/config/tsconfig.json",
|
||||
"include": ["src"],
|
||||
"exclude": ["node_modules"],
|
||||
"compilerOptions": {
|
||||
"outDir": "dist-types",
|
||||
"rootDir": "."
|
||||
}
|
||||
}
|
||||
@@ -3578,6 +3578,8 @@ __metadata:
|
||||
resolution: "@backstage/cli@workspace:packages/cli"
|
||||
dependencies:
|
||||
"@backstage/backend-common": "workspace:^"
|
||||
"@backstage/backend-plugin-api": "workspace:^"
|
||||
"@backstage/backend-test-utils": "workspace:^"
|
||||
"@backstage/catalog-model": "workspace:^"
|
||||
"@backstage/cli-common": "workspace:^"
|
||||
"@backstage/cli-node": "workspace:^"
|
||||
|
||||
Reference in New Issue
Block a user