From d9ea06a8b5a93e3f36ef05443ab4c5f0c03fabe8 Mon Sep 17 00:00:00 2001 From: Zack Griesinger Date: Mon, 27 Dec 2021 14:50:46 -0600 Subject: [PATCH 1/8] Update CLI to allow passing in a prefix glob for versioning Signed-off-by: Zack Griesinger --- packages/cli/package.json | 2 + packages/cli/src/commands/index.ts | 2 + .../cli/src/commands/versions/bump.test.ts | 146 +++++++++++++++++- packages/cli/src/commands/versions/bump.ts | 23 +-- .../cli/src/lib/versioning/packages.test.ts | 5 +- packages/cli/src/lib/versioning/packages.ts | 7 +- 6 files changed, 167 insertions(+), 18 deletions(-) diff --git a/packages/cli/package.json b/packages/cli/package.json index 42a33da0db..e119ced65d 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -83,6 +83,7 @@ "json-schema": "^0.4.0", "jest-transform-yaml": "^0.1.1", "lodash": "^4.17.21", + "minimatch": "3.0.4", "mini-css-extract-plugin": "^2.4.2", "node-libs-browser": "^2.2.1", "ora": "^5.3.0", @@ -127,6 +128,7 @@ "@types/fs-extra": "^9.0.1", "@types/http-proxy": "^1.17.4", "@types/inquirer": "^8.1.3", + "@types/minimatch": "^3.0.5", "@types/mock-fs": "^4.13.0", "@types/node": "^14.14.32", "@types/recursive-readdir": "^2.2.0", diff --git a/packages/cli/src/commands/index.ts b/packages/cli/src/commands/index.ts index bef5dfc285..ca57b545fd 100644 --- a/packages/cli/src/commands/index.ts +++ b/packages/cli/src/commands/index.ts @@ -214,11 +214,13 @@ export function registerCommands(program: CommanderStatic) { program .command('versions:bump') + .option('--prefix', 'Override glob for matching packages to upgrade') .description('Bump Backstage packages to the latest versions') .action(lazy(() => import('./versions/bump').then(m => m.default))); program .command('versions:check') + .option('--prefix ', 'Override glob for matching packages to upgrade') .option('--fix', 'Fix any auto-fixable versioning problems') .description('Check Backstage package versioning') .action(lazy(() => import('./versions/lint').then(m => m.default))); diff --git a/packages/cli/src/commands/versions/bump.test.ts b/packages/cli/src/commands/versions/bump.test.ts index bc4049f1f4..fe529b0769 100644 --- a/packages/cli/src/commands/versions/bump.test.ts +++ b/packages/cli/src/commands/versions/bump.test.ts @@ -16,6 +16,7 @@ import fs from 'fs-extra'; import mockFs from 'mock-fs'; +import { Command } from 'commander'; import { resolve as resolvePath } from 'path'; import { paths } from '../../lib/paths'; import { mapDependencies } from '../../lib/versioning'; @@ -36,6 +37,8 @@ const REGISTRY_VERSIONS: { [name: string]: string } = { '@backstage/core': '1.0.6', '@backstage/core-api': '1.0.7', '@backstage/theme': '2.0.0', + '@backstage-extra/custom': '1.1.0', + '@backstage-extra/custom-two': '2.0.0', }; const HEADER = `# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. @@ -83,7 +86,7 @@ describe('bump', () => { it('should bump backstage dependencies', async () => { // Make sure all modules involved in package discovery are in the module cache before we mock fs - await mapDependencies(paths.targetDir); + await mapDependencies(paths.targetDir, '@backstage/*'); mockFs({ '/yarn.lock': lockfileMock, @@ -123,7 +126,7 @@ describe('bump', () => { jest.spyOn(runObj, 'run').mockResolvedValue(undefined); const { log: logs } = await withLogCollector(['log'], async () => { - await bump(); + await bump({ prefix: null } as Command); }); expect(logs.filter(Boolean)).toEqual([ 'Checking for updates of @backstage/theme', @@ -178,9 +181,144 @@ describe('bump', () => { }); }); + it('should bump backstage dependencies and dependencies matching prefix glob', async () => { + // Make sure all modules involved in package discovery are in the module cache before we mock fs + await mapDependencies(paths.targetDir, '@backstage/*'); + const customLockfileMock = `${lockfileMock} +"@backstage-extra/custom@^1.1.0": + version "1.1.0" + +"@backstage-extra/custom@^1.0.1": + version "1.0.1" + +"@backstage-extra/custom-two@^1.0.0": + version "1.0.0" +`; + const customLockfileMockResult = `${HEADER} +"@backstage-extra/custom-two@^1.0.0": + version "1.0.0" + +"@backstage-extra/custom@^1.1.0": + version "1.1.0" + +"@backstage/core@^1.0.5": + version "1.0.6" + dependencies: + "@backstage/core-api" "^1.0.6" + +"@backstage/theme@^1.0.0": + version "1.0.0" +`; + mockFs({ + '/yarn.lock': customLockfileMock, + '/lerna.json': JSON.stringify({ + packages: ['packages/*'], + }), + '/packages/a/package.json': JSON.stringify({ + name: 'a', + dependencies: { + '@backstage/core': '^1.0.5', + '@backstage-extra/custom': '^1.0.1', + '@backstage-extra/custom-two': '^1.0.0', + }, + }), + '/packages/b/package.json': JSON.stringify({ + name: 'b', + dependencies: { + '@backstage/core': '^1.0.3', + '@backstage/theme': '^1.0.0', + '@backstage-extra/custom': '^1.1.0', + '@backstage-extra/custom-two': '^1.0.0', + }, + }), + }); + + paths.targetDir = '/'; + jest + .spyOn(paths, 'resolveTargetRoot') + .mockImplementation((...path) => resolvePath('/', ...path)); + jest.spyOn(runObj, 'runPlain').mockImplementation(async (...[, , , name]) => + JSON.stringify({ + type: 'inspect', + data: { + name: name, + 'dist-tags': { + latest: REGISTRY_VERSIONS[name], + }, + }, + }), + ); + jest.spyOn(runObj, 'run').mockResolvedValue(undefined); + + const { log: logs } = await withLogCollector(['log'], async () => { + await bump({ prefix: '@{backstage,backstage-extra}/*' } as any); + }); + expect(logs.filter(Boolean)).toEqual([ + 'Checking for updates of @backstage/theme', + 'Checking for updates of @backstage-extra/custom-two', + 'Checking for updates of @backstage-extra/custom', + 'Checking for updates of @backstage/core', + 'Checking for updates of @backstage/core-api', + 'Some packages are outdated, updating', + 'unlocking @backstage-extra/custom@^1.0.1 ~> 1.1.0', + 'unlocking @backstage/core@^1.0.3 ~> 1.0.6', + 'unlocking @backstage/core-api@^1.0.6 ~> 1.0.7', + 'unlocking @backstage/core-api@^1.0.3 ~> 1.0.7', + 'bumping @backstage-extra/custom-two in a to ^2.0.0', + 'bumping @backstage/theme in b to ^2.0.0', + 'bumping @backstage-extra/custom-two in b to ^2.0.0', + 'Running yarn install to install new versions', + '⚠️ The following packages may have breaking changes:', + ' @backstage-extra/custom-two : 1.0.0 ~> 2.0.0', + ' @backstage/theme : 1.0.0 ~> 2.0.0', + ' https://github.com/backstage/backstage/blob/master/packages/theme/CHANGELOG.md', + 'Version bump complete!', + ]); + + expect(runObj.runPlain).toHaveBeenCalledTimes(6); + expect(runObj.runPlain).toHaveBeenCalledWith( + 'yarn', + 'info', + '--json', + '@backstage/core', + ); + expect(runObj.runPlain).toHaveBeenCalledWith( + 'yarn', + 'info', + '--json', + '@backstage/theme', + ); + + expect(runObj.run).toHaveBeenCalledTimes(1); + expect(runObj.run).toHaveBeenCalledWith('yarn', ['install']); + + const lockfileContents = await fs.readFile('/yarn.lock', 'utf8'); + expect(lockfileContents).toEqual(customLockfileMockResult); + + const packageA = await fs.readJson('/packages/a/package.json'); + expect(packageA).toEqual({ + name: 'a', + dependencies: { + '@backstage-extra/custom': '^1.0.1', + '@backstage-extra/custom-two': '^2.0.0', + '@backstage/core': '^1.0.5', // not bumped since new version is within range + }, + }); + const packageB = await fs.readJson('/packages/b/package.json'); + expect(packageB).toEqual({ + name: 'b', + dependencies: { + '@backstage-extra/custom': '^1.1.0', + '@backstage-extra/custom-two': '^2.0.0', + '@backstage/core': '^1.0.3', // not bumped + '@backstage/theme': '^2.0.0', // bumped since newer + }, + }); + }); + it('should ignore not found packages', async () => { // Make sure all modules involved in package discovery are in the module cache before we mock fs - await mapDependencies(paths.targetDir); + await mapDependencies(paths.targetDir, '@backstage/*'); mockFs({ '/yarn.lock': lockfileMockResult, '/lerna.json': JSON.stringify({ @@ -209,7 +347,7 @@ describe('bump', () => { jest.spyOn(runObj, 'run').mockResolvedValue(undefined); const { log: logs } = await withLogCollector(['log'], async () => { - await bump(); + await bump({ prefix: null } as any); }); expect(logs.filter(Boolean)).toEqual([ 'Checking for updates of @backstage/theme', diff --git a/packages/cli/src/commands/versions/bump.ts b/packages/cli/src/commands/versions/bump.ts index 3898c1654a..ce737cd2e3 100644 --- a/packages/cli/src/commands/versions/bump.ts +++ b/packages/cli/src/commands/versions/bump.ts @@ -17,6 +17,8 @@ import fs from 'fs-extra'; import chalk from 'chalk'; import semver from 'semver'; +import minimatch from 'minimatch'; +import { Command } from 'commander'; import { isError } from '@backstage/errors'; import { resolve as resolvePath } from 'path'; import { run } from '../../lib/run'; @@ -26,7 +28,7 @@ import { fetchPackageInfo, Lockfile, } from '../../lib/versioning'; -import { includedFilter, forbiddenDuplicatesFilter } from './lint'; +import { forbiddenDuplicatesFilter } from './lint'; import { BACKSTAGE_JSON } from '@backstage/cli-common'; const DEP_TYPES = [ @@ -43,14 +45,19 @@ type PkgVersionInfo = { location: string; }; -export default async () => { +export default async (cmd: Command) => { const lockfilePath = paths.resolveTargetRoot('yarn.lock'); const lockfile = await Lockfile.load(lockfilePath); + let prefix = cmd.prefix; + + if (!prefix) { + prefix = '@backstage/*'; + } const findTargetVersion = createVersionFinder(); // First we discover all Backstage dependencies within our own repo - const dependencyMap = await mapDependencies(paths.targetDir); + const dependencyMap = await mapDependencies(paths.targetDir, prefix); // Next check with the package registry to see which dependency ranges we need to bump const versionBumps = new Map(); @@ -88,13 +95,11 @@ export default async () => { } }); + // Only check @backstage packages and friends, we don't want this to do a full update of all deps + const filter = (name: string) => minimatch(name, prefix); + // Check for updates of transitive backstage dependencies await workerThreads(16, lockfile.keys(), async name => { - // Only check @backstage packages and friends, we don't want this to do a full update of all deps - if (!includedFilter(name)) { - return; - } - let target: string; try { target = await findTargetVersion(name); @@ -237,7 +242,7 @@ export default async () => { // Finally we make sure the new lockfile doesn't have any duplicates const dedupLockfile = await Lockfile.load(lockfilePath); const result = dedupLockfile.analyze({ - filter: includedFilter, + filter, }); if (result.newVersions.length > 0) { diff --git a/packages/cli/src/lib/versioning/packages.test.ts b/packages/cli/src/lib/versioning/packages.test.ts index dd63e57187..b7f3614fb7 100644 --- a/packages/cli/src/lib/versioning/packages.test.ts +++ b/packages/cli/src/lib/versioning/packages.test.ts @@ -82,7 +82,10 @@ describe('mapDependencies', () => { }), }); - const dependencyMap = await mapDependencies(paths.targetDir); + const dependencyMap = await mapDependencies( + paths.targetDir, + '@backstage/*', + ); expect(Array.from(dependencyMap)).toEqual([ [ '@backstage/core', diff --git a/packages/cli/src/lib/versioning/packages.ts b/packages/cli/src/lib/versioning/packages.ts index 9f82c560f8..86c7117cfe 100644 --- a/packages/cli/src/lib/versioning/packages.ts +++ b/packages/cli/src/lib/versioning/packages.ts @@ -13,12 +13,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - +import minimatch from 'minimatch'; import { runPlain } from '../../lib/run'; import { NotFoundError } from '../errors'; -const PREFIX = '@backstage'; - const DEP_TYPES = [ 'dependencies', 'devDependencies', @@ -66,6 +64,7 @@ export async function fetchPackageInfo( /** Map all dependencies in the repo as dependency => dependents */ export async function mapDependencies( targetDir: string, + prefixGlob: string, ): Promise> { const { Project } = require('@lerna/project'); const project = new Project(targetDir); @@ -78,7 +77,7 @@ export async function mapDependencies( ); for (const [name, range] of deps) { - if (name.startsWith(PREFIX)) { + if (minimatch(name, prefixGlob)) { dependencyMap.set( name, (dependencyMap.get(name) ?? []).concat({ From 9534391ae41d094f2c95d08cd7d910a6da3eb295 Mon Sep 17 00:00:00 2001 From: Zack Griesinger Date: Mon, 27 Dec 2021 14:52:08 -0600 Subject: [PATCH 2/8] Add changeset Signed-off-by: Zack Griesinger --- .changeset/early-balloons-trade.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/early-balloons-trade.md diff --git a/.changeset/early-balloons-trade.md b/.changeset/early-balloons-trade.md new file mode 100644 index 0000000000..4c638260e1 --- /dev/null +++ b/.changeset/early-balloons-trade.md @@ -0,0 +1,5 @@ +--- +'@backstage/cli': minor +--- + +Add --prefix option to override matching glob patterns for backstage versioning From 93d8a6f0bb0b4f1a7066f7e2c5c744282278bd62 Mon Sep 17 00:00:00 2001 From: Zack Griesinger Date: Mon, 27 Dec 2021 14:59:06 -0600 Subject: [PATCH 3/8] Update docs Signed-off-by: Zack Griesinger --- docs/getting-started/keeping-backstage-updated.md | 7 +++++++ docs/local-dev/cli-commands.md | 1 + packages/cli/src/commands/index.ts | 1 - 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/docs/getting-started/keeping-backstage-updated.md b/docs/getting-started/keeping-backstage-updated.md index ffe4f4dcd5..95ffb8cebd 100644 --- a/docs/getting-started/keeping-backstage-updated.md +++ b/docs/getting-started/keeping-backstage-updated.md @@ -22,6 +22,13 @@ yarn backstage-cli versions:bump The reason for bumping all `@backstage` packages at once is to maintain the dependencies that they have between each other. +If you are using other plugins you can pass in the `--prefix` option to update +more than just the `@backstage/*` dependencies. + +```bash +yarn backstage-cli versions:bump --prefix '@{backstage,roadiehq}/*' +``` + ## Following create-app template changes The `@backstage/create-app` command creates the initial structure of your diff --git a/docs/local-dev/cli-commands.md b/docs/local-dev/cli-commands.md index 412e3c4598..e10bf88850 100644 --- a/docs/local-dev/cli-commands.md +++ b/docs/local-dev/cli-commands.md @@ -594,6 +594,7 @@ Usage: backstage-cli versions:bump [options] Options: -h, --help display help for command + -p, --prefix Override glob for matching packages to upgrade ``` ## versions:check diff --git a/packages/cli/src/commands/index.ts b/packages/cli/src/commands/index.ts index ca57b545fd..d85cab0a8c 100644 --- a/packages/cli/src/commands/index.ts +++ b/packages/cli/src/commands/index.ts @@ -220,7 +220,6 @@ export function registerCommands(program: CommanderStatic) { program .command('versions:check') - .option('--prefix ', 'Override glob for matching packages to upgrade') .option('--fix', 'Fix any auto-fixable versioning problems') .description('Check Backstage package versioning') .action(lazy(() => import('./versions/lint').then(m => m.default))); From bafc399585888adb8cd1b43b48052fece7e8ed91 Mon Sep 17 00:00:00 2001 From: Zack Griesinger Date: Mon, 27 Dec 2021 15:54:10 -0600 Subject: [PATCH 4/8] Add better logging and fix command index Signed-off-by: Zack Griesinger --- packages/cli/src/commands/index.ts | 2 +- packages/cli/src/commands/versions/bump.test.ts | 3 +++ packages/cli/src/commands/versions/bump.ts | 7 ++++++- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/packages/cli/src/commands/index.ts b/packages/cli/src/commands/index.ts index d85cab0a8c..81d5fb7f1f 100644 --- a/packages/cli/src/commands/index.ts +++ b/packages/cli/src/commands/index.ts @@ -214,7 +214,7 @@ export function registerCommands(program: CommanderStatic) { program .command('versions:bump') - .option('--prefix', 'Override glob for matching packages to upgrade') + .option('--prefix ', 'Override glob for matching packages to upgrade') .description('Bump Backstage packages to the latest versions') .action(lazy(() => import('./versions/bump').then(m => m.default))); diff --git a/packages/cli/src/commands/versions/bump.test.ts b/packages/cli/src/commands/versions/bump.test.ts index fe529b0769..19e0d28553 100644 --- a/packages/cli/src/commands/versions/bump.test.ts +++ b/packages/cli/src/commands/versions/bump.test.ts @@ -129,6 +129,7 @@ describe('bump', () => { await bump({ prefix: null } as Command); }); expect(logs.filter(Boolean)).toEqual([ + 'Using default prefix glob @backstage/*', 'Checking for updates of @backstage/theme', 'Checking for updates of @backstage/core', 'Checking for updates of @backstage/core-api', @@ -254,6 +255,7 @@ describe('bump', () => { await bump({ prefix: '@{backstage,backstage-extra}/*' } as any); }); expect(logs.filter(Boolean)).toEqual([ + 'Using custom prefix glob @{backstage,backstage-extra}/*', 'Checking for updates of @backstage/theme', 'Checking for updates of @backstage-extra/custom-two', 'Checking for updates of @backstage-extra/custom', @@ -350,6 +352,7 @@ describe('bump', () => { await bump({ prefix: null } as any); }); expect(logs.filter(Boolean)).toEqual([ + 'Using default prefix glob @backstage/*', 'Checking for updates of @backstage/theme', 'Checking for updates of @backstage/core', 'Package info not found, ignoring package @backstage/theme', diff --git a/packages/cli/src/commands/versions/bump.ts b/packages/cli/src/commands/versions/bump.ts index ce737cd2e3..b9ee85fe0e 100644 --- a/packages/cli/src/commands/versions/bump.ts +++ b/packages/cli/src/commands/versions/bump.ts @@ -38,6 +38,8 @@ const DEP_TYPES = [ 'optionalDependencies', ]; +const DEFAULT_PREFIX_GLOB = '@backstage/*'; + type PkgVersionInfo = { range: string; target: string; @@ -51,7 +53,10 @@ export default async (cmd: Command) => { let prefix = cmd.prefix; if (!prefix) { - prefix = '@backstage/*'; + console.log(`Using default prefix glob ${DEFAULT_PREFIX_GLOB}`); + prefix = DEFAULT_PREFIX_GLOB; + } else { + console.log(`Using custom prefix glob ${prefix}`); } const findTargetVersion = createVersionFinder(); From bec82b0b2ff0074bce68a076fec785ee370e4634 Mon Sep 17 00:00:00 2001 From: Zack Griesinger Date: Mon, 27 Dec 2021 16:04:32 -0600 Subject: [PATCH 5/8] Add back in skip case Signed-off-by: Zack Griesinger --- packages/cli/src/commands/versions/bump.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/cli/src/commands/versions/bump.ts b/packages/cli/src/commands/versions/bump.ts index b9ee85fe0e..1357457d49 100644 --- a/packages/cli/src/commands/versions/bump.ts +++ b/packages/cli/src/commands/versions/bump.ts @@ -100,11 +100,15 @@ export default async (cmd: Command) => { } }); - // Only check @backstage packages and friends, we don't want this to do a full update of all deps const filter = (name: string) => minimatch(name, prefix); // Check for updates of transitive backstage dependencies await workerThreads(16, lockfile.keys(), async name => { + // Only check @backstage packages and friends, we don't want this to do a full update of all deps + if (!filter(name)) { + return; + } + let target: string; try { target = await findTargetVersion(name); From b471662e8adaa7bd18add66af0226caf40ec3588 Mon Sep 17 00:00:00 2001 From: Zackery Griesinger Date: Tue, 28 Dec 2021 09:06:35 -0600 Subject: [PATCH 6/8] Review comments - swap prefix to pattern Signed-off-by: Zackery Griesinger --- .changeset/early-balloons-trade.md | 2 +- .../getting-started/keeping-backstage-updated.md | 4 ++-- docs/local-dev/cli-commands.md | 2 +- packages/cli/src/commands/index.ts | 5 ++++- packages/cli/src/commands/versions/bump.test.ts | 14 +++++++------- packages/cli/src/commands/versions/bump.ts | 16 ++++++++-------- packages/cli/src/lib/versioning/packages.ts | 4 ++-- yarn.lock | 5 +++++ 8 files changed, 30 insertions(+), 22 deletions(-) diff --git a/.changeset/early-balloons-trade.md b/.changeset/early-balloons-trade.md index 4c638260e1..5f521e1434 100644 --- a/.changeset/early-balloons-trade.md +++ b/.changeset/early-balloons-trade.md @@ -1,5 +1,5 @@ --- -'@backstage/cli': minor +'@backstage/cli': patch --- Add --prefix option to override matching glob patterns for backstage versioning diff --git a/docs/getting-started/keeping-backstage-updated.md b/docs/getting-started/keeping-backstage-updated.md index 95ffb8cebd..107119aace 100644 --- a/docs/getting-started/keeping-backstage-updated.md +++ b/docs/getting-started/keeping-backstage-updated.md @@ -22,11 +22,11 @@ yarn backstage-cli versions:bump The reason for bumping all `@backstage` packages at once is to maintain the dependencies that they have between each other. -If you are using other plugins you can pass in the `--prefix` option to update +If you are using other plugins you can pass in the `--pattern` option to update more than just the `@backstage/*` dependencies. ```bash -yarn backstage-cli versions:bump --prefix '@{backstage,roadiehq}/*' +yarn backstage-cli versions:bump --pattern '@{backstage,roadiehq}/*' ``` ## Following create-app template changes diff --git a/docs/local-dev/cli-commands.md b/docs/local-dev/cli-commands.md index e10bf88850..caec60ed70 100644 --- a/docs/local-dev/cli-commands.md +++ b/docs/local-dev/cli-commands.md @@ -594,7 +594,7 @@ Usage: backstage-cli versions:bump [options] Options: -h, --help display help for command - -p, --prefix Override glob for matching packages to upgrade + -p, --pattern Override glob for matching packages to upgrade ``` ## versions:check diff --git a/packages/cli/src/commands/index.ts b/packages/cli/src/commands/index.ts index 81d5fb7f1f..fa00bf4073 100644 --- a/packages/cli/src/commands/index.ts +++ b/packages/cli/src/commands/index.ts @@ -214,7 +214,10 @@ export function registerCommands(program: CommanderStatic) { program .command('versions:bump') - .option('--prefix ', 'Override glob for matching packages to upgrade') + .option( + '--pattern ', + 'Override glob for matching packages to upgrade', + ) .description('Bump Backstage packages to the latest versions') .action(lazy(() => import('./versions/bump').then(m => m.default))); diff --git a/packages/cli/src/commands/versions/bump.test.ts b/packages/cli/src/commands/versions/bump.test.ts index 19e0d28553..b9a030c630 100644 --- a/packages/cli/src/commands/versions/bump.test.ts +++ b/packages/cli/src/commands/versions/bump.test.ts @@ -126,10 +126,10 @@ describe('bump', () => { jest.spyOn(runObj, 'run').mockResolvedValue(undefined); const { log: logs } = await withLogCollector(['log'], async () => { - await bump({ prefix: null } as Command); + await bump({ pattern: null } as Command); }); expect(logs.filter(Boolean)).toEqual([ - 'Using default prefix glob @backstage/*', + 'Using default pattern glob @backstage/*', 'Checking for updates of @backstage/theme', 'Checking for updates of @backstage/core', 'Checking for updates of @backstage/core-api', @@ -182,7 +182,7 @@ describe('bump', () => { }); }); - it('should bump backstage dependencies and dependencies matching prefix glob', async () => { + it('should bump backstage dependencies and dependencies matching pattern glob', async () => { // Make sure all modules involved in package discovery are in the module cache before we mock fs await mapDependencies(paths.targetDir, '@backstage/*'); const customLockfileMock = `${lockfileMock} @@ -252,10 +252,10 @@ describe('bump', () => { jest.spyOn(runObj, 'run').mockResolvedValue(undefined); const { log: logs } = await withLogCollector(['log'], async () => { - await bump({ prefix: '@{backstage,backstage-extra}/*' } as any); + await bump({ pattern: '@{backstage,backstage-extra}/*' } as any); }); expect(logs.filter(Boolean)).toEqual([ - 'Using custom prefix glob @{backstage,backstage-extra}/*', + 'Using custom pattern glob @{backstage,backstage-extra}/*', 'Checking for updates of @backstage/theme', 'Checking for updates of @backstage-extra/custom-two', 'Checking for updates of @backstage-extra/custom', @@ -349,10 +349,10 @@ describe('bump', () => { jest.spyOn(runObj, 'run').mockResolvedValue(undefined); const { log: logs } = await withLogCollector(['log'], async () => { - await bump({ prefix: null } as any); + await bump({ pattern: null } as any); }); expect(logs.filter(Boolean)).toEqual([ - 'Using default prefix glob @backstage/*', + 'Using default pattern glob @backstage/*', 'Checking for updates of @backstage/theme', 'Checking for updates of @backstage/core', 'Package info not found, ignoring package @backstage/theme', diff --git a/packages/cli/src/commands/versions/bump.ts b/packages/cli/src/commands/versions/bump.ts index 1357457d49..2c16f324bc 100644 --- a/packages/cli/src/commands/versions/bump.ts +++ b/packages/cli/src/commands/versions/bump.ts @@ -38,7 +38,7 @@ const DEP_TYPES = [ 'optionalDependencies', ]; -const DEFAULT_PREFIX_GLOB = '@backstage/*'; +const DEFAULT_PATTERN_GLOB = '@backstage/*'; type PkgVersionInfo = { range: string; @@ -50,19 +50,19 @@ type PkgVersionInfo = { export default async (cmd: Command) => { const lockfilePath = paths.resolveTargetRoot('yarn.lock'); const lockfile = await Lockfile.load(lockfilePath); - let prefix = cmd.prefix; + let pattern = cmd.pattern; - if (!prefix) { - console.log(`Using default prefix glob ${DEFAULT_PREFIX_GLOB}`); - prefix = DEFAULT_PREFIX_GLOB; + if (!pattern) { + console.log(`Using default pattern glob ${DEFAULT_PATTERN_GLOB}`); + pattern = DEFAULT_PATTERN_GLOB; } else { - console.log(`Using custom prefix glob ${prefix}`); + console.log(`Using custom pattern glob ${pattern}`); } const findTargetVersion = createVersionFinder(); // First we discover all Backstage dependencies within our own repo - const dependencyMap = await mapDependencies(paths.targetDir, prefix); + const dependencyMap = await mapDependencies(paths.targetDir, pattern); // Next check with the package registry to see which dependency ranges we need to bump const versionBumps = new Map(); @@ -100,7 +100,7 @@ export default async (cmd: Command) => { } }); - const filter = (name: string) => minimatch(name, prefix); + const filter = (name: string) => minimatch(name, pattern); // Check for updates of transitive backstage dependencies await workerThreads(16, lockfile.keys(), async name => { diff --git a/packages/cli/src/lib/versioning/packages.ts b/packages/cli/src/lib/versioning/packages.ts index 86c7117cfe..aa402431b9 100644 --- a/packages/cli/src/lib/versioning/packages.ts +++ b/packages/cli/src/lib/versioning/packages.ts @@ -64,7 +64,7 @@ export async function fetchPackageInfo( /** Map all dependencies in the repo as dependency => dependents */ export async function mapDependencies( targetDir: string, - prefixGlob: string, + pattern: string, ): Promise> { const { Project } = require('@lerna/project'); const project = new Project(targetDir); @@ -77,7 +77,7 @@ export async function mapDependencies( ); for (const [name, range] of deps) { - if (minimatch(name, prefixGlob)) { + if (minimatch(name, pattern)) { dependencyMap.set( name, (dependencyMap.get(name) ?? []).concat({ diff --git a/yarn.lock b/yarn.lock index 4c9a81dd72..83cd5fa6cb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7840,6 +7840,11 @@ resolved "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== +"@types/minimatch@^3.0.5": + version "3.0.5" + resolved "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz#1001cc5e6a3704b83c236027e77f2f58ea010f40" + integrity sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ== + "@types/minimist@^1.2.0": version "1.2.2" resolved "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz#ee771e2ba4b3dc5b372935d549fd9617bf345b8c" From ba21c9acf171bebf0701878ec7f1191e7247a1e9 Mon Sep 17 00:00:00 2001 From: Zack Griesinger Date: Thu, 30 Dec 2021 10:17:28 -0600 Subject: [PATCH 7/8] Fix TypeScript Error Signed-off-by: Zack Griesinger --- packages/cli/src/commands/versions/bump.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/cli/src/commands/versions/bump.test.ts b/packages/cli/src/commands/versions/bump.test.ts index b9a030c630..377e0d59d2 100644 --- a/packages/cli/src/commands/versions/bump.test.ts +++ b/packages/cli/src/commands/versions/bump.test.ts @@ -126,7 +126,7 @@ describe('bump', () => { jest.spyOn(runObj, 'run').mockResolvedValue(undefined); const { log: logs } = await withLogCollector(['log'], async () => { - await bump({ pattern: null } as Command); + await bump({ pattern: null } as unknown as Command); }); expect(logs.filter(Boolean)).toEqual([ 'Using default pattern glob @backstage/*', @@ -349,7 +349,7 @@ describe('bump', () => { jest.spyOn(runObj, 'run').mockResolvedValue(undefined); const { log: logs } = await withLogCollector(['log'], async () => { - await bump({ pattern: null } as any); + await bump({ pattern: null } as unknown as Command); }); expect(logs.filter(Boolean)).toEqual([ 'Using default pattern glob @backstage/*', From 1b69ed0e39263eb3216a3ff291de0f0d6276a3a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Tue, 4 Jan 2022 10:30:10 +0100 Subject: [PATCH 8/8] fix review comment MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- .changeset/early-balloons-trade.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/early-balloons-trade.md b/.changeset/early-balloons-trade.md index 5f521e1434..a08ec947de 100644 --- a/.changeset/early-balloons-trade.md +++ b/.changeset/early-balloons-trade.md @@ -2,4 +2,4 @@ '@backstage/cli': patch --- -Add --prefix option to override matching glob patterns for backstage versioning +Add --pattern option to override matching glob patterns for backstage versioning