Skip to content

Commit 674cd5c

Browse files
committed
cache benchmark revision archives
1 parent 88c4543 commit 674cd5c

2 files changed

Lines changed: 68 additions & 36 deletions

File tree

resources/benchmark/projects.ts

Lines changed: 60 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import assert from 'node:assert';
12
import fs from 'node:fs';
23
import path from 'node:path';
34

@@ -6,53 +7,60 @@ import { git, localRepoPath, makeTmpDir, npm } from '../utils.js';
67
import { LOCAL } from './config.js';
78
import type { BenchmarkProject } from './types.js';
89

9-
// Build a benchmark-friendly environment for each revision.
10+
// Build a benchmark-friendly install for each revision.
1011
export function prepareBenchmarkProjects(
1112
revisionList: ReadonlyArray<string>,
1213
): Array<BenchmarkProject> {
1314
const { tmpDirPath } = makeTmpDir('graphql-js-benchmark');
15+
const { tmpDirPath: benchmarkCachePath } = makeTmpDir(
16+
'graphql-js-benchmark-cache',
17+
false,
18+
);
1419

1520
return revisionList.map((revision) => {
16-
console.log(`\u{1F373} Preparing ${revision}...`);
17-
const projectPath = tmpDirPath('setup', revision);
18-
fs.rmSync(projectPath, { recursive: true, force: true });
19-
fs.mkdirSync(projectPath, { recursive: true });
20-
21-
fs.cpSync(localRepoPath('benchmark'), path.join(projectPath, 'benchmark'), {
22-
recursive: true,
23-
});
24-
25-
fs.writeFileSync(
26-
path.join(projectPath, 'package.json'),
27-
JSON.stringify(
21+
// Resolve refs like "main" to full SHAs so equivalent revisions reuse setup.
22+
const hash = revision === LOCAL ? LOCAL : git().revParse(revision);
23+
const projectPath = tmpDirPath('setup', hash);
24+
if (!fs.existsSync(projectPath)) {
25+
console.log('\u{1F373} Preparing ' + revision + '...');
26+
fs.mkdirSync(projectPath, { recursive: true });
27+
fs.cpSync(
28+
localRepoPath('benchmark'),
29+
path.join(projectPath, 'benchmark'),
2830
{
29-
private: true,
30-
type: 'module',
31-
dependencies: {
32-
graphql: prepareNPMPackage(revision),
33-
},
31+
recursive: true,
3432
},
35-
null,
36-
2,
37-
),
38-
);
39-
npm({ cwd: projectPath, quiet: true }).install('--ignore-scripts');
33+
);
34+
35+
fs.writeFileSync(
36+
path.join(projectPath, 'package.json'),
37+
JSON.stringify(
38+
{
39+
private: true,
40+
type: 'module',
41+
dependencies: {
42+
graphql: prepareNPMPackage(hash),
43+
},
44+
},
45+
null,
46+
2,
47+
),
48+
);
49+
npm({ cwd: projectPath, quiet: true }).install('--ignore-scripts');
50+
}
4051

4152
return { revision, projectPath };
4253
});
4354

44-
function prepareNPMPackage(revision: string): string {
45-
if (revision === LOCAL) {
55+
function prepareNPMPackage(hash: string): string {
56+
if (hash === LOCAL) {
4657
const repoDir = localRepoPath();
4758
const archivePath = tmpDirPath('graphql-local.tgz');
48-
fs.renameSync(buildNPMArchive(repoDir), archivePath);
59+
copyBuiltArchive(repoDir, archivePath);
4960
return archivePath;
5061
}
5162

52-
// Returns the complete git hash for a given git revision reference.
53-
const hash = git().revParse(revision);
54-
55-
const archivePath = tmpDirPath(`graphql-${hash}.tgz`);
63+
const archivePath = benchmarkCachePath(`graphql-${hash}.tgz`);
5664
if (fs.existsSync(archivePath)) {
5765
return archivePath;
5866
}
@@ -63,16 +71,35 @@ export function prepareBenchmarkProjects(
6371
git({ quiet: true }).clone(localRepoPath(), repoDir);
6472
git({ cwd: repoDir, quiet: true }).checkout('--detach', hash);
6573
npm({ cwd: repoDir, quiet: true }).ci('--ignore-scripts');
66-
fs.renameSync(buildNPMArchive(repoDir), archivePath);
74+
copyBuiltArchive(repoDir, archivePath);
6775
fs.rmSync(repoDir, { recursive: true });
6876
return archivePath;
6977
}
7078

79+
function copyBuiltArchive(repoDir: string, archivePath: string): void {
80+
const sourcePath = buildNPMArchive(repoDir);
81+
fs.copyFileSync(sourcePath, archivePath);
82+
fs.rmSync(sourcePath, { force: true });
83+
}
84+
7185
function buildNPMArchive(repoDir: string): string {
7286
npm({ cwd: repoDir, quiet: true }).run('build:npm');
7387

7488
const distDir = path.join(repoDir, 'npmDist');
75-
const archiveName = npm({ cwd: repoDir, quiet: true }).pack(distDir);
76-
return path.join(repoDir, archiveName);
89+
const archivePath = path.join(repoDir, getNPMArchiveName(repoDir));
90+
fs.rmSync(archivePath, { force: true });
91+
npm({ cwd: repoDir, quiet: true }).pack(distDir);
92+
assert(fs.existsSync(archivePath), 'npm pack did not create an archive.');
93+
return archivePath;
7794
}
7895
}
96+
97+
function getNPMArchiveName(repoDir: string): string {
98+
const packageJSON = JSON.parse(
99+
fs.readFileSync(path.join(repoDir, 'package.json'), 'utf8'),
100+
) as { name?: string; version?: string };
101+
const packageName = packageJSON.name?.replace(/^@/, '').replaceAll('/', '-');
102+
assert(packageName != null, 'package.json is missing a package name.');
103+
assert(packageJSON.version != null, 'package.json is missing a version.');
104+
return `${packageName}-${packageJSON.version}.tgz`;
105+
}

resources/utils.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,15 @@ interface MakeTmpDirReturn {
1818
tmpDirPath: (...paths: ReadonlyArray<string>) => string;
1919
}
2020

21-
export function makeTmpDir(name: string): MakeTmpDirReturn {
21+
export function makeTmpDir(
22+
name: string,
23+
clear: boolean = true,
24+
): MakeTmpDirReturn {
2225
const tmpDir = path.join(os.tmpdir(), name);
23-
fs.rmSync(tmpDir, { recursive: true, force: true });
24-
fs.mkdirSync(tmpDir);
26+
if (clear) {
27+
fs.rmSync(tmpDir, { recursive: true, force: true });
28+
}
29+
fs.mkdirSync(tmpDir, { recursive: true });
2530

2631
return {
2732
tmpDirPath: (...paths) => path.join(tmpDir, ...paths),

0 commit comments

Comments
 (0)