-
Notifications
You must be signed in to change notification settings - Fork 196
/
Copy pathgenerate.ts
136 lines (120 loc) · 4.02 KB
/
generate.ts
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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
/**
* @license
* Copyright 2021 Google LLC
* SPDX-License-Identifier: BSD-3-Clause
*/
import * as typedoc from 'typedoc';
import * as fs from 'fs/promises';
import * as pathlib from 'path';
import {execFile} from 'child_process';
import {promisify} from 'util';
import {ApiDocsTransformer} from './transformer.js';
import {lit2Config} from './configs/lit-2.js';
import {lit3Config} from './configs/lit-3.js';
import type {ApiDocsConfig} from './types.js';
const isWindows = /^win/.test(process.platform)
const execFileAsync = promisify(execFile);
// Only generate documentation for most recent Lit versions.
const configs = [lit2Config, lit3Config];
/**
* Check whether the given file path exists.
*/
const fileExists = async (path: string): Promise<boolean> => {
try {
await fs.stat(path);
return true;
} catch (err) {
if ((err as {code?: string}).code !== 'ENOENT') {
throw err;
}
}
return false;
};
/**
* Clone the given Git repo URL at the given commit into the given directory.
*/
const clone = async ({repo, gitDir, commit}: ApiDocsConfig) => {
console.log(`cloning git repo ${repo} to ${gitDir} at ${commit}`);
// This is the leanest way to shallow fetch just one commit without fetching
// any other git history.
await execFileAsync('git', ['init', gitDir]);
await execFileAsync(
'git',
['remote', 'add', 'origin', `https://github.com/${repo}`],
{cwd: gitDir}
);
await execFileAsync('git', ['fetch', 'origin', '--depth=1', commit], {
cwd: gitDir,
});
await execFileAsync('git', ['checkout', commit], {cwd: gitDir});
};
const INSTALLED_FILE = 'INSTALLED';
/**
* Run NPM install and other given setup commands.
*/
const setup = async (config: ApiDocsConfig) => {
console.log(`running npm ci in ${config.gitDir}`);
await execFileAsync(isWindows ? 'npm.cmd' : 'npm', ['ci'], {cwd: config.gitDir});
for (let {cmd, args} of config.extraSetupCommands ?? []) {
console.log(`running ${cmd} ${args.join(' ')} in ${config.gitDir}`);
if (cmd === 'npm' && isWindows) cmd = 'npm.cmd'
await execFileAsync(cmd, args, {cwd: config.gitDir});
}
await fs.writeFile(pathlib.join(config.workDir, INSTALLED_FILE), '', 'utf8');
};
const analyze = async (config: ApiDocsConfig) => {
const installedFilename = pathlib.join(config.workDir, INSTALLED_FILE);
const installedFileExists = await fileExists(installedFilename);
if (
!installedFileExists ||
(await fs.readFile(installedFilename, 'utf8')).trim() !== config.commit
) {
if (installedFileExists) {
await fs.rm(installedFilename);
}
if (await fileExists(config.gitDir)) {
await fs.rm(config.gitDir, {recursive: true});
}
await clone(config);
await setup(config);
await fs.writeFile(installedFilename, config.commit, 'utf8');
} else {
console.log(`Re-using git repo ${config.gitDir}`);
}
console.log(`Analyzing ${config.gitDir}`);
const app = new typedoc.Application();
app.options.addReader(new typedoc.TSConfigReader());
app.bootstrap({
tsconfig: config.tsConfigPath,
entryPoints: config.entrypointModules,
entryPointStrategy: typedoc.EntryPointStrategy.Expand,
});
const root = app.convert();
if (!root) {
throw new Error('TypeDoc.Application.convert() returned undefined');
}
const json = await app.serializer.projectToObject(
root,
pathlib.resolve(config.tsConfigPath, '..')
);
const transformer = new ApiDocsTransformer(json, config);
const {pages, symbolMap} = await transformer.transform();
await fs.mkdir(pathlib.dirname(config.pagesOutPath), {recursive: true});
await fs.writeFile(
config.pagesOutPath,
JSON.stringify(pages, null, 2),
'utf8'
);
console.log(`Wrote ${config.pagesOutPath}`);
await fs.mkdir(pathlib.dirname(config.symbolsOutPath), {recursive: true});
await fs.writeFile(
config.symbolsOutPath,
JSON.stringify(symbolMap, null, 2),
'utf8'
);
console.log(`Wrote ${config.symbolsOutPath}`);
};
const main = async () => {
await Promise.all(configs.map((config) => analyze(config)));
};
main();