/
generate-azure-pipelines-tasks.mjs
72 lines (64 loc) · 2.38 KB
/
generate-azure-pipelines-tasks.mjs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
import os from 'node:os';
import fs from 'fs-extra';
import { glob } from 'glob';
import JSON5 from 'json5';
import Git from 'simple-git';
import path from 'upath';
import { updateJsonFile } from './utils.mjs';
const localPath = path.join(os.tmpdir(), 'azure-pipelines-tasks');
/**
* This script:
* 1. Clones the Azure Pipelines Tasks repo
* 2. Finds all `task.json` files
* 3. For each `task.json` it finds each commit that has that file
* 4. For each commit it gets the `task.json` content and extracts the task name, id and version
* 5. After all the `task.json` files have been processed it writes the results to `./data/azure-pipelines-tasks.json`
*/
await (async () => {
console.log('Generating azure pipelines tasks');
await fs.ensureDir(localPath);
const git = Git(localPath);
if (await git.checkIsRepo()) {
await git.pull();
} else {
await git.clone(
'https://github.com/microsoft/azure-pipelines-tasks.git',
'.'
);
}
// Find all `task.json` files
const files = (await glob(path.join(localPath, '**/task.json'))).map((file) =>
file.replace(`${localPath}/`, '')
);
/** @type {Record<string, Set<string>>} */
const tasks = {};
for (const file of files) {
// Find all commits that have the file
const revs = (await git.raw(['rev-list', 'HEAD', '--', file])).split('\n');
console.log(`Parsing ${file}`);
for (const rev of revs) {
try {
// Get the content of the file at the commit
const content = await git.show([`${rev}:${file}`]);
/** @type {{name: string, id: string, version: {Major: number, Minor: number, Patch: number}}} */
const parsedContent = JSON5.parse(content);
const version = `${parsedContent.version.Major}.${parsedContent.version.Minor}.${parsedContent.version.Patch}`;
tasks[parsedContent.name.toLowerCase()] =
tasks[parsedContent.name.toLowerCase()]?.add(version) ??
new Set([version]);
tasks[parsedContent.id.toLowerCase()] =
tasks[parsedContent.id.toLowerCase()]?.add(version) ??
new Set([version]);
} catch (e) {
console.error(`Failed to parse ${file} at ${rev}`);
console.error(e.toString());
}
}
}
const data = JSON.stringify(
tasks,
(_, value) => (value instanceof Set ? [...value] : value),
2
);
await updateJsonFile(`./data/azure-pipelines-tasks.json`, data);
})();