Add additionalActions to new command
Signed-off-by: Min Kim <minkimcello@gmail.com>
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright 2024 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 { paths } from '../../lib/paths';
|
||||
import { addPackageDependency, addToBackend, Task } from '../../lib/tasks';
|
||||
|
||||
export interface AdditionalActionsOptions {
|
||||
name: string;
|
||||
version: string;
|
||||
id: string;
|
||||
extension: string;
|
||||
}
|
||||
|
||||
export async function installFrontend(options: AdditionalActionsOptions) {
|
||||
if (await fs.pathExists(paths.resolveTargetRoot('packages/app'))) {
|
||||
await Task.forItem('app', 'adding dependency', async () => {
|
||||
await addPackageDependency(
|
||||
paths.resolveTargetRoot('packages/app/package.json'),
|
||||
{
|
||||
dependencies: {
|
||||
[options.name]: `^${options.version}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export async function addFrontendLegacy(options: AdditionalActionsOptions) {
|
||||
await Task.forItem('app', 'adding import', async () => {
|
||||
const pluginsFilePath = paths.resolveTargetRoot('packages/app/src/App.tsx');
|
||||
if (!(await fs.pathExists(pluginsFilePath))) {
|
||||
return;
|
||||
}
|
||||
|
||||
const content = await fs.readFile(pluginsFilePath, 'utf8');
|
||||
const revLines = content.split('\n').reverse();
|
||||
|
||||
const lastImportIndex = revLines.findIndex(line =>
|
||||
line.match(/ from ("|').*("|')/),
|
||||
);
|
||||
const lastRouteIndex = revLines.findIndex(line =>
|
||||
line.match(/<\/FlatRoutes/),
|
||||
);
|
||||
|
||||
if (lastImportIndex !== -1 && lastRouteIndex !== -1) {
|
||||
const importLine = `import { ${options.extension} } from '${options.name}';`;
|
||||
if (!content.includes(importLine)) {
|
||||
revLines.splice(lastImportIndex, 0, importLine);
|
||||
}
|
||||
|
||||
const componentLine = `<Route path="/${options.id}" element={<${options.extension} />} />`;
|
||||
if (!content.includes(componentLine)) {
|
||||
const [indentation] = revLines[lastRouteIndex + 1].match(/^\s*/) ?? [];
|
||||
revLines.splice(lastRouteIndex + 1, 0, indentation + componentLine);
|
||||
}
|
||||
|
||||
const newContent = revLines.reverse().join('\n');
|
||||
await fs.writeFile(pluginsFilePath, newContent, 'utf8');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export async function installBackend(options: AdditionalActionsOptions) {
|
||||
if (await fs.pathExists(paths.resolveTargetRoot('packages/backend'))) {
|
||||
await Task.forItem('backend', 'adding dependency', async () => {
|
||||
await addPackageDependency(
|
||||
paths.resolveTargetRoot('packages/backend/package.json'),
|
||||
{
|
||||
dependencies: {
|
||||
[options.name]: `^${options.version}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export async function addBackend(options: AdditionalActionsOptions) {
|
||||
await addToBackend(options.name);
|
||||
}
|
||||
@@ -38,6 +38,7 @@ import {
|
||||
promptOptions,
|
||||
populateOptions,
|
||||
createDirName,
|
||||
runAdditionalActions,
|
||||
} from './util';
|
||||
|
||||
export default async () => {
|
||||
@@ -66,43 +67,55 @@ export default async () => {
|
||||
const dirName = createDirName(template, options);
|
||||
const targetDir = paths.resolveTargetRoot(options.targetPath, dirName);
|
||||
|
||||
const packageName = resolvePackageName({
|
||||
baseName: dirName,
|
||||
scope: options.scope,
|
||||
plugin: template.plugin ?? true,
|
||||
});
|
||||
|
||||
const moduleVar = `${camelCase(options.id)}Module${camelCase(
|
||||
options.moduleId,
|
||||
)[0].toUpperCase()}${camelCase(options.moduleId).slice(1)}`; // used in default-backend-module template
|
||||
const extension = `${upperFirst(camelCase(options.id))}Page`; // used in default-plugin template
|
||||
const pluginVar = `${camelCase(options.id)}Plugin`; // used in default-backend-plugin and default-plugin template
|
||||
|
||||
let modified = false;
|
||||
try {
|
||||
await executePluginPackageTemplate(
|
||||
{
|
||||
private: options.private,
|
||||
defaultVersion: options.baseVersion,
|
||||
license: options.license,
|
||||
isMonoRepo: await isMonoRepo(),
|
||||
createTemporaryDirectory,
|
||||
markAsModified() {
|
||||
modified = true;
|
||||
if (options.install) {
|
||||
await executePluginPackageTemplate(
|
||||
{
|
||||
private: options.private,
|
||||
defaultVersion: options.baseVersion,
|
||||
license: options.license,
|
||||
isMonoRepo: await isMonoRepo(),
|
||||
createTemporaryDirectory,
|
||||
markAsModified() {
|
||||
modified = true;
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
targetDir,
|
||||
templateDir: template.templatePath,
|
||||
values: {
|
||||
name: resolvePackageName({
|
||||
baseName: dirName,
|
||||
scope: options.scope,
|
||||
plugin: template.plugin ?? true,
|
||||
}),
|
||||
pluginVersion: options.baseVersion,
|
||||
moduleVar: `${camelCase(options.id)}Module${camelCase(
|
||||
options.moduleId,
|
||||
)[0].toUpperCase()}${camelCase(options.moduleId).slice(1)}`, // used in default-backend-module template
|
||||
extension: `${upperFirst(camelCase(options.id))}Page`, // used in default-plugin template
|
||||
pluginVar: `${camelCase(options.id)}Plugin`, // used in default-backend-plugin and default-plugin template
|
||||
...options,
|
||||
{
|
||||
targetDir,
|
||||
templateDir: template.templatePath,
|
||||
values: {
|
||||
name: packageName,
|
||||
pluginVersion: options.baseVersion,
|
||||
moduleVar,
|
||||
extension,
|
||||
pluginVar,
|
||||
...options,
|
||||
},
|
||||
},
|
||||
},
|
||||
);
|
||||
);
|
||||
}
|
||||
|
||||
// create additional actions
|
||||
// install to app
|
||||
// install to backend
|
||||
// add to backend/index.ts
|
||||
if (template.additionalActions?.length) {
|
||||
await runAdditionalActions(template.additionalActions, {
|
||||
name: packageName,
|
||||
version: options.baseVersion,
|
||||
id: options.id, // for frontend legacy
|
||||
extension: extension, // for frontend legacy
|
||||
});
|
||||
}
|
||||
|
||||
if (options.install) {
|
||||
// 🚨 temporary
|
||||
|
||||
@@ -25,7 +25,15 @@ import {
|
||||
npmRegistryPrompt,
|
||||
ownerPrompt,
|
||||
} from '../../lib/new/factories/common/prompts';
|
||||
|
||||
import defaultTemplates from '../../../templates';
|
||||
import {
|
||||
installFrontend,
|
||||
addFrontendLegacy,
|
||||
installBackend,
|
||||
addBackend,
|
||||
AdditionalActionsOptions,
|
||||
} from './additionalActions';
|
||||
|
||||
import { Template, TemplateLocation, ConfigurablePrompt } from './types';
|
||||
|
||||
@@ -219,3 +227,27 @@ export function createDirName(template: Template, options: Options) {
|
||||
}
|
||||
return options.id;
|
||||
}
|
||||
|
||||
export async function runAdditionalActions(
|
||||
additionalActions: string[],
|
||||
options: AdditionalActionsOptions,
|
||||
) {
|
||||
for (const action of additionalActions) {
|
||||
switch (action) {
|
||||
case 'install-frontend':
|
||||
await installFrontend(options);
|
||||
break;
|
||||
case 'add-frontend-legacy':
|
||||
await addFrontendLegacy(options);
|
||||
break;
|
||||
case 'install-backend':
|
||||
await installBackend(options);
|
||||
break;
|
||||
case 'add-backend':
|
||||
await addBackend(options);
|
||||
break;
|
||||
default:
|
||||
throw new Error(`${action} is not a valid additional action`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -198,14 +198,9 @@ export async function addPackageDependency(
|
||||
}
|
||||
}
|
||||
|
||||
export async function addToBackend(
|
||||
name: string,
|
||||
options: {
|
||||
type: 'plugin' | 'module';
|
||||
},
|
||||
) {
|
||||
export async function addToBackend(name: string) {
|
||||
if (await fs.pathExists(paths.resolveTargetRoot('packages/backend'))) {
|
||||
await Task.forItem('backend', `adding ${options.type}`, async () => {
|
||||
await Task.forItem('backend', `adding ${name}`, async () => {
|
||||
const backendFilePath = paths.resolveTargetRoot(
|
||||
'packages/backend/src/index.ts',
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user