Skip to content

Commit 87b8e55

Browse files
committed
create new homebrew package scripts
1 parent 9008bfc commit 87b8e55

File tree

7 files changed

+174
-1
lines changed

7 files changed

+174
-1
lines changed
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { httpsSha256 } from './utils';
2+
3+
export async function generateHomebrewFormula(version: string): Promise<string> {
4+
const url = `https://registry.npmjs.org/@mongosh/cli-repl/-/cli-repl-${version}.tgz`;
5+
const sha = await httpsSha256(url);
6+
return renderFormula({ version, sha });
7+
}
8+
9+
function renderFormula(context: { version: string, sha: string }): string {
10+
return `require "language/node"
11+
12+
class Mongosh < Formula
13+
desc "The MongoDB Shell"
14+
15+
homepage "https://github.com/mongodb-js/mongosh#readme"
16+
url "https://registry.npmjs.org/@mongosh/cli-repl/-/cli-repl-${context.version}.tgz"
17+
version "${context.version}"
18+
19+
# This is the checksum of the archive. Can be obtained with:
20+
# curl -s https://registry.npmjs.org/@mongosh/cli-repl/-/cli-repl-${context.version}.tgz | shasum -a 256
21+
sha256 "${context.sha}"
22+
23+
depends_on "node@14"
24+
25+
def install
26+
system "#{Formula["node@14"].bin}/npm", "install", *Language::Node.std_npm_install_args(libexec)
27+
(bin/"mongosh").write_env_script libexec/"bin/mongosh", :PATH => "#{Formula["node@14"].opt_bin}:$PATH"
28+
end
29+
30+
test do
31+
system "#{bin}/mongosh --version"
32+
end
33+
end
34+
`;
35+
}

packages/build/src/homebrew/index.ts

Whitespace-only changes.
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import { execSync } from 'child_process';
2+
import { readFileSync, writeFileSync } from 'fs-extra';
3+
import path from 'path';
4+
import { expect, useTmpdir } from '../../../cli-repl/test/repl-helpers';
5+
import { updateMongoDBTap } from './update-mongodb-tap';
6+
7+
describe('Homebrew update-mongodb-tap', () => {
8+
const repoDir = useTmpdir();
9+
const tmpDir = useTmpdir();
10+
11+
let mongoBrewFormulaDir: string;
12+
let mongoshFormulaFile: string;
13+
14+
beforeEach(() => {
15+
execSync('git init', { cwd: repoDir.path });
16+
17+
mongoBrewFormulaDir = path.resolve(repoDir.path, 'Formula');
18+
mongoshFormulaFile = path.resolve(mongoBrewFormulaDir, 'mongosh.rb');
19+
20+
execSync(`mkdir -p ${mongoBrewFormulaDir}`);
21+
writeFileSync(mongoshFormulaFile, 'formula', 'utf-8');
22+
execSync('git add . && git commit -m "add mongosh formula"', { cwd: repoDir.path });
23+
});
24+
25+
it('writes updated formula and pushes changes', async() => {
26+
const updated = await updateMongoDBTap({
27+
tmpDir: tmpDir.path,
28+
packageVersion: '1.0.0',
29+
packageSha: 'sha',
30+
homebrewFormula: 'updated formula',
31+
mongoHomebrewRepoUrl: `file://${repoDir.path}`
32+
});
33+
expect(updated).to.equal(true);
34+
35+
execSync('git checkout mongosh-1.0.0-sha', { cwd: repoDir.path });
36+
expect(readFileSync(mongoshFormulaFile, 'utf-8')).to.equal('updated formula');
37+
});
38+
39+
it('does not push changes if formula is same', async() => {
40+
const updated = await updateMongoDBTap({
41+
tmpDir: tmpDir.path,
42+
packageVersion: '1.0.0',
43+
packageSha: 'sha',
44+
homebrewFormula: 'formula',
45+
mongoHomebrewRepoUrl: `file://${repoDir.path}`
46+
});
47+
expect(updated).to.equal(false);
48+
49+
const branches = execSync('git branch -a', { cwd: repoDir.path }).toString().trim();
50+
expect(branches).to.equal('* master');
51+
});
52+
});
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { execSync } from 'child_process';
2+
import { version } from 'os';
3+
import path from 'path';
4+
import { promises as fs } from 'fs';
5+
import { cloneRepository } from './utils';
6+
7+
export interface UpdateMongoDBTapParameters {
8+
packageVersion: string;
9+
packageSha: string;
10+
homebrewFormula: string;
11+
tmpDir: string;
12+
mongoHomebrewRepoUrl?: string;
13+
}
14+
15+
export async function updateMongoDBTap(params: UpdateMongoDBTapParameters): Promise<boolean> {
16+
const repoUrl = params.mongoHomebrewRepoUrl || '[email protected]:mongodb/homebrew-brew.git';
17+
const cloneDir = path.resolve(params.tmpDir, 'homebrew-brew');
18+
cloneRepository(cloneDir, repoUrl);
19+
20+
const branchName = `mongosh-${params.packageVersion}-${params.packageSha}`;
21+
execSync(`git checkout -b ${branchName}`, { cwd: cloneDir, stdio: 'inherit' });
22+
23+
const formulaPath = path.resolve(cloneDir, 'Formula', 'mongosh.rb');
24+
25+
const currentContent = await fs.readFile(formulaPath, 'utf-8');
26+
if (currentContent === params.homebrewFormula) {
27+
console.warn('There are no changes to the homebrew formula');
28+
return false;
29+
}
30+
31+
await fs.writeFile( formulaPath, params.homebrewFormula, 'utf-8');
32+
33+
execSync('git add .', { cwd: cloneDir, stdio: 'inherit' });
34+
execSync(`git commit -m "mongosh ${version}"`, { cwd: cloneDir, stdio: 'inherit' });
35+
execSync(`git push origin ${branchName}`, { cwd: cloneDir, stdio: 'inherit' });
36+
return true;
37+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { execSync } from 'child_process';
2+
import { expect, useTmpdir } from '../../../cli-repl/test/repl-helpers';
3+
import { cloneRepository } from './utils';
4+
5+
describe('Homebrew Utils', () => {
6+
const repoDir = useTmpdir();
7+
const tmpDir = useTmpdir();
8+
9+
beforeEach(() => {
10+
execSync('git init', { cwd: repoDir.path });
11+
execSync('touch empty.txt', { cwd: repoDir.path });
12+
execSync('git add . && git commit -m "commit1"', { cwd: repoDir.path });
13+
execSync('touch another.txt', { cwd: repoDir.path });
14+
execSync('git add . && git commit -m "commit2"', { cwd: repoDir.path });
15+
});
16+
17+
describe('cloneRepository', () => {
18+
it('clones shallow as requested', () => {
19+
cloneRepository(tmpDir.path, `file://${repoDir.path}`);
20+
const output = execSync('git log -2 --oneline', { cwd: tmpDir.path }).toString();
21+
const lines = output.split('\n').filter(l => !!l);
22+
expect(lines.length).to.equal(1);
23+
expect(lines[0]).to.match(/ commit2$/);
24+
});
25+
});
26+
});

packages/build/src/homebrew/utils.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { execSync } from 'child_process';
2+
import crypto from 'crypto';
3+
import https from 'https';
4+
5+
export function httpsSha256(url: string): Promise<string> {
6+
return new Promise((resolve, reject) => {
7+
https.get(url, (stream) => {
8+
const hash = crypto.createHash('sha256');
9+
stream.on('error', err => reject(err));
10+
stream.on('data', chunk => hash.update(chunk));
11+
stream.on('end', () => resolve(hash.digest('hex')));
12+
});
13+
});
14+
}
15+
16+
export function cloneRepository(cloneDir: string, repositoryUrl: string): void {
17+
execSync(`git clone "${repositoryUrl}" "${cloneDir}" --depth 1`, { stdio: 'inherit' });
18+
}
19+

packages/cli-repl/test/repl-helpers.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,15 @@ chai.use(chaiAsPromised);
1717
// to wait for these to finish.
1818
const tick = promisify(setImmediate);
1919

20+
// We keep an additional index as we might create two temp directories
21+
// at the same time stamp leading to conflicts
22+
let tmpDirsIndex = 1;
23+
2024
function useTmpdir(): { readonly path: string } {
2125
let tmpdir: string;
2226

2327
beforeEach(async() => {
24-
tmpdir = path.resolve(__dirname, '..', '..', '..', 'tmp', 'test', `repltest-${Date.now()}`);
28+
tmpdir = path.resolve(__dirname, '..', '..', '..', 'tmp', 'test', `repltest-${Date.now()}-${tmpDirsIndex++}`);
2529
await fs.mkdir(tmpdir, { recursive: true });
2630
});
2731

0 commit comments

Comments
 (0)