Skip to content

Commit 78ad910

Browse files
authored
refactor(build): restructure build helpers to use classes MONGOSH-2007 (#2374)
1 parent bf1255f commit 78ad910

18 files changed

+989
-1183
lines changed

packages/build/src/homebrew/publish-to-homebrew.spec.ts

Lines changed: 41 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,25 @@
11
import chai, { expect } from 'chai';
22
import sinon from 'sinon';
33
import type { GithubRepo } from '@mongodb-js/devtools-github-repo';
4-
import { publishToHomebrew } from './publish-to-homebrew';
4+
import type { HomebrewPublisherConfig } from './publish-to-homebrew';
5+
import { HomebrewPublisher } from './publish-to-homebrew';
56

67
chai.use(require('sinon-chai'));
78

8-
describe('Homebrew publish-to-homebrew', function () {
9+
describe('HomebrewPublisher', function () {
910
let homebrewCore: GithubRepo;
1011
let homebrewCoreFork: GithubRepo;
1112
let createPullRequest: sinon.SinonStub;
1213
let httpsSha256: sinon.SinonStub;
1314
let generateFormula: sinon.SinonStub;
1415
let updateHomebrewFork: sinon.SinonStub;
1516

16-
beforeEach(function () {
17+
let testPublisher: HomebrewPublisher;
18+
19+
const setupHomebrewPublisher = (
20+
config: Omit<HomebrewPublisherConfig, 'homebrewCore' | 'homebrewCoreFork'>
21+
) => {
1722
createPullRequest = sinon.stub();
18-
httpsSha256 = sinon.stub();
19-
generateFormula = sinon.stub();
20-
updateHomebrewFork = sinon.stub();
2123

2224
homebrewCore = {
2325
repo: {
@@ -32,9 +34,33 @@ describe('Homebrew publish-to-homebrew', function () {
3234
repo: 'homebrew-core',
3335
},
3436
} as unknown as GithubRepo;
37+
38+
testPublisher = new HomebrewPublisher({
39+
...config,
40+
homebrewCore,
41+
homebrewCoreFork,
42+
});
43+
44+
httpsSha256 = sinon.stub(testPublisher, 'httpsSha256');
45+
generateFormula = sinon.stub(testPublisher, 'generateFormula');
46+
updateHomebrewFork = sinon.stub(testPublisher, 'updateHomebrewFork');
47+
};
48+
49+
beforeEach(function () {
50+
setupHomebrewPublisher({
51+
packageVersion: '1.0.0',
52+
githubReleaseLink: 'githubRelease',
53+
isDryRun: false,
54+
});
3555
});
3656

3757
it('creates and merges a PR on update and cleans up', async function () {
58+
setupHomebrewPublisher({
59+
packageVersion: '1.0.0',
60+
githubReleaseLink: 'githubRelease',
61+
isDryRun: false,
62+
});
63+
3864
httpsSha256
3965
.rejects()
4066
.withArgs(
@@ -69,16 +95,7 @@ describe('Homebrew publish-to-homebrew', function () {
6995
)
7096
.resolves({ prNumber: 42, url: 'url' });
7197

72-
await publishToHomebrew(
73-
homebrewCore,
74-
homebrewCoreFork,
75-
'1.0.0',
76-
'githubRelease',
77-
false,
78-
httpsSha256,
79-
generateFormula,
80-
updateHomebrewFork
81-
);
98+
await testPublisher.publish();
8299

83100
expect(httpsSha256).to.have.been.called;
84101
expect(generateFormula).to.have.been.called;
@@ -87,6 +104,12 @@ describe('Homebrew publish-to-homebrew', function () {
87104
});
88105

89106
it('does not try to push/merge when there is no formula update', async function () {
107+
setupHomebrewPublisher({
108+
packageVersion: '1.0.0',
109+
githubReleaseLink: 'githubRelease',
110+
isDryRun: false,
111+
});
112+
90113
httpsSha256
91114
.rejects()
92115
.withArgs(
@@ -111,16 +134,7 @@ describe('Homebrew publish-to-homebrew', function () {
111134
})
112135
.resolves(undefined);
113136

114-
await publishToHomebrew(
115-
homebrewCore,
116-
homebrewCoreFork,
117-
'1.0.0',
118-
'githubRelease',
119-
false,
120-
httpsSha256,
121-
generateFormula,
122-
updateHomebrewFork
123-
);
137+
await testPublisher.publish();
124138

125139
expect(httpsSha256).to.have.been.called;
126140
expect(generateFormula).to.have.been.called;
@@ -163,16 +177,7 @@ describe('Homebrew publish-to-homebrew', function () {
163177
)
164178
.resolves({ prNumber: 42, url: 'url' });
165179

166-
await publishToHomebrew(
167-
homebrewCore,
168-
homebrewCoreFork,
169-
'1.0.0',
170-
'githubRelease',
171-
false,
172-
httpsSha256,
173-
generateFormula,
174-
updateHomebrewFork
175-
);
180+
await testPublisher.publish();
176181

177182
expect(httpsSha256).to.have.been.called;
178183
expect(generateFormula).to.have.been.called;
Lines changed: 81 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,60 +1,88 @@
11
import type { GithubRepo } from '@mongodb-js/devtools-github-repo';
2-
import { generateUpdatedFormula } from './generate-formula';
3-
import { updateHomebrewFork } from './update-homebrew-fork';
4-
import { httpsSha256 } from './utils';
5-
6-
export async function publishToHomebrew(
7-
homebrewCore: GithubRepo,
8-
homebrewCoreFork: GithubRepo,
9-
packageVersion: string,
10-
githubReleaseLink: string,
11-
isDryRun: boolean,
12-
httpsSha256Fn = httpsSha256,
13-
generateFormulaFn = generateUpdatedFormula,
14-
updateHomebrewForkFn = updateHomebrewFork
15-
): Promise<void> {
16-
const cliReplPackageUrl = `https://registry.npmjs.org/@mongosh/cli-repl/-/cli-repl-${packageVersion}.tgz`;
17-
const packageSha = isDryRun
18-
? `dryRun-fakesha256-${Date.now()}`
19-
: await httpsSha256Fn(cliReplPackageUrl);
20-
21-
const homebrewFormula = await generateFormulaFn(
22-
{ version: packageVersion, sha: packageSha },
23-
homebrewCore,
24-
isDryRun
25-
);
26-
if (!homebrewFormula) {
27-
console.warn('There are no changes to the homebrew formula');
28-
return;
29-
}
2+
import { generateUpdatedFormula as generateUpdatedFormulaFn } from './generate-formula';
3+
import { updateHomebrewFork as updateHomebrewForkFn } from './update-homebrew-fork';
4+
import { httpsSha256 as httpsSha256Fn } from './utils';
5+
6+
export type HomebrewPublisherConfig = {
7+
homebrewCore: GithubRepo;
8+
homebrewCoreFork: GithubRepo;
9+
packageVersion: string;
10+
githubReleaseLink: string;
11+
isDryRun?: boolean;
12+
};
3013

31-
const forkBranch = await updateHomebrewForkFn({
32-
packageVersion,
33-
packageSha,
34-
homebrewFormula,
35-
homebrewCore,
36-
homebrewCoreFork,
37-
isDryRun,
38-
});
39-
if (!forkBranch) {
40-
console.warn('There are no changes to the homebrew formula');
41-
return;
14+
export class HomebrewPublisher {
15+
readonly httpsSha256: typeof httpsSha256Fn;
16+
readonly generateFormula: typeof generateUpdatedFormulaFn;
17+
readonly updateHomebrewFork: typeof updateHomebrewForkFn;
18+
19+
constructor(
20+
public config: HomebrewPublisherConfig,
21+
{
22+
httpsSha256 = httpsSha256Fn,
23+
generateFormula = generateUpdatedFormulaFn,
24+
updateHomebrewFork = updateHomebrewForkFn,
25+
} = {}
26+
) {
27+
this.httpsSha256 = httpsSha256;
28+
this.generateFormula = generateFormula;
29+
this.updateHomebrewFork = updateHomebrewFork;
4230
}
4331

44-
const description = `This PR was created automatically and bumps \`mongosh\` to the latest published version \`${packageVersion}\`.\n\nFor additional details see ${githubReleaseLink}.`;
32+
async publish(): Promise<void> {
33+
const {
34+
isDryRun,
35+
homebrewCore,
36+
packageVersion,
37+
homebrewCoreFork,
38+
githubReleaseLink,
39+
} = this.config;
40+
41+
const cliReplPackageUrl = `https://registry.npmjs.org/@mongosh/cli-repl/-/cli-repl-${packageVersion}.tgz`;
42+
const packageSha = isDryRun
43+
? `dryRun-fakesha256-${Date.now()}`
44+
: await this.httpsSha256(cliReplPackageUrl);
45+
46+
const homebrewFormula = await this.generateFormula(
47+
{ version: packageVersion, sha: packageSha },
48+
homebrewCore,
49+
isDryRun || false
50+
);
51+
if (!homebrewFormula) {
52+
console.warn('There are no changes to the homebrew formula');
53+
return;
54+
}
55+
56+
const forkBranch = await this.updateHomebrewFork({
57+
packageVersion,
58+
packageSha,
59+
homebrewFormula,
60+
homebrewCore,
61+
homebrewCoreFork,
62+
isDryRun: isDryRun || false,
63+
});
64+
if (!forkBranch) {
65+
console.warn('There are no changes to the homebrew formula');
66+
return;
67+
}
68+
69+
const description = `This PR was created automatically and bumps \`mongosh\` to the latest published version \`${packageVersion}\`.\n\nFor additional details see ${githubReleaseLink}.`;
4570

46-
if (isDryRun) {
47-
await homebrewCoreFork.deleteBranch(forkBranch);
48-
console.warn('Deleted branch instead of creating homebrew PR');
49-
return;
71+
if (isDryRun) {
72+
await homebrewCoreFork.deleteBranch(forkBranch);
73+
console.warn('Deleted branch instead of creating homebrew PR');
74+
return;
75+
}
76+
const pr = await homebrewCore.createPullRequest(
77+
`mongosh ${packageVersion}`,
78+
description,
79+
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
80+
`${homebrewCoreFork.repo.owner}:${forkBranch}`,
81+
'master'
82+
);
83+
console.info(
84+
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
85+
`Created PR #${pr.prNumber} in ${homebrewCore.repo.owner}/${homebrewCore.repo.repo}: ${pr.url}`
86+
);
5087
}
51-
const pr = await homebrewCore.createPullRequest(
52-
`mongosh ${packageVersion}`,
53-
description,
54-
`${homebrewCoreFork.repo.owner}:${forkBranch}`,
55-
'master'
56-
);
57-
console.info(
58-
`Created PR #${pr.prNumber} in ${homebrewCore.repo.owner}/${homebrewCore.repo.repo}: ${pr.url}`
59-
);
6088
}

packages/build/src/npm-packages/bump.spec.ts

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,12 @@
11
import { expect } from 'chai';
22
import type { SinonStub } from 'sinon';
33
import sinon from 'sinon';
4-
import {
5-
bumpMongoshReleasePackages,
6-
updateShellApiMongoshVersion,
7-
} from './bump';
4+
import { PackageBumper } from './bump';
85
import { promises as fs } from 'fs';
96
import path from 'path';
107
import { PROJECT_ROOT } from './constants';
118

12-
describe('npm-packages bump', function () {
9+
describe('PackageBumper', function () {
1310
let fsWriteFile: SinonStub;
1411
const shellApiSrc = path.join(
1512
PROJECT_ROOT,
@@ -19,9 +16,22 @@ describe('npm-packages bump', function () {
1916
'mongosh-version.ts'
2017
);
2118

19+
let testBumper: PackageBumper;
20+
let getPackagesInTopologicalOrder: sinon.SinonStub;
21+
2222
beforeEach(function () {
2323
fsWriteFile = sinon.stub(fs, 'writeFile');
2424
fsWriteFile.resolves();
25+
26+
const spawnSync = sinon.stub();
27+
spawnSync.resolves();
28+
29+
getPackagesInTopologicalOrder = sinon.stub();
30+
31+
testBumper = new PackageBumper({
32+
spawnSync,
33+
getPackagesInTopologicalOrder,
34+
});
2535
});
2636

2737
afterEach(function () {
@@ -30,15 +40,13 @@ describe('npm-packages bump', function () {
3040

3141
describe('bumpMongoshReleasePackages', function () {
3242
let fsReadFile: SinonStub;
33-
let getPackagesInTopologicalOrder: sinon.SinonStub;
3443
beforeEach(function () {
3544
fsReadFile = sinon.stub(fs, 'readFile');
36-
getPackagesInTopologicalOrder = sinon.stub();
3745
});
3846

3947
it('warns and does not run if version is not set', async function () {
4048
const consoleWarnSpy = sinon.spy(console, 'warn');
41-
await bumpMongoshReleasePackages('');
49+
await testBumper.bumpMongoshReleasePackages('');
4250
expect(consoleWarnSpy).calledOnceWith(
4351
'mongosh: Release version not specified. Skipping mongosh bump.'
4452
);
@@ -54,10 +62,6 @@ describe('npm-packages bump', function () {
5462
'packages',
5563
'autocomplete'
5664
);
57-
getPackagesInTopologicalOrder.resolves([
58-
{ name: 'mongosh', location: mongoshPath },
59-
{ name: '@mongosh/autocomplete', location: autocompletePath },
60-
]);
6165

6266
const rootProjectJson = path.join(PROJECT_ROOT, 'package.json');
6367
const mongoshProjectJson = path.join(mongoshPath, 'package.json');
@@ -106,12 +110,14 @@ describe('npm-packages bump', function () {
106110
fsReadFile.withArgs(file, 'utf8').resolves(JSON.stringify(json));
107111
}
108112

109-
const updateShellApiMongoshVersion = sinon.stub();
110-
await bumpMongoshReleasePackages(
111-
'9.9.9',
112-
getPackagesInTopologicalOrder,
113-
updateShellApiMongoshVersion
114-
);
113+
getPackagesInTopologicalOrder.resolves([
114+
{ name: 'mongosh', location: mongoshPath },
115+
{ name: '@mongosh/autocomplete', location: autocompletePath },
116+
]);
117+
118+
sinon.stub(testBumper, 'updateShellApiMongoshVersion').resolves();
119+
120+
await testBumper.bumpMongoshReleasePackages('9.9.9');
115121
expect(fsWriteFile).callCount(3);
116122

117123
expect(
@@ -168,7 +174,7 @@ describe('npm-packages bump', function () {
168174
export const MONGOSH_VERSION = '2.3.8';`);
169175

170176
const newVersion = '3.0.0';
171-
await updateShellApiMongoshVersion(newVersion);
177+
await testBumper.updateShellApiMongoshVersion(newVersion);
172178

173179
expect(fsWriteFile).calledWith(
174180
shellApiSrc,

0 commit comments

Comments
 (0)