Skip to content

Commit f0f3f64

Browse files
authored
Share bump info between validate and actual commands (#1115)
1 parent ea9f0b0 commit f0f3f64

12 files changed

Lines changed: 128 additions & 62 deletions

beachball.config.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
// @ts-check
2-
/** @type {import('./src/types/BeachballOptions').RepoOptions}*/
3-
module.exports = {
2+
/** @type {Partial<import('./src/types/BeachballOptions').RepoOptions>}*/
3+
const config = {
44
disallowedChangeTypes: ['major'],
55
ignorePatterns: [
66
'.*ignore',
77
'*.yml',
8+
'.eslintrc.js',
89
'.github/**',
910
'.prettierrc.json5',
1011
'.vscode/**',
@@ -18,3 +19,5 @@ module.exports = {
1819
'yarn.lock',
1920
],
2021
};
22+
23+
module.exports = config;
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"type": "patch",
3+
"comment": "Share bump info between validate and actual commands. This should be a significant performance improvement in large repos.",
4+
"packageName": "beachball",
5+
"email": "elcraig@microsoft.com",
6+
"dependentChangeType": "patch"
7+
}

src/__e2e__/bump.test.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import type { PackageJson } from '../types/PackageInfo';
1212
import { getParsedOptions } from '../options/getOptions';
1313
import { defaultRemoteBranchName } from '../__fixtures__/gitDefaults';
1414
import { readJson } from '../object/readJson';
15+
import { validate } from '../validation/validate';
1516

1617
describe('version bumping', () => {
1718
let repositoryFactory: RepositoryFactory | undefined;
@@ -56,7 +57,10 @@ describe('version bumping', () => {
5657
generateChangeFiles(['pkg-1'], options);
5758
repo.push();
5859

59-
await bump(options, originalPackageInfos);
60+
// For this test, use validate() similar to the CLI to ensure it works
61+
const { bumpInfo } = validate(options, { checkDependencies: true }, originalPackageInfos);
62+
63+
await bump(options, originalPackageInfos, bumpInfo);
6064

6165
const packageInfos = getPackageInfos(parsedOptions);
6266

@@ -191,7 +195,10 @@ describe('version bumping', () => {
191195
generateChangeFiles(['pkg-1'], options);
192196
repo.push();
193197

194-
await bump(options, originalPackageInfos);
198+
// For this test, use validate() similar to the CLI to ensure it works
199+
const { bumpInfo } = validate(options, { checkDependencies: true }, originalPackageInfos);
200+
201+
await bump(options, originalPackageInfos, bumpInfo);
195202

196203
const packageInfos = getPackageInfos(parsedOptions);
197204

src/__e2e__/publishGit.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import type { Repository } from '../__fixtures__/repository';
66
import { RepositoryFactory } from '../__fixtures__/repositoryFactory';
77
import { bumpAndPush } from '../publish/bumpAndPush';
88
import { publish } from '../commands/publish';
9-
import { gatherBumpInfo } from '../bump/gatherBumpInfo';
9+
import { bumpInMemory } from '../bump/bumpInMemory';
1010
import type { ChangeFileInfo } from '../types/ChangeInfo';
1111
import { getPackageInfos } from '../monorepo/getPackageInfos';
1212
import type { PackageJson } from '../types/PackageInfo';
@@ -54,7 +54,7 @@ describe('publish command (git)', () => {
5454
generateChangeFiles(['foo'], options);
5555
repo.push();
5656

57-
await publish(options, packageInfos);
57+
await publish(options, packageInfos, undefined);
5858

5959
const newRepo = repositoryFactory.cloneRepository();
6060

@@ -74,7 +74,7 @@ describe('publish command (git)', () => {
7474
const publishBranch = 'publish_test';
7575
repo1.checkout('-b', publishBranch);
7676

77-
const bumpInfo = gatherBumpInfo(options1, packageInfos1);
77+
const bumpInfo = bumpInMemory(options1, packageInfos1);
7878

7979
// 3. Meanwhile, in repo2, also create a new change file
8080
const repo2 = repositoryFactory.cloneRepository();

src/bump/bumpInMemory.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { initializePackageChangeTypes } from '../changefile/changeTypes';
2+
import { readChangeFiles } from '../changefile/readChangeFiles';
3+
import type { BumpInfo } from '../types/BumpInfo';
4+
import { bumpInPlace } from './bumpInPlace';
5+
import type { BeachballOptions } from '../types/BeachballOptions';
6+
import { getScopedPackages } from '../monorepo/getScopedPackages';
7+
import type { PackageInfos } from '../types/PackageInfo';
8+
import { getPackageGroups } from '../monorepo/getPackageGroups';
9+
import { cloneObject } from '../object/cloneObject';
10+
11+
/**
12+
* Gather bump info and bump versions in memory.
13+
* Does NOT mutate the given `originalPackageInfos`.
14+
*/
15+
export function bumpInMemory(options: BeachballOptions, originalPackageInfos: PackageInfos): BumpInfo {
16+
const packageInfos = cloneObject(originalPackageInfos);
17+
const changes = readChangeFiles(options, packageInfos);
18+
19+
// Determine base change types for each package (not considering disallowedChangeTypes or groups)
20+
const calculatedChangeTypes = initializePackageChangeTypes(changes);
21+
22+
const bumpInfo: BumpInfo = {
23+
calculatedChangeTypes,
24+
packageInfos,
25+
packageGroups: getPackageGroups(packageInfos, options.path, options.groups),
26+
changeFileChangeInfos: changes,
27+
modifiedPackages: new Set<string>(),
28+
scopedPackages: new Set(getScopedPackages(options, packageInfos)),
29+
dependentChangedBy: {},
30+
};
31+
32+
bumpInPlace(bumpInfo, options);
33+
34+
return bumpInfo;
35+
}

src/bump/gatherBumpInfo.ts

Lines changed: 3 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,11 @@
1-
import { initializePackageChangeTypes } from '../changefile/changeTypes';
2-
import { readChangeFiles } from '../changefile/readChangeFiles';
31
import type { BumpInfo } from '../types/BumpInfo';
4-
import { bumpInPlace } from './bumpInPlace';
52
import type { BeachballOptions } from '../types/BeachballOptions';
6-
import { getScopedPackages } from '../monorepo/getScopedPackages';
73
import type { PackageInfos } from '../types/PackageInfo';
8-
import { getPackageGroups } from '../monorepo/getPackageGroups';
9-
import { cloneObject } from '../object/cloneObject';
4+
import { bumpInMemory } from './bumpInMemory';
105

116
/**
12-
* Gather bump info and bump versions in memory.
13-
* Does NOT mutate the given `originalPackageInfos`.
7+
* @deprecated Use `bumpInMemory` instead.
148
*/
159
export function gatherBumpInfo(options: BeachballOptions, originalPackageInfos: PackageInfos): BumpInfo {
16-
const packageInfos = cloneObject(originalPackageInfos);
17-
const changes = readChangeFiles(options, packageInfos);
18-
19-
// Determine base change types for each package (not considering disallowedChangeTypes or groups)
20-
const calculatedChangeTypes = initializePackageChangeTypes(changes);
21-
22-
const bumpInfo: BumpInfo = {
23-
calculatedChangeTypes,
24-
packageInfos,
25-
packageGroups: getPackageGroups(packageInfos, options.path, options.groups),
26-
changeFileChangeInfos: changes,
27-
modifiedPackages: new Set<string>(),
28-
scopedPackages: new Set(getScopedPackages(options, packageInfos)),
29-
dependentChangedBy: {},
30-
};
31-
32-
bumpInPlace(bumpInfo, options);
33-
34-
return bumpInfo;
10+
return bumpInMemory(options, originalPackageInfos);
3511
}

src/cli.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,25 +37,25 @@ import { validate } from './validation/validate';
3737

3838
case 'publish': {
3939
const packageInfos = getPackageInfos(parsedOptions);
40-
validate(options, { checkDependencies: true }, packageInfos);
40+
const { bumpInfo } = validate(options, { checkDependencies: true }, packageInfos);
4141

4242
// set a default publish message
4343
options.message = options.message || 'applying package updates';
44-
await publish(options, packageInfos);
44+
await publish(options, packageInfos, bumpInfo);
4545
break;
4646
}
4747

4848
case 'bump': {
4949
const packageInfos = getPackageInfos(parsedOptions);
50-
validate(options, { checkDependencies: true }, packageInfos);
51-
await bump(options, packageInfos);
50+
const { bumpInfo } = validate(options, { checkDependencies: true }, packageInfos);
51+
await bump(options, packageInfos, bumpInfo);
5252
break;
5353
}
5454

5555
case 'canary': {
5656
const packageInfos = getPackageInfos(parsedOptions);
57-
validate(options, { checkDependencies: true }, packageInfos);
58-
await canary(options, packageInfos);
57+
const { bumpInfo } = validate(options, { checkDependencies: true }, packageInfos);
58+
await canary(options, packageInfos, bumpInfo);
5959
break;
6060
}
6161

src/commands/bump.ts

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { gatherBumpInfo } from '../bump/gatherBumpInfo';
1+
import { bumpInMemory } from '../bump/bumpInMemory';
22
import { performBump } from '../bump/performBump';
33
import { getPackageInfos } from '../monorepo/getPackageInfos';
44
import type { BeachballOptions } from '../types/BeachballOptions';
@@ -7,13 +7,23 @@ import type { PackageInfos } from '../types/PackageInfo';
77

88
/**
99
* Bump versions and update changelogs, but don't commit, push, or publish.
10+
* @param oldPackageInfo Pre-read package info prior to version bumps
11+
* @param bumpInfo Pre-calculated bump info from `validate()` (can be undefined for tests)
1012
*/
11-
export async function bump(options: BeachballOptions, packageInfos: PackageInfos): Promise<BumpInfo>;
13+
export async function bump(
14+
options: BeachballOptions,
15+
oldPackageInfo: PackageInfos,
16+
bumpInfo?: BumpInfo
17+
): Promise<BumpInfo>;
1218
/** @deprecated Must provide the package infos */
1319
export async function bump(options: BeachballOptions): Promise<BumpInfo>;
14-
export async function bump(options: BeachballOptions, packageInfos?: PackageInfos): Promise<BumpInfo> {
20+
export async function bump(
21+
options: BeachballOptions,
22+
oldPackageInfo?: PackageInfos,
23+
bumpInfo?: BumpInfo
24+
): Promise<BumpInfo> {
1525
// eslint-disable-next-line etc/no-deprecated
16-
const bumpInfo = gatherBumpInfo(options, packageInfos || getPackageInfos(options.path));
26+
bumpInfo ||= bumpInMemory(options, oldPackageInfo || getPackageInfos(options.path));
1727
// The bumpInfo is returned for testing
1828
return performBump(bumpInfo, options);
1929
}

src/commands/canary.ts

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,35 @@
11
import semver from 'semver';
2-
import { gatherBumpInfo } from '../bump/gatherBumpInfo';
2+
import { bumpInMemory } from '../bump/bumpInMemory';
33
import { performBump } from '../bump/performBump';
44
import { setDependentVersions } from '../bump/setDependentVersions';
55
import { getPackageInfos } from '../monorepo/getPackageInfos';
66
import { listPackageVersions } from '../packageManager/listPackageVersions';
77
import { publishToRegistry } from '../publish/publishToRegistry';
88
import type { BeachballOptions } from '../types/BeachballOptions';
99
import type { PackageInfos } from '../types/PackageInfo';
10+
import type { BumpInfo } from '../types/BumpInfo';
1011

11-
export async function canary(options: BeachballOptions, oldPackageInfo: PackageInfos): Promise<void>;
12+
/**
13+
* Bump and publish a "canary" prerelease version.
14+
* @param oldPackageInfo Pre-read package info prior to version bumps
15+
* @param bumpInfo Pre-calculated bump info from `validate()` (can be undefined for tests)
16+
*/
17+
export async function canary(
18+
options: BeachballOptions,
19+
oldPackageInfo: PackageInfos,
20+
bumpInfo: BumpInfo | undefined
21+
): Promise<void>;
1222
/** @deprecated Must provide the package infos */
1323
export async function canary(options: BeachballOptions): Promise<void>;
14-
export async function canary(options: BeachballOptions, oldPackageInfo?: PackageInfos): Promise<void> {
24+
export async function canary(
25+
options: BeachballOptions,
26+
oldPackageInfo?: PackageInfos,
27+
bumpInfo?: BumpInfo
28+
): Promise<void> {
1529
// eslint-disable-next-line etc/no-deprecated
1630
oldPackageInfo = oldPackageInfo || getPackageInfos(options.path);
1731

18-
const bumpInfo = gatherBumpInfo(options, oldPackageInfo);
32+
bumpInfo ||= bumpInMemory(options, oldPackageInfo);
1933

2034
options.keepChangeFiles = true;
2135
options.generateChangelog = false;

src/commands/publish.ts

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { gatherBumpInfo } from '../bump/gatherBumpInfo';
1+
import { bumpInMemory } from '../bump/bumpInMemory';
22
import type { BeachballOptions } from '../types/BeachballOptions';
33
import { gitFailFast, getBranchName, getCurrentHash, git } from 'workspace-tools';
44
import prompts from 'prompts';
@@ -12,11 +12,21 @@ import type { PackageInfos } from '../types/PackageInfo';
1212

1313
/**
1414
* Potentially bump, publish, and push package changes depending on options.
15+
* @param oldPackageInfos Pre-read package info prior to version bumps
16+
* @param bumpInfo Pre-calculated bump info from `validate()` (can be undefined for tests)
1517
*/
16-
export async function publish(options: BeachballOptions, oldPackageInfos: PackageInfos): Promise<void>;
18+
export async function publish(
19+
options: BeachballOptions,
20+
oldPackageInfos: PackageInfos,
21+
bumpInfo?: PublishBumpInfo
22+
): Promise<void>;
1723
/** @deprecated Must provide the package infos */
1824
export async function publish(options: BeachballOptions): Promise<void>;
19-
export async function publish(options: BeachballOptions, oldPackageInfos?: PackageInfos): Promise<void> {
25+
export async function publish(
26+
options: BeachballOptions,
27+
oldPackageInfos?: PackageInfos,
28+
bumpInfo?: PublishBumpInfo
29+
): Promise<void> {
2030
console.log('\nPreparing to publish');
2131

2232
const { path: cwd, branch, registry, tag } = options;
@@ -66,7 +76,7 @@ export async function publish(options: BeachballOptions, oldPackageInfos?: Packa
6676
gitFailFast(['checkout', '-b', publishBranch], { cwd });
6777

6878
console.log(`\nGathering info ${options.bump ? 'to bump versions' : 'about versions and changes'}`);
69-
const bumpInfo: PublishBumpInfo = gatherBumpInfo(options, oldPackageInfos);
79+
bumpInfo ||= bumpInMemory(options, oldPackageInfos);
7080

7181
// eslint-disable-next-line etc/no-deprecated
7282
if (options.new) {

0 commit comments

Comments
 (0)