From 98dea870e6d148caa1fb5b1ffc3f3466b4aec791 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Tue, 7 Apr 2020 00:00:14 +0200 Subject: [PATCH 1/4] packages/cli: refactor build-cache to have a reusable withCache function --- .../cli/src/commands/build-cache/index.ts | 36 ++++++++++++------- .../cli/src/commands/build-cache/options.ts | 30 ++++++++++++---- 2 files changed, 46 insertions(+), 20 deletions(-) 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, + }; +} From 08a5023ad445e66b22bc6f83577e9ebe60cbac3e Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Tue, 7 Apr 2020 00:01:56 +0200 Subject: [PATCH 2/4] packages/cli: make plugin:build have built-in caching --- packages/cli/src/commands/plugin/build.ts | 13 ++++++++----- .../cli/templates/default-plugin/package.json.hbs | 2 +- packages/core/package.json | 2 +- plugins/home-page/package.json | 2 +- plugins/welcome/package.json | 2 +- 5 files changed, 12 insertions(+), 9 deletions(-) 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..83d998f8e4 100644 --- a/packages/cli/templates/default-plugin/package.json.hbs +++ b/packages/cli/templates/default-plugin/package.json.hbs @@ -7,7 +7,7 @@ "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..0bc9165238 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -20,7 +20,7 @@ "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..4432fe1588 100644 --- a/plugins/home-page/package.json +++ b/plugins/home-page/package.json @@ -7,7 +7,7 @@ "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..f7e317ce54 100644 --- a/plugins/welcome/package.json +++ b/plugins/welcome/package.json @@ -7,7 +7,7 @@ "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" }, From f5ddb991053fdeebb30a45712f01dd0e581ef330 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Tue, 7 Apr 2020 10:06:00 +0200 Subject: [PATCH 3/4] packages/cli: remove output dir before building with cache --- packages/cli/src/commands/build-cache/index.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/cli/src/commands/build-cache/index.ts b/packages/cli/src/commands/build-cache/index.ts index fafc945907..a8a1a27e9d 100644 --- a/packages/cli/src/commands/build-cache/index.ts +++ b/packages/cli/src/commands/build-cache/index.ts @@ -14,6 +14,7 @@ * limitations under the License. */ +import fs from 'fs-extra'; import { Command } from 'commander'; import { run } from 'helpers/run'; import { Cache } from './cache'; @@ -31,6 +32,7 @@ export async function withCache( const key = await Cache.readInputKey(options.inputs); if (!key) { print('input directory is dirty, skipping cache'); + await fs.remove(options.output); await buildFunc(); return; } @@ -49,6 +51,7 @@ export async function withCache( } print('cache miss, need to build'); + await fs.remove(options.output); await buildFunc(); await cacheResult.archive(options.output, options.maxCacheEntries); From 1fdba128c60d3bc9acb8228c169d6fbc6da35de3 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Tue, 7 Apr 2020 10:47:46 +0200 Subject: [PATCH 4/4] packages,plugins: separate build:watch is no longer needed --- packages/cli/templates/default-plugin/package.json.hbs | 1 - packages/core/package.json | 1 - plugins/home-page/package.json | 1 - plugins/welcome/package.json | 1 - 4 files changed, 4 deletions(-) diff --git a/packages/cli/templates/default-plugin/package.json.hbs b/packages/cli/templates/default-plugin/package.json.hbs index 83d998f8e4..3fb02a992e 100644 --- a/packages/cli/templates/default-plugin/package.json.hbs +++ b/packages/cli/templates/default-plugin/package.json.hbs @@ -6,7 +6,6 @@ "license": "Apache-2.0", "private": true, "scripts": { - "build:watch": "backstage-cli plugin:build --watch", "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 0bc9165238..fcba46b1f1 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -19,7 +19,6 @@ "main": "dist/index.cjs.js", "types": "dist/index.d.ts", "scripts": { - "build:watch": "backstage-cli plugin:build --watch", "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 4432fe1588..548ed25a8d 100644 --- a/plugins/home-page/package.json +++ b/plugins/home-page/package.json @@ -6,7 +6,6 @@ "license": "Apache-2.0", "private": true, "scripts": { - "build:watch": "backstage-cli plugin:build --watch", "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 f7e317ce54..f9f39f5c4e 100644 --- a/plugins/welcome/package.json +++ b/plugins/welcome/package.json @@ -6,7 +6,6 @@ "private": true, "license": "Apache-2.0", "scripts": { - "build:watch": "backstage-cli plugin:build --watch", "build": "backstage-cli plugin:build", "lint": "backstage-cli lint", "test": "backstage-cli test"