Skip to content

Commit c8bf6ce

Browse files
committed
perf(scripts/diff-features): fetch enumerations async
1 parent 65becf4 commit c8bf6ce

File tree

2 files changed

+63
-69
lines changed

2 files changed

+63
-69
lines changed

scripts/diff-features.ts

Lines changed: 37 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,26 @@
11
/* This file is a part of @mdn/browser-compat-data
22
* See LICENSE file for more information. */
33

4-
import { execSync } from 'node:child_process';
4+
import { exec, execSync } from 'node:child_process';
55
import fs from 'node:fs';
6+
import { promisify } from 'node:util';
7+
import path from 'node:path';
68

79
import esMain from 'es-main';
810
import yargs from 'yargs';
911
import { hideBin } from 'yargs/helpers';
12+
import { temporaryDirectoryTask } from 'tempy';
13+
14+
/**
15+
* Executes a command asynchronously.
16+
* @param command The command to execute asynchronously.
17+
* @returns The output of the command.
18+
*/
19+
const execAsync = async (command: string): Promise<string> => {
20+
const result = await promisify(exec)(command, { encoding: 'utf-8' });
21+
22+
return result.stdout.trim();
23+
};
1024

1125
/**
1226
* Compare two references and print diff as Markdown or JSON
@@ -16,14 +30,14 @@ import { hideBin } from 'yargs/helpers';
1630
* @param opts.format Format to export data as (either 'markdown' or 'json', default 'json')
1731
* @param opts.github Whether to obtain artifacts from GitHub
1832
*/
19-
const main = (opts: {
33+
const main = async (opts: {
2034
ref1: string | undefined;
2135
ref2: string | undefined;
2236
format?: string;
2337
github?: boolean;
24-
}): void => {
38+
}): Promise<void> => {
2539
const { ref1, ref2, format, github } = opts;
26-
const results = diff({ ref1, ref2, github });
40+
const results = await diff({ ref1, ref2, github });
2741

2842
if (format === 'markdown') {
2943
printMarkdown(results.added, results.removed);
@@ -41,12 +55,12 @@ const main = (opts: {
4155
* @param opts.quiet If true, don't log to console
4256
* @returns Diff between two refs
4357
*/
44-
const diff = (opts: {
58+
const diff = async (opts: {
4559
ref1?: string;
4660
ref2?: string;
4761
github?: boolean;
4862
quiet?: boolean;
49-
}): { added: string[]; removed: string[] } => {
63+
}): Promise<{ added: string[]; removed: string[] }> => {
5064
const { ref1, ref2, github, quiet } = opts;
5165
let refA, refB;
5266

@@ -64,8 +78,8 @@ const diff = (opts: {
6478
refB = `${ref1}`;
6579
}
6680

67-
const aSide = enumerate(refA, github === false, quiet);
68-
const bSide = enumerate(refB, github === false, quiet);
81+
const aSide = await enumerate(refA, github === false, quiet);
82+
const bSide = await enumerate(refB, github === false, quiet);
6983

7084
return {
7185
added: [...bSide].filter((feature) => !aSide.has(feature)),
@@ -80,14 +94,14 @@ const diff = (opts: {
8094
* @param quiet If true, don't log to console
8195
* @returns Feature list from reference
8296
*/
83-
const enumerate = (
97+
const enumerate = async (
8498
ref: string,
8599
skipGithub: boolean,
86100
quiet = false,
87-
): Set<string> => {
101+
): Promise<Set<string>> => {
88102
if (!skipGithub) {
89103
try {
90-
return new Set(getEnumerationFromGithub(ref));
104+
return new Set(await getEnumerationFromGithub(ref));
91105
} catch (e) {
92106
if (!quiet) {
93107
console.error(
@@ -105,50 +119,28 @@ const enumerate = (
105119
* @param ref Reference to obtain features for
106120
* @returns Feature list from reference
107121
*/
108-
const getEnumerationFromGithub = (ref: string): string[] => {
122+
const getEnumerationFromGithub = async (ref: string): Promise<string[]> => {
109123
const ENUMERATE_WORKFLOW = '15595228';
110124
const ENUMERATE_WORKFLOW_ARTIFACT = 'enumerate-features';
111125
const ENUMERATE_WORKFLOW_FILE = 'features.json';
112126

113-
/**
114-
* Unlinks the workflow file
115-
*/
116-
const unlinkFile = () => {
117-
try {
118-
fs.unlinkSync(ENUMERATE_WORKFLOW_FILE);
119-
} catch (err: any) {
120-
if (err.code == 'ENOENT') {
121-
return;
122-
}
123-
throw err;
124-
}
125-
};
126-
127-
const hash = execSync(`git rev-parse ${ref}`, {
128-
encoding: 'utf-8',
129-
}).trim();
130-
const workflowRun = execSync(
127+
const hash = await execAsync(`git rev-parse ${ref}`);
128+
const workflowRun = await execAsync(
131129
`gh api /repos/:owner/:repo/actions/workflows/${ENUMERATE_WORKFLOW}/runs\\?branch=main\\&head_sha=${hash}\\&per_page=1 --jq '[.workflow_runs[] | select(.head_sha=="${hash}") | .id] | first'`,
132-
{
133-
encoding: 'utf-8',
134-
},
135-
).trim();
130+
);
136131

137132
if (!workflowRun) {
138133
throw Error('No workflow run found for commit.');
139134
}
140135

141-
try {
142-
unlinkFile();
143-
execSync(
144-
`gh run download ${workflowRun} -n ${ENUMERATE_WORKFLOW_ARTIFACT}`,
145-
);
146-
return JSON.parse(
147-
fs.readFileSync(ENUMERATE_WORKFLOW_FILE, { encoding: 'utf-8' }),
136+
return await temporaryDirectoryTask(async (tempdir) => {
137+
await execAsync(
138+
`gh run download ${workflowRun} -n ${ENUMERATE_WORKFLOW_ARTIFACT} --dir ${tempdir}`,
148139
);
149-
} finally {
150-
unlinkFile();
151-
}
140+
const file = path.join(tempdir, ENUMERATE_WORKFLOW_FILE);
141+
142+
return JSON.parse(fs.readFileSync(file, { encoding: 'utf-8' }));
143+
});
152144
};
153145

154146
/**
@@ -249,7 +241,7 @@ if (esMain(import.meta)) {
249241
},
250242
);
251243

252-
main(argv as any);
244+
await main(argv as any);
253245
}
254246

255247
export default diff;

scripts/release/changes.ts

Lines changed: 26 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -72,13 +72,13 @@ const pullsFromGitHub = (fromDate: string): FeatureChange[] =>
7272
* @param pull The pull request to test
7373
* @returns The changes from the pull request
7474
*/
75-
const getDiff = (
75+
const getDiff = async (
7676
pull: FeatureChange,
77-
): { added: string[]; removed: string[] } => {
77+
): Promise<{ added: string[]; removed: string[] }> => {
7878
let diff;
7979

8080
try {
81-
diff = diffFeatures({ ref1: pull.mergeCommit, quiet: true });
81+
diff = await diffFeatures({ ref1: pull.mergeCommit, quiet: true });
8282
} catch (e) {
8383
throw new Error(
8484
chalk`{red ${e}}\n {yellow (Failed to diff features for #${pull.number}, skipping)}`,
@@ -123,27 +123,29 @@ export const getChanges = async (date: string): Promise<Changes> => {
123123

124124
progressBar.start(pulls.length, 0);
125125

126-
for (const pull of pulls) {
127-
const diff = getDiff(pull);
128-
129-
changes.added.push(
130-
...diff.added.map((feature) => ({
131-
number: pull.number,
132-
url: pull.url,
133-
feature,
134-
})),
135-
);
136-
137-
changes.removed.push(
138-
...diff.removed.map((feature) => ({
139-
number: pull.number,
140-
url: pull.url,
141-
feature,
142-
})),
143-
);
144-
145-
progressBar.increment();
146-
}
126+
await Promise.all(
127+
pulls.map(async (pull) => {
128+
const diff = await getDiff(pull);
129+
130+
changes.added.push(
131+
...diff.added.map((feature) => ({
132+
number: pull.number,
133+
url: pull.url,
134+
feature,
135+
})),
136+
);
137+
138+
changes.removed.push(
139+
...diff.removed.map((feature) => ({
140+
number: pull.number,
141+
url: pull.url,
142+
feature,
143+
})),
144+
);
145+
146+
progressBar.increment();
147+
}),
148+
);
147149

148150
progressBar.stop();
149151
console.log('\n');

0 commit comments

Comments
 (0)