diff --git a/packages/cli/src/commands/build-cache/index.ts b/packages/cli/src/commands/build-cache/index.ts index 70033097e5..fafc945907 100644 --- a/packages/cli/src/commands/build-cache/index.ts +++ b/packages/cli/src/commands/build-cache/index.ts @@ -17,24 +17,21 @@ import { Command } from 'commander'; import { run } from 'helpers/run'; import { Cache } from './cache'; -import { parseOptions } from './options'; +import { parseOptions, Options } from './options'; function print(msg: string) { process.stdout.write(`[build-cache] ${msg}\n`); } -/* - * The build-cache command is used to make builds a no-op if there are no changes to the package. - * It supports both local development where the output directory remains intact, as well as CI - * where the output directory is stored in a separate cache dir. - */ -export default async (cmd: Command, args: string[]) => { - const options = await parseOptions(cmd); - +// Wrap a build function with a cache, which won't call the build function on cache hit +export async function withCache( + options: Options, + buildFunc: () => Promise, +): Promise { const key = await Cache.readInputKey(options.inputs); if (!key) { print('input directory is dirty, skipping cache'); - await run(args[0], args.slice(1)); + await buildFunc(); return; } @@ -52,9 +49,22 @@ export default async (cmd: Command, args: string[]) => { } print('cache miss, need to build'); + await buildFunc(); - await run(args[0], args.slice(1)); - - print('caching build output'); await cacheResult.archive(options.output, options.maxCacheEntries); +} + +/* + * The build-cache command is used to make builds a no-op if there are no changes to the package. + * It supports both local development where the output directory remains intact, as well as CI + * where the output directory is stored in a separate cache dir. + */ +export default async (cmd: Command, args: string[]) => { + const options = await parseOptions(cmd); + + await withCache(options, async () => { + await run(args[0], args.slice(1)); + }); }; + +export * from './options'; diff --git a/packages/cli/src/commands/build-cache/options.ts b/packages/cli/src/commands/build-cache/options.ts index 523d5fc7e6..6903c01ddf 100644 --- a/packages/cli/src/commands/build-cache/options.ts +++ b/packages/cli/src/commands/build-cache/options.ts @@ -18,6 +18,7 @@ import { resolve as resolvePath } from 'path'; import { Command } from 'commander'; import { paths } from 'helpers/paths'; +const DEFAULT_CACHE_DIR = '/node_modules/.cache/backstage-builds'; const DEFAULT_MAX_ENTRIES = 10; export type Options = { @@ -27,19 +28,34 @@ export type Options = { maxCacheEntries: number; }; -export async function parseOptions(cmd: Command): Promise { - const argTransformer = (arg: string) => - resolvePath(arg.replace(//g, paths.targetRoot).replace(/'/g, '')); +function transformPath(path: string): string { + return resolvePath( + path.replace(//g, paths.targetRoot).replace(/'/g, ''), + ); +} - const inputs = cmd.input.map(argTransformer) as string[]; +export async function parseOptions(cmd: Command): Promise { + const inputs = cmd.input.map(transformPath) as string[]; if (inputs.length === 0) { - inputs.push(argTransformer('.')); + inputs.push(transformPath('.')); } - const output = argTransformer(cmd.output); - const cacheDir = argTransformer( + const output = transformPath(cmd.output); + const cacheDir = transformPath( process.env.BACKSTAGE_CACHE_DIR || cmd.cacheDir, ); const maxCacheEntries = Number(process.env.BACKSTAGE_CACHE_MAX_ENTRIES) || DEFAULT_MAX_ENTRIES; return { inputs, output, cacheDir, maxCacheEntries }; } + +export function getDefaultCacheOptions(): Options { + return { + inputs: [transformPath('.')], + output: transformPath('dist'), + cacheDir: transformPath( + process.env.BACKSTAGE_CACHE_DIR || DEFAULT_CACHE_DIR, + ), + maxCacheEntries: + Number(process.env.BACKSTAGE_CACHE_MAX_ENTRIES) || DEFAULT_MAX_ENTRIES, + }; +}