mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
[kbn/optimizer] add support for --focus option (#80436)
Co-authored-by: spalger <spalger@users.noreply.github.com>
This commit is contained in:
parent
3d6d4a62b9
commit
bc4093a0cb
5 changed files with 158 additions and 6 deletions
|
@ -95,6 +95,11 @@ run(
|
|||
throw createFlagError('expected --filter to be one or more strings');
|
||||
}
|
||||
|
||||
const focus = typeof flags.focus === 'string' ? [flags.focus] : flags.focus;
|
||||
if (!Array.isArray(focus) || !focus.every((f) => typeof f === 'string')) {
|
||||
throw createFlagError('expected --focus to be one or more strings');
|
||||
}
|
||||
|
||||
const validateLimits = flags['validate-limits'] ?? false;
|
||||
if (typeof validateLimits !== 'boolean') {
|
||||
throw createFlagError('expected --validate-limits to have no value');
|
||||
|
@ -118,6 +123,7 @@ run(
|
|||
inspectWorkers,
|
||||
includeCoreBundle,
|
||||
filter,
|
||||
focus,
|
||||
});
|
||||
|
||||
if (validateLimits) {
|
||||
|
@ -165,6 +171,7 @@ run(
|
|||
cache: true,
|
||||
'inspect-workers': true,
|
||||
filter: [],
|
||||
focus: [],
|
||||
},
|
||||
help: `
|
||||
--watch run the optimizer in watch mode
|
||||
|
@ -173,6 +180,7 @@ run(
|
|||
--profile profile the webpack builds and write stats.json files to build outputs
|
||||
--no-core disable generating the core bundle
|
||||
--no-cache disable the cache
|
||||
--focus just like --filter, except dependencies are automatically included, --filter applies to result
|
||||
--filter comma-separated list of bundle id filters, results from multiple flags are merged, * and ! are supported
|
||||
--no-examples don't build the example plugins
|
||||
--dist create bundles that are suitable for inclusion in the Kibana distributable, enabled when running with --update-limits
|
||||
|
|
80
packages/kbn-optimizer/src/optimizer/focus_bundles.test.ts
Normal file
80
packages/kbn-optimizer/src/optimizer/focus_bundles.test.ts
Normal file
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import Path from 'path';
|
||||
|
||||
import { focusBundles } from './focus_bundles';
|
||||
import { Bundle } from '../common';
|
||||
|
||||
function createBundle(id: string, deps: ReturnType<Bundle['readBundleDeps']>) {
|
||||
const bundle = new Bundle({
|
||||
type: id === 'core' ? 'entry' : 'plugin',
|
||||
id,
|
||||
contextDir: Path.resolve('/kibana/plugins', id),
|
||||
outputDir: Path.resolve('/kibana/plugins', id, 'target/public'),
|
||||
publicDirNames: ['public'],
|
||||
sourceRoot: Path.resolve('/kibana'),
|
||||
});
|
||||
|
||||
jest.spyOn(bundle, 'readBundleDeps').mockReturnValue(deps);
|
||||
|
||||
return bundle;
|
||||
}
|
||||
|
||||
const BUNDLES = [
|
||||
createBundle('core', {
|
||||
implicit: [],
|
||||
explicit: [],
|
||||
}),
|
||||
createBundle('foo', {
|
||||
implicit: ['core'],
|
||||
explicit: [],
|
||||
}),
|
||||
createBundle('bar', {
|
||||
implicit: ['core'],
|
||||
explicit: ['foo'],
|
||||
}),
|
||||
createBundle('baz', {
|
||||
implicit: ['core'],
|
||||
explicit: ['bar'],
|
||||
}),
|
||||
createBundle('box', {
|
||||
implicit: ['core'],
|
||||
explicit: ['foo'],
|
||||
}),
|
||||
];
|
||||
|
||||
function test(filters: string[]) {
|
||||
return focusBundles(filters, BUNDLES)
|
||||
.map((b) => b.id)
|
||||
.sort((a, b) => a.localeCompare(b))
|
||||
.join(', ');
|
||||
}
|
||||
|
||||
it('returns all bundles when no focus filters are defined', () => {
|
||||
expect(test([])).toMatchInlineSnapshot(`"bar, baz, box, core, foo"`);
|
||||
});
|
||||
|
||||
it('includes a single instance of all implicit and explicit dependencies', () => {
|
||||
expect(test(['core'])).toMatchInlineSnapshot(`"core"`);
|
||||
expect(test(['foo'])).toMatchInlineSnapshot(`"core, foo"`);
|
||||
expect(test(['bar'])).toMatchInlineSnapshot(`"bar, core, foo"`);
|
||||
expect(test(['baz'])).toMatchInlineSnapshot(`"bar, baz, core, foo"`);
|
||||
expect(test(['box'])).toMatchInlineSnapshot(`"box, core, foo"`);
|
||||
});
|
44
packages/kbn-optimizer/src/optimizer/focus_bundles.ts
Normal file
44
packages/kbn-optimizer/src/optimizer/focus_bundles.ts
Normal file
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import { Bundle } from '../common';
|
||||
import { filterById } from './filter_by_id';
|
||||
|
||||
export function focusBundles(filters: string[], bundles: Bundle[]) {
|
||||
if (!filters.length) {
|
||||
return [...bundles];
|
||||
}
|
||||
|
||||
const queue = new Set<Bundle>(filterById(filters, bundles));
|
||||
const focused: Bundle[] = [];
|
||||
|
||||
for (const bundle of queue) {
|
||||
focused.push(bundle);
|
||||
|
||||
const { explicit, implicit } = bundle.readBundleDeps();
|
||||
const depIds = [...explicit, ...implicit];
|
||||
if (depIds.length) {
|
||||
for (const dep of filterById(depIds, bundles)) {
|
||||
queue.add(dep);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return focused;
|
||||
}
|
|
@ -22,6 +22,7 @@ jest.mock('./kibana_platform_plugins.ts');
|
|||
jest.mock('./get_plugin_bundles.ts');
|
||||
jest.mock('../common/theme_tags.ts');
|
||||
jest.mock('./filter_by_id.ts');
|
||||
jest.mock('./focus_bundles');
|
||||
jest.mock('../limits.ts');
|
||||
|
||||
jest.mock('os', () => {
|
||||
|
@ -121,6 +122,7 @@ describe('OptimizerConfig::parseOptions()', () => {
|
|||
"cache": true,
|
||||
"dist": false,
|
||||
"filters": Array [],
|
||||
"focus": Array [],
|
||||
"includeCoreBundle": false,
|
||||
"inspectWorkers": false,
|
||||
"maxWorkerCount": 2,
|
||||
|
@ -149,6 +151,7 @@ describe('OptimizerConfig::parseOptions()', () => {
|
|||
"cache": false,
|
||||
"dist": false,
|
||||
"filters": Array [],
|
||||
"focus": Array [],
|
||||
"includeCoreBundle": false,
|
||||
"inspectWorkers": false,
|
||||
"maxWorkerCount": 2,
|
||||
|
@ -177,6 +180,7 @@ describe('OptimizerConfig::parseOptions()', () => {
|
|||
"cache": true,
|
||||
"dist": false,
|
||||
"filters": Array [],
|
||||
"focus": Array [],
|
||||
"includeCoreBundle": false,
|
||||
"inspectWorkers": false,
|
||||
"maxWorkerCount": 2,
|
||||
|
@ -207,6 +211,7 @@ describe('OptimizerConfig::parseOptions()', () => {
|
|||
"cache": true,
|
||||
"dist": false,
|
||||
"filters": Array [],
|
||||
"focus": Array [],
|
||||
"includeCoreBundle": false,
|
||||
"inspectWorkers": false,
|
||||
"maxWorkerCount": 2,
|
||||
|
@ -234,6 +239,7 @@ describe('OptimizerConfig::parseOptions()', () => {
|
|||
"cache": true,
|
||||
"dist": false,
|
||||
"filters": Array [],
|
||||
"focus": Array [],
|
||||
"includeCoreBundle": false,
|
||||
"inspectWorkers": false,
|
||||
"maxWorkerCount": 2,
|
||||
|
@ -261,6 +267,7 @@ describe('OptimizerConfig::parseOptions()', () => {
|
|||
"cache": true,
|
||||
"dist": false,
|
||||
"filters": Array [],
|
||||
"focus": Array [],
|
||||
"includeCoreBundle": false,
|
||||
"inspectWorkers": false,
|
||||
"maxWorkerCount": 100,
|
||||
|
@ -285,6 +292,7 @@ describe('OptimizerConfig::parseOptions()', () => {
|
|||
"cache": false,
|
||||
"dist": false,
|
||||
"filters": Array [],
|
||||
"focus": Array [],
|
||||
"includeCoreBundle": false,
|
||||
"inspectWorkers": false,
|
||||
"maxWorkerCount": 100,
|
||||
|
@ -309,6 +317,7 @@ describe('OptimizerConfig::parseOptions()', () => {
|
|||
"cache": false,
|
||||
"dist": false,
|
||||
"filters": Array [],
|
||||
"focus": Array [],
|
||||
"includeCoreBundle": false,
|
||||
"inspectWorkers": false,
|
||||
"maxWorkerCount": 100,
|
||||
|
@ -334,6 +343,7 @@ describe('OptimizerConfig::parseOptions()', () => {
|
|||
"cache": false,
|
||||
"dist": false,
|
||||
"filters": Array [],
|
||||
"focus": Array [],
|
||||
"includeCoreBundle": false,
|
||||
"inspectWorkers": false,
|
||||
"maxWorkerCount": 100,
|
||||
|
@ -359,6 +369,7 @@ describe('OptimizerConfig::parseOptions()', () => {
|
|||
"cache": true,
|
||||
"dist": false,
|
||||
"filters": Array [],
|
||||
"focus": Array [],
|
||||
"includeCoreBundle": false,
|
||||
"inspectWorkers": false,
|
||||
"maxWorkerCount": 100,
|
||||
|
@ -386,6 +397,7 @@ describe('OptimizerConfig::create()', () => {
|
|||
.findKibanaPlatformPlugins;
|
||||
const getPluginBundles: jest.Mock = jest.requireMock('./get_plugin_bundles.ts').getPluginBundles;
|
||||
const filterById: jest.Mock = jest.requireMock('./filter_by_id.ts').filterById;
|
||||
const focusBundles: jest.Mock = jest.requireMock('./focus_bundles').focusBundles;
|
||||
const readLimits: jest.Mock = jest.requireMock('../limits.ts').readLimits;
|
||||
|
||||
beforeEach(() => {
|
||||
|
@ -400,6 +412,7 @@ describe('OptimizerConfig::create()', () => {
|
|||
findKibanaPlatformPlugins.mockReturnValue(Symbol('new platform plugins'));
|
||||
getPluginBundles.mockReturnValue([Symbol('bundle1'), Symbol('bundle2')]);
|
||||
filterById.mockReturnValue(Symbol('filtered bundles'));
|
||||
focusBundles.mockReturnValue(Symbol('focused bundles'));
|
||||
readLimits.mockReturnValue(Symbol('limits'));
|
||||
|
||||
jest.spyOn(OptimizerConfig, 'parseOptions').mockImplementation((): {
|
||||
|
@ -417,6 +430,7 @@ describe('OptimizerConfig::create()', () => {
|
|||
inspectWorkers: Symbol('parsed inspect workers'),
|
||||
profileWebpack: Symbol('parsed profile webpack'),
|
||||
filters: [],
|
||||
focus: [],
|
||||
includeCoreBundle: false,
|
||||
}));
|
||||
});
|
||||
|
@ -470,17 +484,14 @@ describe('OptimizerConfig::create()', () => {
|
|||
"calls": Array [
|
||||
Array [
|
||||
Array [],
|
||||
Array [
|
||||
Symbol(bundle1),
|
||||
Symbol(bundle2),
|
||||
],
|
||||
Symbol(focused bundles),
|
||||
],
|
||||
],
|
||||
"instances": Array [
|
||||
[Window],
|
||||
],
|
||||
"invocationCallOrder": Array [
|
||||
23,
|
||||
24,
|
||||
],
|
||||
"results": Array [
|
||||
Object {
|
||||
|
|
|
@ -32,6 +32,7 @@ import {
|
|||
import { findKibanaPlatformPlugins, KibanaPlatformPlugin } from './kibana_platform_plugins';
|
||||
import { getPluginBundles } from './get_plugin_bundles';
|
||||
import { filterById } from './filter_by_id';
|
||||
import { focusBundles } from './focus_bundles';
|
||||
import { readLimits } from '../limits';
|
||||
|
||||
export interface Limits {
|
||||
|
@ -104,6 +105,11 @@ interface Options {
|
|||
* --filter f*r # [foobar], excludes [foo, bar]
|
||||
*/
|
||||
filter?: string[];
|
||||
/**
|
||||
* behaves just like filter, but includes required bundles and plugins of the
|
||||
* listed bundle ids. Filters only apply to bundles selected by focus
|
||||
*/
|
||||
focus?: string[];
|
||||
|
||||
/** flag that causes the core bundle to be built along with plugins */
|
||||
includeCoreBundle?: boolean;
|
||||
|
@ -132,6 +138,7 @@ export interface ParsedOptions {
|
|||
pluginPaths: string[];
|
||||
pluginScanDirs: string[];
|
||||
filters: string[];
|
||||
focus: string[];
|
||||
inspectWorkers: boolean;
|
||||
includeCoreBundle: boolean;
|
||||
themeTags: ThemeTags;
|
||||
|
@ -148,6 +155,7 @@ export class OptimizerConfig {
|
|||
const cache = options.cache !== false && !process.env.KBN_OPTIMIZER_NO_CACHE;
|
||||
const includeCoreBundle = !!options.includeCoreBundle;
|
||||
const filters = options.filter || [];
|
||||
const focus = options.focus || [];
|
||||
|
||||
const repoRoot = options.repoRoot;
|
||||
if (!Path.isAbsolute(repoRoot)) {
|
||||
|
@ -210,6 +218,7 @@ export class OptimizerConfig {
|
|||
pluginScanDirs,
|
||||
pluginPaths,
|
||||
filters,
|
||||
focus,
|
||||
inspectWorkers,
|
||||
includeCoreBundle,
|
||||
themeTags,
|
||||
|
@ -236,7 +245,7 @@ export class OptimizerConfig {
|
|||
];
|
||||
|
||||
return new OptimizerConfig(
|
||||
filterById(options.filters, bundles),
|
||||
filterById(options.filters, focusBundles(options.focus, bundles)),
|
||||
options.cache,
|
||||
options.watch,
|
||||
options.inspectWorkers,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue