From 42fc671805792cac76e5461f1cee90cbd477de1a Mon Sep 17 00:00:00 2001 From: Josh Dover Date: Wed, 27 Mar 2019 10:32:12 -0500 Subject: [PATCH] Add --plugin-path support for new platform plugins --- src/cli/serve/serve.js | 1 + src/core/server/config/__mocks__/env.ts | 10 +++++++++- src/core/server/config/__snapshots__/env.test.ts.snap | 6 ++++++ src/core/server/config/env.ts | 1 + .../legacy/__snapshots__/legacy_service.test.ts.snap | 2 ++ .../server/plugins/discovery/plugin_discovery.test.ts | 10 ++++++++-- src/core/server/plugins/discovery/plugins_discovery.ts | 7 +++++-- src/core/server/plugins/plugins_config.ts | 8 ++++++++ src/core/server/plugins/plugins_service.test.ts | 1 + 9 files changed, 41 insertions(+), 5 deletions(-) diff --git a/src/cli/serve/serve.js b/src/cli/serve/serve.js index f2380586380324..37d5ce9351719c 100644 --- a/src/cli/serve/serve.js +++ b/src/cli/serve/serve.js @@ -223,6 +223,7 @@ export default function (program) { repl: !!opts.repl, basePath: !!opts.basePath, optimize: !!opts.optimize, + pluginPath: opts.pluginPath, }, features: { isClusterModeSupported: CAN_CLUSTER, diff --git a/src/core/server/config/__mocks__/env.ts b/src/core/server/config/__mocks__/env.ts index 2f9c0575858c38..2ef31b6a464918 100644 --- a/src/core/server/config/__mocks__/env.ts +++ b/src/core/server/config/__mocks__/env.ts @@ -21,9 +21,16 @@ import { EnvOptions } from '../env'; +type Optional = T | undefined; + +// Prettier changes this syntax to be invalid. +// tslint:disable prettier type DeepPartial = { - [P in keyof T]?: T[P] extends Array ? Array> : DeepPartial + [P in keyof T]?: + T[P] extends Optional> ? Optional : + T[P] extends Array ? Array> : DeepPartial }; +// tslint:enable prettier export function getEnvOptions(options: DeepPartial = {}): EnvOptions { return { @@ -37,6 +44,7 @@ export function getEnvOptions(options: DeepPartial = {}): EnvOptions repl: false, basePath: false, optimize: false, + pluginPath: undefined, ...(options.cliArgs || {}), }, isDevClusterMaster: diff --git a/src/core/server/config/__snapshots__/env.test.ts.snap b/src/core/server/config/__snapshots__/env.test.ts.snap index 8b35a3ebfabbce..0de3a11c242d8e 100644 --- a/src/core/server/config/__snapshots__/env.test.ts.snap +++ b/src/core/server/config/__snapshots__/env.test.ts.snap @@ -9,6 +9,7 @@ Env { "envName": "development", "open": false, "optimize": false, + "pluginPath": undefined, "quiet": false, "repl": false, "silent": false, @@ -50,6 +51,7 @@ Env { "envName": "production", "open": false, "optimize": false, + "pluginPath": undefined, "quiet": false, "repl": false, "silent": false, @@ -90,6 +92,7 @@ Env { "dev": true, "open": false, "optimize": false, + "pluginPath": undefined, "quiet": false, "repl": false, "silent": false, @@ -130,6 +133,7 @@ Env { "dev": false, "open": false, "optimize": false, + "pluginPath": undefined, "quiet": false, "repl": false, "silent": false, @@ -170,6 +174,7 @@ Env { "dev": false, "open": false, "optimize": false, + "pluginPath": undefined, "quiet": false, "repl": false, "silent": false, @@ -210,6 +215,7 @@ Env { "dev": false, "open": false, "optimize": false, + "pluginPath": undefined, "quiet": false, "repl": false, "silent": false, diff --git a/src/core/server/config/env.ts b/src/core/server/config/env.ts index 4ee7a778e9c8f6..0a81fe29df60e4 100644 --- a/src/core/server/config/env.ts +++ b/src/core/server/config/env.ts @@ -55,6 +55,7 @@ export interface CliArgs { basePath: boolean; optimize: boolean; open: boolean; + pluginPath?: string[]; } export class Env { diff --git a/src/core/server/legacy/__snapshots__/legacy_service.test.ts.snap b/src/core/server/legacy/__snapshots__/legacy_service.test.ts.snap index 050184b1f1d52b..2c262eaae43b76 100644 --- a/src/core/server/legacy/__snapshots__/legacy_service.test.ts.snap +++ b/src/core/server/legacy/__snapshots__/legacy_service.test.ts.snap @@ -8,6 +8,7 @@ Array [ "dev": true, "open": false, "optimize": false, + "pluginPath": undefined, "quiet": true, "repl": false, "silent": false, @@ -65,6 +66,7 @@ Array [ "dev": true, "open": false, "optimize": false, + "pluginPath": undefined, "quiet": false, "repl": false, "silent": true, diff --git a/src/core/server/plugins/discovery/plugin_discovery.test.ts b/src/core/server/plugins/discovery/plugin_discovery.test.ts index 266ad1780d47f7..7b346484303e74 100644 --- a/src/core/server/plugins/discovery/plugin_discovery.test.ts +++ b/src/core/server/plugins/discovery/plugin_discovery.test.ts @@ -44,6 +44,7 @@ const TEST_PLUGIN_SEARCH_PATHS = { emptyPlugins: resolve(process.cwd(), 'plugins'), nonExistentKibanaExtra: resolve(process.cwd(), '..', 'kibana-extra'), }; +const TEST_EXTRA_PLUGIN_PATH = resolve(process.cwd(), 'my-extra-plugin'); const logger = loggingServiceMock.create(); beforeEach(() => { @@ -122,7 +123,11 @@ test('properly iterates through plugin search locations', async () => { }, }; - const env = Env.createDefault(getEnvOptions()); + const env = Env.createDefault( + getEnvOptions({ + cliArgs: { envName: 'development', pluginPath: [TEST_EXTRA_PLUGIN_PATH] }, + }) + ); const configService = new ConfigService( new BehaviorSubject(new ObjectToConfigAdapter({})), env, @@ -136,12 +141,13 @@ test('properly iterates through plugin search locations', async () => { const { plugin$, error$ } = discover(pluginsConfig, { configService, env, logger }); const plugins = await plugin$.pipe(toArray()).toPromise(); - expect(plugins).toHaveLength(3); + expect(plugins).toHaveLength(4); for (const path of [ resolve(TEST_PLUGIN_SEARCH_PATHS.nonEmptySrcPlugins, '1'), resolve(TEST_PLUGIN_SEARCH_PATHS.nonEmptySrcPlugins, '3'), resolve(TEST_PLUGIN_SEARCH_PATHS.nonEmptySrcPlugins, '6'), + TEST_EXTRA_PLUGIN_PATH, ]) { const discoveredPlugin = plugins.find(plugin => plugin.path === path)!; expect(discoveredPlugin).toBeInstanceOf(Plugin); diff --git a/src/core/server/plugins/discovery/plugins_discovery.ts b/src/core/server/plugins/discovery/plugins_discovery.ts index bbd11507121573..0a4f8c27d2b139 100644 --- a/src/core/server/plugins/discovery/plugins_discovery.ts +++ b/src/core/server/plugins/discovery/plugins_discovery.ts @@ -19,7 +19,7 @@ import { readdir, stat } from 'fs'; import { resolve } from 'path'; -import { bindNodeCallback, from } from 'rxjs'; +import { bindNodeCallback, from, merge } from 'rxjs'; import { catchError, filter, map, mergeMap, shareReplay } from 'rxjs/operators'; import { CoreContext } from '../../core_context'; import { Logger } from '../../logging'; @@ -46,7 +46,10 @@ export function discover(config: PluginsConfig, coreContext: CoreContext) { const log = coreContext.logger.get('plugins-discovery'); log.debug('Discovering plugins...'); - const discoveryResults$ = processPluginSearchPaths$(config.pluginSearchPaths, log).pipe( + const discoveryResults$ = merge( + from(config.knownPluginPaths), + processPluginSearchPaths$(config.pluginSearchPaths, log) + ).pipe( mergeMap(pluginPathOrError => { return typeof pluginPathOrError === 'string' ? createPlugin$(pluginPathOrError, log, coreContext) diff --git a/src/core/server/plugins/plugins_config.ts b/src/core/server/plugins/plugins_config.ts index cbdfad840aa605..8b47a0be4a1bf4 100644 --- a/src/core/server/plugins/plugins_config.ts +++ b/src/core/server/plugins/plugins_config.ts @@ -40,8 +40,16 @@ export class PluginsConfig { */ public readonly pluginSearchPaths: ReadonlyArray; + /** + * Defines directories where a known plugin exists. + */ + public readonly knownPluginPaths: ReadonlyArray; + constructor(config: PluginsConfigType, env: Env) { this.initialize = config.initialize; this.pluginSearchPaths = env.pluginSearchPaths; + // Only allow custom pluginPaths in dev. + this.knownPluginPaths = + env.cliArgs.envName === 'development' ? env.cliArgs.pluginPath || [] : []; } } diff --git a/src/core/server/plugins/plugins_service.test.ts b/src/core/server/plugins/plugins_service.test.ts index 553cb8a0313899..d34a5ceab3f3d4 100644 --- a/src/core/server/plugins/plugins_service.test.ts +++ b/src/core/server/plugins/plugins_service.test.ts @@ -309,6 +309,7 @@ test('`setup` properly invokes `discover` and ignores non-critical errors.', asy expect(mockDiscover).toHaveBeenCalledWith( { initialize: true, + knownPluginPaths: [], pluginSearchPaths: [ resolve(process.cwd(), 'src', 'plugins'), resolve(process.cwd(), 'plugins'),