cli: decouple template versions from cli version

This commit is contained in:
Patrik Oldsberg
2020-10-27 18:22:21 +01:00
parent 2283fd92fc
commit 2711b9da42
9 changed files with 105 additions and 37 deletions
+7
View File
@@ -108,6 +108,13 @@
"yn": "^4.0.0"
},
"devDependencies": {
"@backstage/backend-common": "^0.1.1-alpha.25",
"@backstage/cli": "^0.1.1-alpha.25",
"@backstage/config": "^0.1.1-alpha.25",
"@backstage/core": "^0.1.1-alpha.25",
"@backstage/dev-utils": "^0.1.1-alpha.25",
"@backstage/test-utils": "^0.1.1-alpha.25",
"@backstage/theme": "^0.1.1-alpha.25",
"@types/diff": "^4.0.2",
"@types/fs-extra": "^9.0.1",
"@types/html-webpack-plugin": "^3.2.2",
@@ -28,8 +28,8 @@ import {
getCodeownersFilePath,
} from '../../lib/codeowners';
import { paths } from '../../lib/paths';
import { versions } from '../../lib/version';
import { Task, templatingTask } from '../../lib/tasks';
import { version as backstageVersion } from '../../lib/version';
const exec = promisify(execCb);
@@ -243,7 +243,7 @@ export default async (cmd: Command) => {
? paths.resolveTargetRoot('plugins', pluginId)
: paths.resolveTargetRoot(pluginId);
const ownerIds = parseOwnerIds(answers.owner);
const { version } = isMonoRepo
const { version: pluginVersion } = isMonoRepo
? await fs.readJson(paths.resolveTargetRoot('lerna.json'))
: { version: '0.1.0' };
@@ -259,14 +259,18 @@ export default async (cmd: Command) => {
Task.section('Preparing files');
await templatingTask(templateDir, tempDir, {
...answers,
version,
backstageVersion,
name,
privatePackage,
npmRegistry,
});
await templatingTask(
templateDir,
tempDir,
{
...answers,
pluginVersion,
name,
privatePackage,
npmRegistry,
},
versions,
);
Task.section('Moving to final location');
await movePlugin(tempDir, pluginDir, pluginId);
@@ -276,7 +280,7 @@ export default async (cmd: Command) => {
if ((await fs.pathExists(appPackage)) && !cmd.backend) {
Task.section('Adding plugin as dependency in app');
await addPluginDependencyToApp(paths.targetRoot, name, version);
await addPluginDependencyToApp(paths.targetRoot, name, pluginVersion);
Task.section('Import plugin in app');
await addPluginToApp(paths.targetRoot, pluginId, name);
+5 -9
View File
@@ -25,13 +25,12 @@ import {
yesPromptFunc,
} from '../../lib/diff';
import { paths } from '../../lib/paths';
import { version as backstageVersion } from '../../lib/version';
export type PluginData = {
id: string;
name: string;
privatePackage: string;
version: string;
pluginVersion: string;
npmRegistry: string;
};
@@ -62,10 +61,7 @@ export default async (cmd: Command) => {
}
const data = await readPluginData();
const templateFiles = await diffTemplateFiles('default-plugin', {
backstageVersion,
...data,
});
const templateFiles = await diffTemplateFiles('default-plugin', data);
await handleAllFiles(fileHandlers, templateFiles, promptFunc);
await finalize();
};
@@ -74,13 +70,13 @@ export default async (cmd: Command) => {
async function readPluginData(): Promise<PluginData> {
let name: string;
let privatePackage: string;
let version: string;
let pluginVersion: string;
let npmRegistry: string;
try {
const pkg = require(paths.resolveTarget('package.json'));
name = pkg.name;
privatePackage = pkg.private;
version = pkg.version;
pluginVersion = pkg.version;
const scope = name.split('/')[0];
if (`${scope}:registry` in pkg.publishConfig) {
const registryURL = pkg.publishConfig[`${scope}:registry`];
@@ -102,5 +98,5 @@ async function readPluginData(): Promise<PluginData> {
const id = pluginIdMatch[1];
return { id, name, privatePackage, version, npmRegistry };
return { id, name, privatePackage, pluginVersion, npmRegistry };
}
+11 -1
View File
@@ -24,6 +24,7 @@ import handlebars from 'handlebars';
import recursiveReadDir from 'recursive-readdir';
import { paths } from '../paths';
import { FileDiff } from './types';
import { versions } from '../../lib/version';
export type TemplatedFile = {
path: string;
@@ -40,7 +41,16 @@ async function readTemplateFile(
return contents;
}
return handlebars.compile(contents)(templateVars);
return handlebars.compile(contents)(templateVars, {
helpers: {
version(name: string) {
if (versions[name]) {
return versions[name];
}
throw new Error(`No version available for package ${name}`);
},
},
});
}
async function readTemplate(
+11 -5
View File
@@ -33,7 +33,8 @@ describe('templatingTask', () => {
// Files content
const testFileContent = 'testing';
const testVersionFileContent = 'version: {{version}}';
const testVersionFileContent =
"version: {{pluginVersion}} {{version 'mock-pkg'}}";
mockFs({
[tmplDir]: {
@@ -45,15 +46,20 @@ describe('templatingTask', () => {
[destDir]: {},
});
await templatingTask(tmplDir, destDir, {
version: '0.0.0',
});
await templatingTask(
tmplDir,
destDir,
{
version: '0.0.0',
},
{ 'mock-pkg': '0.1.2' },
);
await expect(
fs.readFile(resolvePath(destDir, 'test.txt'), 'utf8'),
).resolves.toBe(testFileContent);
await expect(
fs.readFile(resolvePath(destDir, 'sub/version.txt'), 'utf8'),
).resolves.toBe('version: 0.0.0');
).resolves.toBe('version: 0.0.0 0.1.2');
});
});
+14 -1
View File
@@ -69,6 +69,7 @@ export async function templatingTask(
templateDir: string,
destinationDir: string,
context: any,
versions: { [name: string]: string },
) {
const files = await recursive(templateDir).catch(error => {
throw new Error(`Failed to read template directory: ${error.message}`);
@@ -85,7 +86,19 @@ export async function templatingTask(
const template = await fs.readFile(file);
const compiled = handlebars.compile(template.toString());
const contents = compiled({ name: basename(destination), ...context });
const contents = compiled(
{ name: basename(destination), ...context },
{
helpers: {
version(name: string) {
if (versions[name]) {
return versions[name];
}
throw new Error(`No version available for package ${name}`);
},
},
},
);
await fs.writeFile(destination, contents).catch(error => {
throw new Error(
+32
View File
@@ -17,6 +17,38 @@
import fs from 'fs-extra';
import { paths } from './paths';
/* eslint-disable import/no-extraneous-dependencies,monorepo/no-internal-import */
/*
This is a list of all packages used by the templates. If dependencies are added or removed,
this list should be updated as well.
The list, and the accompanying devDependencies entries, are here to ensure correct versioning
and bumping of this package. Without this list the version would not be bumped unless we
manually trigger a release.
This does not create an actual dependency on these packages and does not bring in any code.
Rollup will extract the value of the version field in each package at build time without
leaving any imports in place.
*/
import { version as backendCommon } from '@backstage/backend-common/package.json';
import { version as cli } from '@backstage/cli/package.json';
import { version as config } from '@backstage/config/package.json';
import { version as core } from '@backstage/core/package.json';
import { version as devUtils } from '@backstage/dev-utils/package.json';
import { version as testUtils } from '@backstage/test-utils/package.json';
import { version as theme } from '@backstage/theme/package.json';
export const versions: { [name: string]: string } = {
'@backstage/backend-common': backendCommon,
'@backstage/cli': cli,
'@backstage/config': config,
'@backstage/core': core,
'@backstage/dev-utils': devUtils,
'@backstage/test-utils': testUtils,
'@backstage/theme': theme,
};
export function findVersion() {
const pkgContent = fs.readFileSync(paths.resolveOwn('package.json'), 'utf8');
return JSON.parse(pkgContent).version;
@@ -1,6 +1,6 @@
{
"name": "{{name}}",
"version": "{{version}}",
"version": "{{pluginVersion}}",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -23,8 +23,8 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/backend-common": "^{{backstageVersion}}",
"@backstage/config": "^{{backstageVersion}}",
"@backstage/backend-common": "^{{version '@backstage/backend-common'}}",
"@backstage/config": "^{{version '@backstage/config'}}",
"@types/express": "^4.17.6",
"express": "^4.17.1",
"express-promise-router": "^3.0.3",
@@ -33,7 +33,7 @@
"yn": "^4.0.0"
},
"devDependencies": {
"@backstage/cli": "^{{backstageVersion}}",
"@backstage/cli": "^{{version '@backstage/cli'}}",
"@types/supertest": "^2.0.8",
"supertest": "^4.0.2",
"msw": "^0.21.2"
@@ -1,6 +1,6 @@
{
"name": "{{name}}",
"version": "{{version}}",
"version": "{{pluginVersion}}",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -24,8 +24,8 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/core": "^{{backstageVersion}}",
"@backstage/theme": "^{{backstageVersion}}",
"@backstage/core": "^{{version '@backstage/core'}}",
"@backstage/theme": "^{{version '@backstage/theme'}}",
"@material-ui/core": "^4.11.0",
"@material-ui/icons": "^4.9.1",
"@material-ui/lab": "4.0.0-alpha.45",
@@ -34,9 +34,9 @@
"react-use": "^15.3.3"
},
"devDependencies": {
"@backstage/cli": "^{{backstageVersion}}",
"@backstage/dev-utils": "^{{backstageVersion}}",
"@backstage/test-utils": "^{{backstageVersion}}",
"@backstage/cli": "^{{version '@backstage/cli'}}",
"@backstage/dev-utils": "^{{version '@backstage/dev-utils'}}",
"@backstage/test-utils": "^{{version '@backstage/test-utils'}}",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
"@testing-library/user-event": "^12.0.7",