cli: make create-plugin prefer version ranges that are already in the lockfile
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/cli': patch
|
||||
---
|
||||
|
||||
The `create-plugin` command now prefers dependency versions ranges that are already in the lockfile.
|
||||
@@ -30,8 +30,9 @@ import {
|
||||
getCodeownersFilePath,
|
||||
} from '../../lib/codeowners';
|
||||
import { paths } from '../../lib/paths';
|
||||
import { packageVersions } from '../../lib/version';
|
||||
import { Task, templatingTask } from '../../lib/tasks';
|
||||
import { Lockfile } from '../../lib/versioning';
|
||||
import { createPackageVersionProvider } from '../../lib/version';
|
||||
|
||||
const exec = promisify(execCb);
|
||||
|
||||
@@ -262,6 +263,13 @@ export default async (cmd: Command) => {
|
||||
? await fs.readJson(paths.resolveTargetRoot('lerna.json'))
|
||||
: { version: '0.1.0' };
|
||||
|
||||
let lockfile: Lockfile | undefined;
|
||||
try {
|
||||
lockfile = await Lockfile.load(paths.resolveTargetRoot('yarn.lock'));
|
||||
} catch (error) {
|
||||
console.warn(`No yarn.lock available, ${error}`);
|
||||
}
|
||||
|
||||
Task.log();
|
||||
Task.log('Creating the plugin...');
|
||||
|
||||
@@ -288,7 +296,7 @@ export default async (cmd: Command) => {
|
||||
privatePackage,
|
||||
npmRegistry,
|
||||
},
|
||||
packageVersions,
|
||||
createPackageVersionProvider(lockfile),
|
||||
);
|
||||
|
||||
Task.section('Moving to final location');
|
||||
|
||||
@@ -34,7 +34,7 @@ describe('templatingTask', () => {
|
||||
// Files content
|
||||
const testFileContent = 'testing';
|
||||
const testVersionFileContent =
|
||||
"version: {{pluginVersion}} {{version 'mock-pkg'}}";
|
||||
"version: {{pluginVersion}} {{versionQuery 'mock-pkg'}}";
|
||||
|
||||
mockFs({
|
||||
[tmplDir]: {
|
||||
@@ -52,7 +52,7 @@ describe('templatingTask', () => {
|
||||
{
|
||||
pluginVersion: '0.0.0',
|
||||
},
|
||||
{ 'mock-pkg': '0.1.2' },
|
||||
() => '^0.1.2',
|
||||
);
|
||||
|
||||
await expect(
|
||||
@@ -60,6 +60,6 @@ describe('templatingTask', () => {
|
||||
).resolves.toBe(testFileContent);
|
||||
await expect(
|
||||
fs.readFile(resolvePath(destDir, 'sub/version.txt'), 'utf8'),
|
||||
).resolves.toBe('version: 0.0.0 0.1.2');
|
||||
).resolves.toBe('version: 0.0.0 ^0.1.2');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -69,7 +69,7 @@ export async function templatingTask(
|
||||
templateDir: string,
|
||||
destinationDir: string,
|
||||
context: any,
|
||||
versions: { [name: string]: string },
|
||||
versionProvider: (name: string, versionHint?: string) => string,
|
||||
) {
|
||||
const files = await recursive(templateDir).catch(error => {
|
||||
throw new Error(`Failed to read template directory: ${error.message}`);
|
||||
@@ -90,11 +90,11 @@ export async function templatingTask(
|
||||
{ name: basename(destination), ...context },
|
||||
{
|
||||
helpers: {
|
||||
version(name: string) {
|
||||
if (versions[name]) {
|
||||
return versions[name];
|
||||
}
|
||||
throw new Error(`No version available for package ${name}`);
|
||||
versionQuery(name: string, versionHint: string | unknown) {
|
||||
return versionProvider(
|
||||
name,
|
||||
typeof versionHint === 'string' ? versionHint : undefined,
|
||||
);
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@@ -15,7 +15,9 @@
|
||||
*/
|
||||
|
||||
import fs from 'fs-extra';
|
||||
import semver from 'semver';
|
||||
import { paths } from './paths';
|
||||
import { Lockfile } from './versioning';
|
||||
|
||||
/* eslint-disable import/no-extraneous-dependencies,monorepo/no-internal-import */
|
||||
/*
|
||||
@@ -41,7 +43,7 @@ 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 packageVersions = {
|
||||
export const packageVersions: Record<string, string> = {
|
||||
'@backstage/backend-common': backendCommon,
|
||||
'@backstage/cli': cli,
|
||||
'@backstage/config': config,
|
||||
@@ -60,3 +62,25 @@ export function findVersion() {
|
||||
|
||||
export const version = findVersion();
|
||||
export const isDev = fs.pathExistsSync(paths.resolveOwn('src'));
|
||||
|
||||
export function createPackageVersionProvider(lockfile?: Lockfile) {
|
||||
return (name: string, versionHint?: string) => {
|
||||
const targetVersion = versionHint || packageVersions[name];
|
||||
if (!targetVersion) {
|
||||
throw new Error(`No version available for package ${name}`);
|
||||
}
|
||||
|
||||
const lockfileEntries = lockfile?.get(name);
|
||||
if (
|
||||
name.startsWith('@types/') &&
|
||||
lockfileEntries?.some(entry => entry.range === '*')
|
||||
) {
|
||||
return '*';
|
||||
}
|
||||
const validRanges = lockfileEntries?.filter(entry =>
|
||||
semver.satisfies(targetVersion, entry.range),
|
||||
);
|
||||
const highestRange = validRanges?.slice(-1)[0];
|
||||
return highestRange?.range ?? `^${targetVersion}`;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -23,20 +23,20 @@
|
||||
"clean": "backstage-cli clean"
|
||||
},
|
||||
"dependencies": {
|
||||
"@backstage/backend-common": "^{{version '@backstage/backend-common'}}",
|
||||
"@backstage/config": "^{{version '@backstage/config'}}",
|
||||
"@types/express": "^4.17.6",
|
||||
"express": "^4.17.1",
|
||||
"express-promise-router": "^4.1.0",
|
||||
"winston": "^3.2.1",
|
||||
"cross-fetch": "^3.0.6",
|
||||
"yn": "^4.0.0"
|
||||
"@backstage/backend-common": "{{versionQuery '@backstage/backend-common'}}",
|
||||
"@backstage/config": "{{versionQuery '@backstage/config'}}",
|
||||
"@types/express": "{{versionQuery '@types/express' '4.17.6'}}",
|
||||
"express": "{{versionQuery 'express' '4.17.1'}}",
|
||||
"express-promise-router": "{{versionQuery 'express-promise-router' '4.1.0'}}",
|
||||
"winston": "{{versionQuery 'winston' '3.2.1'}}",
|
||||
"cross-fetch": "{{versionQuery 'cross-fetch' '3.0.6'}}",
|
||||
"yn": "{{versionQuery 'yn' '4.0.0'}}"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/cli": "^{{version '@backstage/cli'}}",
|
||||
"@types/supertest": "^2.0.8",
|
||||
"supertest": "^4.0.2",
|
||||
"msw": "^0.29.0"
|
||||
"@backstage/cli": "{{versionQuery '@backstage/cli'}}",
|
||||
"@types/supertest": "{{versionQuery '@types/supertest' '2.0.8'}}",
|
||||
"supertest": "{{versionQuery 'supertest' '4.0.2'}}",
|
||||
"msw": "{{versionQuery 'msw' '0.29.0'}}"
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
|
||||
@@ -24,28 +24,28 @@
|
||||
"clean": "backstage-cli clean"
|
||||
},
|
||||
"dependencies": {
|
||||
"@backstage/core-components": "^{{version '@backstage/core-components'}}",
|
||||
"@backstage/core-plugin-api": "^{{version '@backstage/core-plugin-api'}}",
|
||||
"@backstage/theme": "^{{version '@backstage/theme'}}",
|
||||
"@material-ui/core": "^4.12.2",
|
||||
"@material-ui/icons": "^4.9.1",
|
||||
"@material-ui/lab": "4.0.0-alpha.57",
|
||||
"react": "^16.13.1",
|
||||
"react-dom": "^16.13.1",
|
||||
"react-use": "^17.2.4"
|
||||
"@backstage/core-components": "{{versionQuery '@backstage/core-components'}}",
|
||||
"@backstage/core-plugin-api": "{{versionQuery '@backstage/core-plugin-api'}}",
|
||||
"@backstage/theme": "{{versionQuery '@backstage/theme'}}",
|
||||
"@material-ui/core": "{{versionQuery '@material-ui/core' '4.12.2'}}",
|
||||
"@material-ui/icons": "{{versionQuery '@material-ui/icons' '4.9.1'}}",
|
||||
"@material-ui/lab": "4{{versionQuery '@material-ui/lab' '.0.0-alpha.57'}}",
|
||||
"react": "{{versionQuery 'react' '16.13.1'}}",
|
||||
"react-dom": "{{versionQuery 'react-dom' '16.13.1'}}",
|
||||
"react-use": "{{versionQuery 'react-use' '17.2.4'}}"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/cli": "^{{version '@backstage/cli'}}",
|
||||
"@backstage/core-app-api": "^{{version '@backstage/core-app-api'}}",
|
||||
"@backstage/dev-utils": "^{{version '@backstage/dev-utils'}}",
|
||||
"@backstage/test-utils": "^{{version '@backstage/test-utils'}}",
|
||||
"@testing-library/jest-dom": "^5.10.1",
|
||||
"@testing-library/react": "^11.2.5",
|
||||
"@testing-library/user-event": "^13.1.8",
|
||||
"@types/jest": "^26.0.7",
|
||||
"@types/node": "^14.14.32",
|
||||
"msw": "^0.29.0",
|
||||
"cross-fetch": "^3.0.6"
|
||||
"@backstage/cli": "{{versionQuery '@backstage/cli'}}",
|
||||
"@backstage/core-app-api": "{{versionQuery '@backstage/core-app-api'}}",
|
||||
"@backstage/dev-utils": "{{versionQuery '@backstage/dev-utils'}}",
|
||||
"@backstage/test-utils": "{{versionQuery '@backstage/test-utils'}}",
|
||||
"@testing-library/jest-dom": "{{versionQuery '@testing-library/jest-dom' '5.10.1'}}",
|
||||
"@testing-library/react": "{{versionQuery '@testing-library/react' '11.2.5'}}",
|
||||
"@testing-library/user-event": "{{versionQuery '@testing-library/user-event' '13.1.8'}}",
|
||||
"@types/jest": "{{versionQuery '@types/jest' '26.0.7'}}",
|
||||
"@types/node": "{{versionQuery '@types/node' '14.14.32'}}",
|
||||
"msw": "{{versionQuery 'msw' '0.29.0'}}",
|
||||
"cross-fetch": "{{versionQuery 'cross-fetch' '3.0.6'}}"
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
|
||||
Reference in New Issue
Block a user