diff --git a/packages/cli/src/commands/build-cache/index.ts b/packages/cli/src/commands/build-cache/index.ts index 70033097e5..a8a1a27e9d 100644 --- a/packages/cli/src/commands/build-cache/index.ts +++ b/packages/cli/src/commands/build-cache/index.ts @@ -14,27 +14,26 @@ * limitations under the License. */ +import fs from 'fs-extra'; 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 fs.remove(options.output); + await buildFunc(); return; } @@ -52,9 +51,23 @@ export default async (cmd: Command, args: string[]) => { } print('cache miss, need to build'); + await fs.remove(options.output); + 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, + }; +} diff --git a/packages/cli/src/commands/plugin/build.ts b/packages/cli/src/commands/plugin/build.ts index cb28d4cf5f..aa9c68c494 100644 --- a/packages/cli/src/commands/plugin/build.ts +++ b/packages/cli/src/commands/plugin/build.ts @@ -17,6 +17,7 @@ import { rollup, watch, OutputOptions } from 'rollup'; import conf from './rollup.config'; import { Command } from 'commander'; +import { withCache, getDefaultCacheOptions } from 'commands/build-cache'; export default async (cmd: Command) => { if (cmd.watch) { @@ -40,10 +41,12 @@ export default async (cmd: Command) => { }); } - const bundle = await rollup({ - input: conf.input, - plugins: conf.plugins, + await withCache(getDefaultCacheOptions(), async () => { + const bundle = await rollup({ + input: conf.input, + plugins: conf.plugins, + }); + await bundle.generate(conf.output as OutputOptions); + await bundle.write(conf.output as OutputOptions); }); - await bundle.generate(conf.output as OutputOptions); - await bundle.write(conf.output as OutputOptions); }; diff --git a/packages/cli/templates/default-plugin/package.json.hbs b/packages/cli/templates/default-plugin/package.json.hbs index dc1500944a..3fb02a992e 100644 --- a/packages/cli/templates/default-plugin/package.json.hbs +++ b/packages/cli/templates/default-plugin/package.json.hbs @@ -6,8 +6,7 @@ "license": "Apache-2.0", "private": true, "scripts": { - "build:watch": "backstage-cli plugin:build --watch", - "build": "backstage-cli build-cache -- backstage-cli plugin:build", + "build": "backstage-cli plugin:build", "lint": "backstage-cli lint", "test": "backstage-cli test" }, diff --git a/packages/core/package.json b/packages/core/package.json index 93c2e2fdf7..fcba46b1f1 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -19,8 +19,7 @@ "main": "dist/index.cjs.js", "types": "dist/index.d.ts", "scripts": { - "build:watch": "backstage-cli plugin:build --watch", - "build": "backstage-cli build-cache -- backstage-cli plugin:build", + "build": "backstage-cli plugin:build", "lint": "backstage-cli lint", "test": "backstage-cli test" }, diff --git a/plugins/home-page/package.json b/plugins/home-page/package.json index 88afe98bd4..548ed25a8d 100644 --- a/plugins/home-page/package.json +++ b/plugins/home-page/package.json @@ -6,8 +6,7 @@ "license": "Apache-2.0", "private": true, "scripts": { - "build:watch": "backstage-cli plugin:build --watch", - "build": "backstage-cli build-cache -- backstage-cli plugin:build", + "build": "backstage-cli plugin:build", "lint": "backstage-cli lint", "test": "backstage-cli test" }, diff --git a/plugins/welcome/package.json b/plugins/welcome/package.json index 8eb9f45f7f..f9f39f5c4e 100644 --- a/plugins/welcome/package.json +++ b/plugins/welcome/package.json @@ -6,8 +6,7 @@ "private": true, "license": "Apache-2.0", "scripts": { - "build:watch": "backstage-cli plugin:build --watch", - "build": "backstage-cli build-cache -- backstage-cli plugin:build", + "build": "backstage-cli plugin:build", "lint": "backstage-cli lint", "test": "backstage-cli test" },