cli: common helper for executing plugin package templates
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
@@ -16,8 +16,6 @@
|
||||
|
||||
import fs from 'fs-extra';
|
||||
import camelCase from 'lodash/camelCase';
|
||||
import upperFirst from 'lodash/upperFirst';
|
||||
import chalk from 'chalk';
|
||||
import { paths } from '../../paths';
|
||||
import {
|
||||
addCodeownersEntry,
|
||||
@@ -25,10 +23,9 @@ import {
|
||||
parseOwnerIds,
|
||||
} from '../../codeowners';
|
||||
import { createFactory, CreateContext } from '../types';
|
||||
import { Lockfile } from '../../versioning';
|
||||
import { addPackageDependency, Task, templatingTask } from '../../tasks';
|
||||
import { createPackageVersionProvider } from '../../version';
|
||||
import { addPackageDependency, Task } from '../../tasks';
|
||||
import { ownerPrompt, pluginIdPrompt } from './common/prompts';
|
||||
import { executePluginPackageTemplate } from './common/tasks';
|
||||
|
||||
type Options = {
|
||||
id: string;
|
||||
@@ -47,38 +44,14 @@ export const backendPlugin = createFactory<Options>({
|
||||
const id = `${options.id}-backend`;
|
||||
const name = ctx.scope ? `@${ctx.scope}/plugin-${id}` : `plugin-${id}`;
|
||||
|
||||
const pluginDir = ctx.isMonoRepo
|
||||
const targetDir = ctx.isMonoRepo
|
||||
? paths.resolveTargetRoot('plugins', id)
|
||||
: paths.resolveTargetRoot(`backstage-plugin-${id}`);
|
||||
|
||||
let lockfile: Lockfile | undefined;
|
||||
try {
|
||||
lockfile = await Lockfile.load(paths.resolveTargetRoot('yarn.lock'));
|
||||
} catch (error) {
|
||||
console.warn(`No yarn.lock available, ${error}`);
|
||||
}
|
||||
|
||||
Task.section('Validating prerequisites');
|
||||
const shortPluginDir = pluginDir.replace(`${paths.targetRoot}/`, '');
|
||||
await Task.forItem('availability', shortPluginDir, async () => {
|
||||
if (await fs.pathExists(pluginDir)) {
|
||||
throw new Error(
|
||||
`A backend plugin with the same ID already exists at ${chalk.cyan(
|
||||
shortPluginDir,
|
||||
)}. Please try again with a different ID.`,
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
const tempDir = await Task.forItem('creating', 'temp dir', async () => {
|
||||
return await ctx.createTemporaryDirectory(`backstage-plugin-${id}`);
|
||||
});
|
||||
|
||||
Task.section('Executing plugin template');
|
||||
await templatingTask(
|
||||
paths.resolveOwn('templates/default-backend-plugin'),
|
||||
tempDir,
|
||||
{
|
||||
await executePluginPackageTemplate(ctx, {
|
||||
targetDir,
|
||||
templateName: 'default-backend-plugin',
|
||||
values: {
|
||||
id,
|
||||
name,
|
||||
pluginVar: `${camelCase(id)}Plugin`,
|
||||
@@ -86,20 +59,8 @@ export const backendPlugin = createFactory<Options>({
|
||||
privatePackage: ctx.private,
|
||||
npmRegistry: ctx.npmRegistry,
|
||||
},
|
||||
createPackageVersionProvider(lockfile),
|
||||
);
|
||||
|
||||
Task.section('Installing plugin');
|
||||
await Task.forItem('moving', shortPluginDir, async () => {
|
||||
await fs.move(tempDir, pluginDir).catch(error => {
|
||||
throw new Error(
|
||||
`Failed to move plugin from ${tempDir} to ${pluginDir}, ${error.message}`,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
ctx.markAsModified();
|
||||
|
||||
if (await fs.pathExists(paths.resolveTargetRoot('packages/backend'))) {
|
||||
await Task.forItem('backend', 'adding dependency', async () => {
|
||||
await addPackageDependency(
|
||||
@@ -124,9 +85,9 @@ export const backendPlugin = createFactory<Options>({
|
||||
}
|
||||
}
|
||||
|
||||
await Task.forCommand('yarn install', { cwd: pluginDir, optional: true });
|
||||
await Task.forCommand('yarn install', { cwd: targetDir, optional: true });
|
||||
await Task.forCommand('yarn lint --fix', {
|
||||
cwd: pluginDir,
|
||||
cwd: targetDir,
|
||||
optional: true,
|
||||
});
|
||||
},
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* 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 { paths } from '../../../paths';
|
||||
import { Task, templatingTask } from '../../../tasks';
|
||||
import { Lockfile } from '../../../versioning';
|
||||
import { createPackageVersionProvider } from '../../../version';
|
||||
import { CreateContext } from '../../types';
|
||||
|
||||
export async function executePluginPackageTemplate(
|
||||
ctx: CreateContext,
|
||||
options: {
|
||||
templateName: string;
|
||||
targetDir: string;
|
||||
values: Record<string, unknown>;
|
||||
},
|
||||
) {
|
||||
const { targetDir } = options;
|
||||
|
||||
let lockfile: Lockfile | undefined;
|
||||
try {
|
||||
lockfile = await Lockfile.load(paths.resolveTargetRoot('yarn.lock'));
|
||||
} catch {
|
||||
/* ignored */
|
||||
}
|
||||
|
||||
Task.section('Checking Prerequisites');
|
||||
const shortPluginDir = targetDir.replace(`${paths.targetRoot}/`, '');
|
||||
await Task.forItem('availability', shortPluginDir, async () => {
|
||||
if (await fs.pathExists(targetDir)) {
|
||||
throw new Error(
|
||||
`A package with the same plugin ID already exists at ${chalk.cyan(
|
||||
shortPluginDir,
|
||||
)}. Please try again with a different ID.`,
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
const tempDir = await Task.forItem('creating', 'temp dir', async () => {
|
||||
return await ctx.createTemporaryDirectory('backstage-create');
|
||||
});
|
||||
|
||||
Task.section('Executing Template');
|
||||
await templatingTask(
|
||||
paths.resolveOwn('templates', options.templateName),
|
||||
tempDir,
|
||||
options.values,
|
||||
createPackageVersionProvider(lockfile),
|
||||
);
|
||||
|
||||
Task.section('Installing');
|
||||
await Task.forItem('moving', shortPluginDir, async () => {
|
||||
await fs.move(tempDir, targetDir).catch(error => {
|
||||
throw new Error(
|
||||
`Failed to move package from ${tempDir} to ${targetDir}, ${error.message}`,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
ctx.markAsModified();
|
||||
}
|
||||
@@ -17,7 +17,6 @@
|
||||
import fs from 'fs-extra';
|
||||
import camelCase from 'lodash/camelCase';
|
||||
import upperFirst from 'lodash/upperFirst';
|
||||
import chalk from 'chalk';
|
||||
import { paths } from '../../paths';
|
||||
import {
|
||||
addCodeownersEntry,
|
||||
@@ -25,10 +24,9 @@ import {
|
||||
parseOwnerIds,
|
||||
} from '../../codeowners';
|
||||
import { createFactory, CreateContext } from '../types';
|
||||
import { Lockfile } from '../../versioning';
|
||||
import { addPackageDependency, Task, templatingTask } from '../../tasks';
|
||||
import { createPackageVersionProvider } from '../../version';
|
||||
import { addPackageDependency, Task } from '../../tasks';
|
||||
import { ownerPrompt, pluginIdPrompt } from './common/prompts';
|
||||
import { executePluginPackageTemplate } from './common/tasks';
|
||||
|
||||
type Options = {
|
||||
id: string;
|
||||
@@ -49,60 +47,24 @@ export const frontendPlugin = createFactory<Options>({
|
||||
const name = ctx.scope ? `@${ctx.scope}/plugin-${id}` : `plugin-${id}`;
|
||||
const extensionName = `${upperFirst(camelCase(id))}Page`;
|
||||
|
||||
const pluginDir = ctx.isMonoRepo
|
||||
const targetDir = ctx.isMonoRepo
|
||||
? paths.resolveTargetRoot('plugins', id)
|
||||
: paths.resolveTargetRoot(`backstage-plugin-${id}`);
|
||||
|
||||
let lockfile: Lockfile | undefined;
|
||||
try {
|
||||
lockfile = await Lockfile.load(paths.resolveTargetRoot('yarn.lock'));
|
||||
} catch (error) {
|
||||
console.warn(`No yarn.lock available, ${error}`);
|
||||
}
|
||||
|
||||
Task.section('Validating prerequisites');
|
||||
const shortPluginDir = pluginDir.replace(`${paths.targetRoot}/`, '');
|
||||
await Task.forItem('availability', shortPluginDir, async () => {
|
||||
if (await fs.pathExists(pluginDir)) {
|
||||
throw new Error(
|
||||
`A plugin with the same ID already exists at ${chalk.cyan(
|
||||
shortPluginDir,
|
||||
)}. Please try again with a different ID.`,
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
const tempDir = await Task.forItem('creating', 'temp dir', async () => {
|
||||
return await ctx.createTemporaryDirectory(`backstage-plugin-${id}`);
|
||||
});
|
||||
|
||||
Task.section('Executing plugin template');
|
||||
await templatingTask(
|
||||
paths.resolveOwn('templates/default-plugin'),
|
||||
tempDir,
|
||||
{
|
||||
await executePluginPackageTemplate(ctx, {
|
||||
targetDir,
|
||||
templateName: 'default-plugin',
|
||||
values: {
|
||||
id,
|
||||
name,
|
||||
extensionName,
|
||||
pluginVar: `${camelCase(id)}Plugin`,
|
||||
pluginVersion: ctx.defaultVersion,
|
||||
extensionName,
|
||||
name,
|
||||
privatePackage: ctx.private,
|
||||
npmRegistry: ctx.npmRegistry,
|
||||
},
|
||||
createPackageVersionProvider(lockfile),
|
||||
);
|
||||
|
||||
Task.section('Installing plugin');
|
||||
await Task.forItem('moving', shortPluginDir, async () => {
|
||||
await fs.move(tempDir, pluginDir).catch(error => {
|
||||
throw new Error(
|
||||
`Failed to move plugin from ${tempDir} to ${pluginDir}, ${error.message}`,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
ctx.markAsModified();
|
||||
|
||||
if (await fs.pathExists(paths.resolveTargetRoot('packages/app'))) {
|
||||
await Task.forItem('app', 'adding dependency', async () => {
|
||||
await addPackageDependency(
|
||||
@@ -163,9 +125,9 @@ export const frontendPlugin = createFactory<Options>({
|
||||
}
|
||||
}
|
||||
|
||||
await Task.forCommand('yarn install', { cwd: pluginDir, optional: true });
|
||||
await Task.forCommand('yarn install', { cwd: targetDir, optional: true });
|
||||
await Task.forCommand('yarn lint --fix', {
|
||||
cwd: pluginDir,
|
||||
cwd: targetDir,
|
||||
optional: true,
|
||||
});
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user