From fe3211cf3852caacd8d030d2ce10c1ad31b11042 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Sun, 31 Jan 2021 15:12:29 +0100 Subject: [PATCH] cli: make create-plugin add extension to app if possible --- .../commands/create-plugin/createPlugin.ts | 48 ++++++++++++++++++- .../default-plugin/dev/index.tsx.hbs | 4 +- .../templates/default-plugin/src/index.ts.hbs | 2 +- .../default-plugin/src/plugin.ts.hbs | 2 +- 4 files changed, 50 insertions(+), 6 deletions(-) diff --git a/packages/cli/src/commands/create-plugin/createPlugin.ts b/packages/cli/src/commands/create-plugin/createPlugin.ts index c9f1664411..affbf64922 100644 --- a/packages/cli/src/commands/create-plugin/createPlugin.ts +++ b/packages/cli/src/commands/create-plugin/createPlugin.ts @@ -21,6 +21,7 @@ import inquirer, { Answers, Question } from 'inquirer'; import { exec as execCb } from 'child_process'; import { resolve as resolvePath, join as joinPath } from 'path'; import camelCase from 'lodash/camelCase'; +import upperFirst from 'lodash/upperFirst'; import os from 'os'; import { Command } from 'commander'; import { @@ -105,7 +106,7 @@ export async function addPluginDependencyToApp( }); } -export async function addPluginToApp( +export async function addPluginImportToApp( rootDir: string, pluginVar: string, pluginPackage: string, @@ -123,6 +124,46 @@ export async function addPluginToApp( }); } +export async function addPluginExtensionToApp( + pluginId: string, + extensionName: string, + pluginPackage: string, +) { + const pluginsFilePath = paths.resolveTargetRoot('packages/app/src/App.tsx'); + if (!(await fs.pathExists(pluginsFilePath))) { + return; + } + + await Task.forItem('processing', pluginsFilePath, async () => { + 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) { + revLines.splice( + lastImportIndex, + 0, + `import { ${extensionName} } from '${pluginPackage}';`, + ); + const [indentation] = revLines[lastRouteIndex + 1].match(/^\s*/) ?? []; + revLines.splice( + lastRouteIndex + 1, + 0, + `${indentation}}/>`, + ); + + const newContent = revLines.reverse().join('\n'); + await fs.writeFile(pluginsFilePath, newContent, 'utf8'); + } + }); +} + async function cleanUp(tempDir: string) { await Task.forItem('remove', 'temporary directory', async () => { await fs.remove(tempDir); @@ -221,6 +262,7 @@ export default async (cmd: Command) => { ? `@${cmd.scope.replace(/^@/, '')}/plugin-${pluginId}` : `plugin-${pluginId}`; const pluginVar = `${camelCase(answers.id)}Plugin`; + const extensionName = `${upperFirst(camelCase(answers.id))}Page`; const npmRegistry = cmd.npmRegistry && cmd.scope ? cmd.npmRegistry : ''; const privatePackage = cmd.private === false ? false : true; const isMonoRepo = await fs.pathExists(paths.resolveTargetRoot('lerna.json')); @@ -259,6 +301,7 @@ export default async (cmd: Command) => { ...answers, pluginVar, pluginVersion, + extensionName, name, privatePackage, npmRegistry, @@ -277,7 +320,8 @@ export default async (cmd: Command) => { await addPluginDependencyToApp(paths.targetRoot, name, pluginVersion); Task.section('Import plugin in app'); - await addPluginToApp(paths.targetRoot, pluginVar, name); + await addPluginImportToApp(paths.targetRoot, pluginVar, name); + await addPluginExtensionToApp(pluginId, extensionName, name); } if (ownerIds && ownerIds.length) { diff --git a/packages/cli/templates/default-plugin/dev/index.tsx.hbs b/packages/cli/templates/default-plugin/dev/index.tsx.hbs index 13705ecd58..ade00a1613 100644 --- a/packages/cli/templates/default-plugin/dev/index.tsx.hbs +++ b/packages/cli/templates/default-plugin/dev/index.tsx.hbs @@ -1,11 +1,11 @@ import React from 'react'; import { createDevApp } from '@backstage/dev-utils'; -import { {{ pluginVar }}, ExamplePage } from '../src/plugin'; +import { {{ pluginVar }}, {{ extensionName }} } from '../src/plugin'; createDevApp() .registerPlugin({{ pluginVar }}) .addPage({ - element: , + element: <{{ extensionName }} />, title: 'Root Page', }) .render(); diff --git a/packages/cli/templates/default-plugin/src/index.ts.hbs b/packages/cli/templates/default-plugin/src/index.ts.hbs index 165c8419e1..be4881efaf 100644 --- a/packages/cli/templates/default-plugin/src/index.ts.hbs +++ b/packages/cli/templates/default-plugin/src/index.ts.hbs @@ -1 +1 @@ -export { {{ pluginVar }} } from './plugin'; +export { {{ pluginVar }}, {{ extensionName }} } from './plugin'; diff --git a/packages/cli/templates/default-plugin/src/plugin.ts.hbs b/packages/cli/templates/default-plugin/src/plugin.ts.hbs index 2a836592f7..0ae5356fd1 100644 --- a/packages/cli/templates/default-plugin/src/plugin.ts.hbs +++ b/packages/cli/templates/default-plugin/src/plugin.ts.hbs @@ -9,7 +9,7 @@ export const {{ pluginVar }} = createPlugin({ }, }); -export const ExamplePage = {{ pluginVar }}.provide( +export const {{ extensionName }} = {{ pluginVar }}.provide( createRoutableExtension({ component: () => import('./components/ExampleComponent').then(m => m.ExampleComponent),