Skip to content

Commit

Permalink
chore: cache custom generators (#311)
Browse files Browse the repository at this point in the history
  • Loading branch information
shortcuts authored Mar 30, 2022
1 parent 7a7164a commit 7a65dac
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 24 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ build
pom.xml

dist
.cache

.openapi-generator

Expand Down
37 changes: 14 additions & 23 deletions scripts/buildSpecs.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import fsp from 'fs/promises';

import { hashElement } from 'folder-hash';
import yaml from 'js-yaml';

import { exists, run, toAbsolutePath } from './common';
import { checkForCache, exists, run, toAbsolutePath } from './common';
import { createSpinner } from './oraLog';
import type { Spec } from './pre-gen/setHostsOptions';

Expand Down Expand Up @@ -53,30 +52,22 @@ async function buildSpec(
let hash = '';

if (useCache) {
const spinner = createSpinner(
`checking cache for '${client}'`,
const { cacheExists, hash: newCache } = await checkForCache(
{
job: `'${client}' specs`,
folder: toAbsolutePath('specs/'),
generatedFiles: [`bundled/${client}.yml`],
filesToCache: [client, 'common'],
cacheFile,
},
verbose
).start();
// check if file and cache exist
if (await exists(toAbsolutePath(`specs/bundled/${client}.yml`))) {
// compare with stored cache
const specHash = (await hashElement(toAbsolutePath(`specs/${client}`)))
.hash;
const commonHash = (await hashElement(toAbsolutePath(`specs/common`)))
.hash;
hash = `${specHash}-${commonHash}`;
if (await exists(cacheFile)) {
const storedHash = (await fsp.readFile(cacheFile)).toString();
if (storedHash === hash) {
spinner.succeed(
`skipped building ${client} spec because the files did not change`
);
return;
}
}
);

if (cacheExists) {
return;
}

spinner.info(`cache not found for ${client}' spec`);
hash = newCache;
}

const spinner = createSpinner(`building ${client} spec`, verbose).start();
Expand Down
77 changes: 76 additions & 1 deletion scripts/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,17 @@ import fsp from 'fs/promises';
import path from 'path';

import execa from 'execa'; // https://github.com/sindresorhus/execa/tree/v5.1.1
import { hashElement } from 'folder-hash';

import openapitools from '../openapitools.json';

import { createSpinner } from './oraLog';
import type { Generator, RunOptions } from './types';
import type {
CheckForCache,
CheckForCacheOptions,
Generator,
RunOptions,
} from './types';

export const CI = Boolean(process.env.CI);
export const DOCKER = Boolean(process.env.DOCKER);
Expand Down Expand Up @@ -194,11 +200,80 @@ export async function gitCommit({
);
}

export async function checkForCache(
{
job,
folder,
generatedFiles,
filesToCache,
cacheFile,
}: CheckForCacheOptions,
verbose: boolean
): Promise<CheckForCache> {
const spinner = createSpinner(`checking cache for ${job}`, verbose).start();
const cache: CheckForCache = {
cacheExists: false,
hash: '',
};
const generatedFilesExists = (
await Promise.all(
generatedFiles.map((generatedFile) =>
exists(`${folder}/${generatedFile}`)
)
)
).every((exist) => exist);

for (const fileToCache of filesToCache) {
const fileHash = (await hashElement(`${folder}/${fileToCache}`)).hash;

cache.hash = `${cache.hash}-${fileHash}`;
}

// We only skip if both the cache and the generated file exists
if (generatedFilesExists && (await exists(cacheFile))) {
const storedHash = (await fsp.readFile(cacheFile)).toString();
if (storedHash === cache.hash) {
spinner.succeed(`job skipped, cache found for ${job}`);
return {
cacheExists: true,
hash: cache.hash,
};
}
}

spinner.info(`cache not found for ${job}`);

return cache;
}

export async function buildCustomGenerators(verbose: boolean): Promise<void> {
const cacheFile = toAbsolutePath('generators/.cache');
const { cacheExists, hash } = await checkForCache(
{
job: 'custom generators',
folder: toAbsolutePath('generators/'),
generatedFiles: ['build'],
filesToCache: ['src', 'build.gradle', 'settings.gradle'],
cacheFile,
},
verbose
);

if (cacheExists) {
return;
}

const spinner = createSpinner('building custom generators', verbose).start();

await run('./gradle/gradlew --no-daemon -p generators assemble', {
verbose,
});

if (hash) {
spinner.text = 'storing custom generators cache';
await fsp.writeFile(cacheFile, hash);
}

spinner.succeed();
}

Expand Down
13 changes: 13 additions & 0 deletions scripts/types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
import type config from '../config/clients.config.json';

export type CheckForCacheOptions = {
job: string;
folder: string;
generatedFiles: string[];
filesToCache: string[];
cacheFile: string;
};

export type CheckForCache = {
cacheExists: boolean;
hash: string;
};

export type Generator = Record<string, any> & {
language: string;
client: string;
Expand Down

0 comments on commit 7a65dac

Please sign in to comment.