Skip to content

Commit 3312bdc

Browse files
authored
chore(scripts): accurate cache for building docs (#5480)
1 parent 0d97454 commit 3312bdc

File tree

8 files changed

+64
-48
lines changed

8 files changed

+64
-48
lines changed

scripts/cache.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,23 +7,23 @@ import { exists } from './common.ts';
77
export class Cache {
88
folder: string;
99
generatedFiles: string[];
10-
filesToCache: string[];
10+
dependencies: string[];
1111
cacheFile: string;
1212

1313
constructor({
1414
folder,
1515
generatedFiles,
16-
filesToCache,
16+
dependencies,
1717
cacheFile,
1818
}: {
1919
folder: string;
2020
generatedFiles: string[];
21-
filesToCache: string[];
21+
dependencies: string[];
2222
cacheFile: string;
2323
}) {
2424
this.folder = folder;
2525
this.generatedFiles = generatedFiles;
26-
this.filesToCache = filesToCache;
26+
this.dependencies = dependencies;
2727
this.cacheFile = cacheFile;
2828
}
2929

@@ -34,14 +34,14 @@ export class Cache {
3434
hash += (await hashElement(`${this.folder}/${generatedFile}`)).hash;
3535
}
3636

37-
for (const fileToCache of this.filesToCache) {
38-
hash += (await hashElement(`${this.folder}/${fileToCache}`)).hash;
37+
for (const dependency of this.dependencies) {
38+
hash += (await hashElement(`${this.folder}/${dependency}`)).hash;
3939
}
4040

4141
return hash;
4242
}
4343

44-
async isValid(): Promise<boolean> {
44+
async hit(): Promise<boolean> {
4545
if (!(await exists(this.cacheFile))) {
4646
return false;
4747
}

scripts/common.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ export const ROOT_DIR = path.resolve(process.cwd(), '..');
3333
export const GENERATORS = Object.entries(clientsConfig).reduce(
3434
(current, [language, opts]) => {
3535
if (typeof opts === 'string') {
36+
// skip $schema
3637
return current;
3738
}
3839

@@ -51,7 +52,6 @@ export const GENERATORS = Object.entries(clientsConfig).reduce(
5152
}
5253

5354
current[key] = {
54-
additionalProperties: {},
5555
...opts,
5656
output,
5757
client: clientName,
@@ -61,7 +61,7 @@ export const GENERATORS = Object.entries(clientsConfig).reduce(
6161

6262
// guess the package name for js from the output folder variable
6363
if (language === 'javascript') {
64-
current[key].additionalProperties.packageName = output.substring(output.lastIndexOf('/') + 1);
64+
current[key].packageName = output.substring(output.lastIndexOf('/') + 1);
6565
}
6666
}
6767

@@ -153,11 +153,11 @@ async function buildCustomGenerators(): Promise<void> {
153153
const cache = new Cache({
154154
folder: toAbsolutePath('generators/'),
155155
generatedFiles: ['build/classes'],
156-
filesToCache: ['src', 'build.gradle', 'settings.gradle', '../config/.java-version'],
156+
dependencies: ['src', 'build.gradle', 'settings.gradle', '../config/.java-version'],
157157
cacheFile: toAbsolutePath('generators/.cache'),
158158
});
159159

160-
const cacheExists = await cache.isValid();
160+
const cacheExists = await cache.hit();
161161

162162
if (cacheExists) {
163163
spinner.succeed('job skipped, cache found for custom generators');

scripts/config.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import clientsConfig from '../config/clients.config.json' with { type: 'json' };
22

3-
import { CI } from './common.ts';
4-
import type { Language, LanguageConfig } from './types.ts';
3+
import { CI, createClientName } from './common.ts';
4+
import type { Generator, Language, LanguageConfig } from './types.ts';
55

66
export function getClientsConfigField(
77
language: Language,
@@ -45,6 +45,10 @@ export function getTestOutputFolder(language: Language): string {
4545
return getClientsConfigField(language, ['tests', 'outputFolder']);
4646
}
4747

48+
export function getSnippetFile(gen: Generator): string {
49+
return `docs/snippets/${gen.language}/${gen.snippets.outputFolder}/${createClientName(gen.client, gen.language)}${gen.snippets.extension}`;
50+
}
51+
4852
export function getDockerImage(language?: Language): string | undefined {
4953
if (CI || !language) {
5054
return undefined;

scripts/release/dart.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ export async function updateDartPackages(changelog: string, nextVersion: string)
1818
}
1919

2020
if (!nextVersion) {
21-
throw new Error(`Failed to bump '${gen.packageName}'.`);
21+
throw new Error(`Failed to bump '${gen.client}'.`);
2222
}
2323

2424
let currentVersion = await getPubspecField(gen.output, 'version');

scripts/specs/format.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,11 @@ export async function lintCommon(useCache: boolean): Promise<void> {
1818
const cache = new Cache({
1919
folder: toAbsolutePath('specs/'),
2020
generatedFiles: [],
21-
filesToCache: ['common'],
21+
dependencies: ['common'],
2222
cacheFile: toAbsolutePath('specs/dist/common.cache'),
2323
});
2424

25-
if (useCache && (await cache.isValid())) {
25+
if (useCache && (await cache.hit())) {
2626
spinner.succeed("job skipped, cache found for 'common' spec");
2727
return;
2828
}

scripts/specs/index.ts

Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,11 @@ import fsp from 'fs/promises';
33
import yaml from 'js-yaml';
44

55
import { Cache } from '../cache.ts';
6-
import { exists, run, toAbsolutePath } from '../common.ts';
6+
import { exists, GENERATORS, run, toAbsolutePath } from '../common.ts';
77
import { createSpinner } from '../spinners.ts';
88
import type { Spec } from '../types.ts';
99

10+
import { getSnippetFile } from '../config.ts';
1011
import { bundleSpecsForClient, bundleSpecsForDoc, lintCommon } from './format.ts';
1112
import type { BaseBuildSpecsOptions } from './types.ts';
1213

@@ -73,51 +74,64 @@ async function buildSpec({
7374
// In case of lite we use a the `search` spec as a base because only its bundled form exists.
7475
const specBase = isLiteSpec ? 'search' : spec;
7576
const logSuffix = `${outputFormat} ${docs ? 'doc spec' : 'spec'}`;
76-
const basePath = docs ? 'docs/' : 'specs/';
77-
const deps = isLiteSpec ? ['search', 'recommend'] : [spec];
77+
const basePath = docs ? 'docs' : 'specs';
78+
const deps = isLiteSpec ? ['specs/search', 'specs/recommend'] : [`specs/${spec}`];
79+
const generatedFile = `${basePath}/bundled/${spec}.${outputFormat}`;
80+
81+
const generatedFiles = [generatedFile];
82+
if (docs && outputFormat === 'yml') {
83+
for (const gen of Object.values(GENERATORS)) {
84+
if (gen.client === spec) {
85+
deps.push(getSnippetFile(gen));
86+
}
87+
}
88+
89+
generatedFiles.push(`docs/bundled/${spec}-snippets.json`);
90+
}
91+
7892
const cache = new Cache({
79-
folder: toAbsolutePath('specs/'),
80-
generatedFiles: [`bundled/${spec}.yml`],
81-
filesToCache: [...deps, 'common'],
82-
cacheFile: toAbsolutePath(`specs/dist/${spec}.cache`),
93+
folder: toAbsolutePath('.'),
94+
generatedFiles,
95+
dependencies: [...deps, 'specs/common'],
96+
cacheFile: toAbsolutePath(`specs/dist/${spec}-${basePath}-${outputFormat}.cache`),
8397
});
8498

8599
const spinner = createSpinner(`starting '${spec}' ${logSuffix}`);
86100

87101
if (useCache) {
88-
spinner.text = `checking cache for '${specBase}'`;
102+
spinner.text = `checking cache for '${specBase}' ${logSuffix}`;
89103

90-
if (await cache.isValid()) {
91-
spinner.succeed(`job skipped, cache found for '${specBase}'`);
104+
if (await cache.hit()) {
105+
spinner.succeed(`job skipped, cache found for '${specBase}' ${logSuffix}`);
92106
return;
93107
}
94108

95-
spinner.text = `cache not found for '${specBase}'`;
109+
spinner.text = `cache not found for '${specBase}' ${logSuffix}`;
96110
}
97111

98112
// First linting the base
99113
spinner.text = `linting '${spec}' ${logSuffix}`;
100114
await run(`yarn specs:fix specs/${specBase}`);
101115

102116
// Then bundle the file
103-
const bundledPath = toAbsolutePath(`${basePath}/bundled/${spec}.${outputFormat}`);
117+
const bundledPath = toAbsolutePath(generatedFile);
104118
await run(`yarn redocly bundle specs/${specBase}/spec.yml -o ${bundledPath} --ext ${outputFormat} `);
105119

106120
if (!(await exists(bundledPath))) {
107121
throw new Error(`Bundled file not found ${bundledPath}.`);
108122
}
109123

110124
// Add the correct tags to be able to generate the proper client
111-
if (!isLiteSpec) {
112-
docs ? await bundleSpecsForDoc(bundledPath, spec) : await bundleSpecsForClient(bundledPath, spec);
113-
} else {
125+
if (isLiteSpec) {
114126
await buildLiteSpec({
115127
spec,
116128
bundledPath: toAbsolutePath(bundledPath),
117129
outputFormat,
118130
docs,
119131
useCache,
120132
});
133+
} else if (outputFormat === 'yml') {
134+
docs ? await bundleSpecsForDoc(bundledPath, spec) : await bundleSpecsForClient(bundledPath, spec);
121135
}
122136

123137
spinner.text = `validating '${spec}' ${logSuffix}`;

scripts/specs/snippets.ts

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import fsp from 'fs/promises';
22

3-
import { GENERATORS, capitalize, createClientName, exists, toAbsolutePath } from '../common.ts';
3+
import { GENERATORS, capitalize, exists, toAbsolutePath } from '../common.ts';
44
import type { Language } from '../types.ts';
55

6+
import { getSnippetFile } from '../config.ts';
67
import type { CodeSamples, OpenAPICodeSample, SampleForOperation } from './types.ts';
78

89
export function getCodeSampleLabel(language: Language): OpenAPICodeSample['label'] {
@@ -63,16 +64,14 @@ export async function transformGeneratedSnippetsToCodeSamples(clientName: string
6364
continue;
6465
}
6566

66-
const ppath = toAbsolutePath(
67-
`docs/snippets/${gen.language}/${gen.snippets.outputFolder}/${createClientName(clientName, gen.language)}${gen.snippets.extension}`,
68-
);
67+
const snippetPath = toAbsolutePath(getSnippetFile(gen));
6968

70-
if (!(await exists(ppath))) {
69+
if (!(await exists(snippetPath))) {
7170
continue;
7271
}
7372

7473
// find snippets for each operationId in the current gen.language + clientName combo
75-
const snippetFileContent = await fsp.readFile(ppath, 'utf8');
74+
const snippetFileContent = await fsp.readFile(snippetPath, 'utf8');
7675

7776
const importMatch = snippetFileContent.match(/>IMPORT\n([\s\S]*?)\n.*IMPORT</);
7877
if (importMatch) {

scripts/types.ts

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@ import config from '../config/clients.config.json' with { type: 'json' };
22

33
import type { CodeSamples } from './specs/types.ts';
44

5+
type GeneratedFile = {
6+
extension: string;
7+
outputFolder: string;
8+
};
9+
510
/**
611
* Config.
712
*/
@@ -11,23 +16,17 @@ export type LanguageConfig = {
1116
modelFolder: string;
1217
apiFolder: string;
1318
packageVersion?: string;
14-
tests: {
15-
extension: string;
16-
outputFolder: string;
17-
};
19+
tests: GeneratedFile;
20+
snippets: GeneratedFile;
1821
};
1922

20-
type AdditionalProperties = Partial<{
21-
packageName: string;
22-
}> &
23-
Record<string, any>;
24-
25-
export type Generator = Record<string, any> & {
23+
export type Generator = {
2624
language: Language;
2725
client: string;
2826
key: string;
2927
output: string;
30-
additionalProperties: AdditionalProperties;
28+
snippets: GeneratedFile;
29+
packageName?: string;
3130
};
3231

3332
export type GeneratorMode = 'client' | 'guides' | 'snippets' | 'tests';

0 commit comments

Comments
 (0)