From 7fe125abd651c21724c08df14093223d3fc9e844 Mon Sep 17 00:00:00 2001 From: blam Date: Mon, 15 Apr 2024 18:44:10 +0200 Subject: [PATCH] chore: moving out the migrate to a seperate command Signed-off-by: blam --- .../cli/src/commands/versions/bump.test.ts | 161 +----------------- packages/cli/src/commands/versions/bump.ts | 2 +- .../cli/src/commands/versions/migrate.test.ts | 156 +++++++++++++++++ packages/cli/src/commands/versions/migrate.ts | 23 +++ 4 files changed, 187 insertions(+), 155 deletions(-) create mode 100644 packages/cli/src/commands/versions/migrate.test.ts create mode 100644 packages/cli/src/commands/versions/migrate.ts diff --git a/packages/cli/src/commands/versions/bump.test.ts b/packages/cli/src/commands/versions/bump.test.ts index f3eafb760a..d00b4ce8da 100644 --- a/packages/cli/src/commands/versions/bump.test.ts +++ b/packages/cli/src/commands/versions/bump.test.ts @@ -92,8 +92,6 @@ const REGISTRY_VERSIONS: { [name: string]: string } = { '@backstage-extra/custom': '1.1.0', '@backstage-extra/custom-two': '2.0.0', '@backstage/create-app': '1.0.0', - '@backstage-community/custom': '1.1.0', - '@backstage-community/custom-two': '2.0.0', }; const HEADER = `# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. @@ -206,7 +204,7 @@ describe('bump', () => { await bump({ pattern: null, release: 'main' } as unknown as Command); }); expectLogsToMatch(logs, [ - 'Using default pattern glob @backstage?(-community)/*', + 'Using default pattern glob @backstage/*', 'Checking for updates of @backstage/core', 'Checking for updates of @backstage/theme', 'Checking for updates of @backstage/core-api', @@ -263,151 +261,6 @@ describe('bump', () => { }); }); - it('should bump backstage-community dependencies', async () => { - const customLockfileMock = `${lockfileMock} -"@backstage-community/custom@^1.1.0": - version "1.1.0" - -"@backstage-community/custom@^1.0.1": - version "1.0.1" - -"@backstage-community/custom-two@^1.0.0": - version "1.0.0" -`; - const customLockfileMockResult = `${HEADER} -"@backstage-community/custom-two@^1.0.0": - version "1.0.0" - -"@backstage-community/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" -`; - mockDir.setContent({ - 'yarn.lock': customLockfileMock, - 'package.json': JSON.stringify({ - workspaces: { - packages: ['packages/*'], - }, - }), - packages: { - a: { - 'package.json': JSON.stringify({ - name: 'a', - dependencies: { - '@backstage/core': '^1.0.5', - '@backstage-community/custom': '^1.0.1', - '@backstage-community/custom-two': '^1.0.0', - }, - }), - }, - b: { - 'package.json': JSON.stringify({ - name: 'b', - dependencies: { - '@backstage/core': '^1.0.3', - '@backstage/theme': '^1.0.0', - '@backstage-community/custom': '^1.1.0', - '@backstage-community/custom-two': '^1.0.0', - }, - }), - }, - }, - }); - - jest.spyOn(runObj, 'run').mockResolvedValue(undefined); - worker.use( - rest.get( - 'https://versions.backstage.io/v1/tags/main/manifest.json', - (_, res, ctx) => - res( - ctx.status(200), - ctx.json({ - packages: [], - }), - ), - ), - ); - const { log: logs } = await withLogCollector(['log'], async () => { - await bump({ - release: 'main', - } as any); - }); - expectLogsToMatch(logs, [ - 'Checking for updates of @backstage/core', - 'Checking for updates of @backstage-community/custom', - 'Checking for updates of @backstage-community/custom-two', - 'Checking for updates of @backstage/theme', - 'Checking for updates of @backstage/core-api', - 'Some packages are outdated, updating', - 'Using default pattern glob @backstage?(-community)/*', - 'unlocking @backstage/core@^1.0.3 ~> 1.0.6', - 'unlocking @backstage-community/custom@^1.0.1 ~> 1.1.0', - 'unlocking @backstage/core-api@^1.0.6 ~> 1.0.7', - 'unlocking @backstage/core-api@^1.0.3 ~> 1.0.7', - 'bumping @backstage/core in a to ^1.0.6', - 'bumping @backstage-community/custom in a to ^1.1.0', - 'bumping @backstage-community/custom-two in a to ^2.0.0', - 'bumping @backstage/core in b to ^1.0.6', - 'bumping @backstage-community/custom in b to ^1.1.0', - 'bumping @backstage-community/custom-two in b to ^2.0.0', - 'bumping @backstage/theme in b to ^2.0.0', - 'Running yarn install to install new versions', - '⚠️ The following packages may have breaking changes:', - ' @backstage-community/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(mockFetchPackageInfo).toHaveBeenCalledTimes(5); - expect(mockFetchPackageInfo).toHaveBeenCalledWith('@backstage/core'); - expect(mockFetchPackageInfo).toHaveBeenCalledWith('@backstage/theme'); - - expect(runObj.run).toHaveBeenCalledTimes(1); - expect(runObj.run).toHaveBeenCalledWith( - 'yarn', - ['install'], - expect.any(Object), - ); - - const lockfileContents = await fs.readFile( - mockDir.resolve('yarn.lock'), - 'utf8', - ); - expect(lockfileContents).toEqual(customLockfileMockResult); - - const packageA = await fs.readJson( - mockDir.resolve('packages/a/package.json'), - ); - expect(packageA).toEqual({ - name: 'a', - dependencies: { - '@backstage-community/custom': '^1.1.0', - '@backstage-community/custom-two': '^2.0.0', - '@backstage/core': '^1.0.6', - }, - }); - const packageB = await fs.readJson( - mockDir.resolve('packages/b/package.json'), - ); - expect(packageB).toEqual({ - name: 'b', - dependencies: { - '@backstage-community/custom': '^1.1.0', - '@backstage-community/custom-two': '^2.0.0', - '@backstage/core': '^1.0.6', - '@backstage/theme': '^2.0.0', - }, - }); - }); - it('should bump backstage dependencies but not install them', async () => { mockDir.setContent({ 'yarn.lock': lockfileMock, @@ -458,7 +311,7 @@ describe('bump', () => { } as unknown as Command); }); expectLogsToMatch(logs, [ - 'Using default pattern glob @backstage?(-community)/*', + 'Using default pattern glob @backstage/*', 'Checking for updates of @backstage/core', 'Checking for updates of @backstage/theme', 'Checking for updates of @backstage/core-api', @@ -570,7 +423,7 @@ describe('bump', () => { await bump({ pattern: null, release: 'main' } as unknown as Command); }); expectLogsToMatch(logs, [ - 'Using default pattern glob @backstage?(-community)/*', + 'Using default pattern glob @backstage/*', 'Checking for updates of @backstage/core', 'Checking for updates of @backstage/theme', 'Checking for updates of @backstage/theme', @@ -670,7 +523,7 @@ describe('bump', () => { ).rejects.toThrow('No release found for 999.0.1 version'); }); expect(logs.filter(Boolean)).toEqual([ - 'Using default pattern glob @backstage?(-community)/*', + 'Using default pattern glob @backstage/*', ]); expect(runObj.run).toHaveBeenCalledTimes(0); @@ -773,7 +626,7 @@ describe('bump', () => { await bump({ pattern: null, release: 'next' } as unknown as Command); }); expectLogsToMatch(logs, [ - 'Using default pattern glob @backstage?(-community)/*', + 'Using default pattern glob @backstage/*', 'Checking for updates of @backstage/core', 'Checking for updates of @backstage/theme', 'Checking for updates of @backstage/theme', @@ -988,7 +841,7 @@ describe('bump', () => { await bump({ pattern: null, release: 'main' } as unknown as Command); }); expectLogsToMatch(logs, [ - 'Using default pattern glob @backstage?(-community)/*', + 'Using default pattern glob @backstage/*', 'Checking for updates of @backstage/core', 'Checking for updates of @backstage/theme', 'Package info not found, ignoring package @backstage/core', @@ -1103,7 +956,7 @@ describe('bump', () => { await bump({ pattern: null, release: 'main' } as unknown as Command); }); expectLogsToMatch(logs, [ - 'Using default pattern glob @backstage?(-community)/*', + 'Using default pattern glob @backstage/*', 'Checking for updates of @backstage/core', 'Checking for updates of @backstage/theme', 'Checking for updates of @backstage/core-api', diff --git a/packages/cli/src/commands/versions/bump.ts b/packages/cli/src/commands/versions/bump.ts index c6a84208ab..d64d5a9756 100644 --- a/packages/cli/src/commands/versions/bump.ts +++ b/packages/cli/src/commands/versions/bump.ts @@ -48,7 +48,7 @@ const DEP_TYPES = [ 'optionalDependencies', ]; -const DEFAULT_PATTERN_GLOB = '@backstage?(-community)/*'; +const DEFAULT_PATTERN_GLOB = '@backstage/*'; type PkgVersionInfo = { range: string; diff --git a/packages/cli/src/commands/versions/migrate.test.ts b/packages/cli/src/commands/versions/migrate.test.ts new file mode 100644 index 0000000000..1aef6ff307 --- /dev/null +++ b/packages/cli/src/commands/versions/migrate.test.ts @@ -0,0 +1,156 @@ +/* + * Copyright 2024 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 { + MockDirectory, + createMockDirectory, +} from '@backstage/backend-test-utils'; +import * as run from '../../lib/run'; +import migrate from './migrate'; +import { withLogCollector } from '@backstage/test-utils'; +import fs from 'fs-extra'; + +let mockDir: MockDirectory; +jest.mock('../../lib/paths', () => ({ + paths: { + resolveTargetRoot(filename: string) { + return mockDir.resolve(filename); + }, + get targetDir() { + return mockDir.path; + }, + }, +})); + +jest.mock('../../lib/run', () => { + return { + run: jest.fn(), + }; +}); + +const mockFetchPackageInfo = jest.fn(); +jest.mock('../../lib/versioning/packages', () => { + const actual = jest.requireActual('../../lib/versioning/packages'); + return { + ...actual, + fetchPackageInfo: (name: string) => mockFetchPackageInfo(name), + }; +}); + +describe('versions:migrate', () => { + mockDir = createMockDirectory(); + + beforeEach(() => {}); + + it('should bump to the moved version when the package is moved', async () => { + mockDir.setContent({ + 'package.json': JSON.stringify({ + workspaces: { + packages: ['packages/*'], + }, + }), + packages: { + a: { + 'package.json': JSON.stringify({ + name: 'a', + dependencies: { + '@backstage/core': '^1.0.5', + '@backstage/custom': '^1.0.1', + '@backstage/custom-two': '^1.0.0', + }, + }), + }, + b: { + 'package.json': JSON.stringify({ + name: 'b', + dependencies: { + '@backstage/core': '^1.0.3', + '@backstage/theme': '^1.0.0', + '@backstage/custom': '^1.1.0', + '@backstage/custom-two': '^1.0.0', + }, + }), + }, + }, + }); + + jest.spyOn(run, 'run').mockResolvedValue(undefined); + + const { log: logs } = await withLogCollector(['log'], async () => { + await migrate({}); + }); + // expectLogsToMatch(logs, [ + // 'Checking for updates of @backstage/core', + // 'Checking for updates of @backstage/custom', + // 'Checking for updates of @backstage/custom-two', + // 'Checking for updates of @backstage/theme', + // 'Checking for updates of @backstage/core-api', + // 'Some packages are outdated, updating', + // 'Using default pattern glob @backstage?(-community)/*', + // 'unlocking @backstage/core@^1.0.3 ~> 1.0.6', + // 'unlocking @backstage-community/custom@^1.0.1 ~> 1.1.0', + // 'unlocking @backstage/core-api@^1.0.6 ~> 1.0.7', + // 'unlocking @backstage/core-api@^1.0.3 ~> 1.0.7', + // 'bumping @backstage/core in a to ^1.0.6', + // 'bumping @backstage-community/custom in a to ^1.1.0', + // 'bumping @backstage-community/custom-two in a to ^2.0.0', + // 'bumping @backstage/core in b to ^1.0.6', + // 'bumping @backstage-community/custom in b to ^1.1.0', + // 'bumping @backstage-community/custom-two in b to ^2.0.0', + // 'bumping @backstage/theme in b to ^2.0.0', + // 'Running yarn install to install new versions', + // '⚠️ The following packages may have breaking changes:', + // ' @backstage-community/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(mockFetchPackageInfo).toHaveBeenCalledTimes(5); + expect(mockFetchPackageInfo).toHaveBeenCalledWith('@backstage/core'); + expect(mockFetchPackageInfo).toHaveBeenCalledWith('@backstage/theme'); + + expect(run.run).toHaveBeenCalledTimes(1); + expect(run.run).toHaveBeenCalledWith( + 'yarn', + ['install'], + expect.any(Object), + ); + + const packageA = await fs.readJson( + mockDir.resolve('packages/a/package.json'), + ); + expect(packageA).toEqual({ + name: 'a', + dependencies: { + '@backstage-community/custom': '^1.1.0', + '@backstage-community/custom-two': '^2.0.0', + '@backstage/core': '^1.0.6', + }, + }); + const packageB = await fs.readJson( + mockDir.resolve('packages/b/package.json'), + ); + expect(packageB).toEqual({ + name: 'b', + dependencies: { + '@backstage-community/custom': '^1.1.0', + '@backstage-community/custom-two': '^2.0.0', + '@backstage/core': '^1.0.6', + '@backstage/theme': '^2.0.0', + }, + }); + }); +}); diff --git a/packages/cli/src/commands/versions/migrate.ts b/packages/cli/src/commands/versions/migrate.ts new file mode 100644 index 0000000000..2e18db456c --- /dev/null +++ b/packages/cli/src/commands/versions/migrate.ts @@ -0,0 +1,23 @@ +/* + * Copyright 2024 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 { PackageGraph } from '@backstage/cli-node'; +import { OptionValues } from 'commander'; + +export default async (_: OptionValues) => { + console.log( + PackageGraph.fromPackages(await PackageGraph.listTargetPackages()), + ); +};