From 39eb3aff166c9a45d61fa5d64a207c106b7773ff Mon Sep 17 00:00:00 2001 From: Josh Dover Date: Mon, 1 Apr 2019 13:20:26 -0500 Subject: [PATCH] Add --plugin-path support for new platform plugins in dev (#33865) * Add --plugin-path support for new platform plugins * PR comments * PR review comments --- .../config/legacy_object_to_config_adapter.ts | 5 +++-- .../discovery/plugin_discovery.test.ts | 22 ++++++++++++++++--- .../plugins/discovery/plugins_discovery.ts | 15 +++++++++++-- src/core/server/plugins/plugins_config.ts | 13 +++++++++++ .../server/plugins/plugins_service.test.ts | 1 + 5 files changed, 49 insertions(+), 7 deletions(-) diff --git a/src/core/server/legacy/config/legacy_object_to_config_adapter.ts b/src/core/server/legacy/config/legacy_object_to_config_adapter.ts index a853530dce45..ea5c3c972fe5 100644 --- a/src/core/server/legacy/config/legacy_object_to_config_adapter.ts +++ b/src/core/server/legacy/config/legacy_object_to_config_adapter.ts @@ -72,10 +72,11 @@ export class LegacyObjectToConfigAdapter extends ObjectToConfigAdapter { } private static transformPlugins(configValue: Record) { - // This property is the only one we use from the existing `plugins` config node - // since `scanDirs` and `paths` aren't respected by new platform plugin discovery. + // These properties are the only ones we use from the existing `plugins` config node + // since `scanDirs` isn't respected by new platform plugin discovery. return { initialize: configValue.initialize, + paths: configValue.paths, }; } diff --git a/src/core/server/plugins/discovery/plugin_discovery.test.ts b/src/core/server/plugins/discovery/plugin_discovery.test.ts index ac02a21cbe7a..2e3ba501feb1 100644 --- a/src/core/server/plugins/discovery/plugin_discovery.test.ts +++ b/src/core/server/plugins/discovery/plugin_discovery.test.ts @@ -34,6 +34,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(() => { @@ -112,9 +113,15 @@ test('properly iterates through plugin search locations', async () => { }, }; - const env = Env.createDefault(getEnvOptions()); + const env = Env.createDefault( + getEnvOptions({ + cliArgs: { envName: 'development' }, + }) + ); const configService = new ConfigService( - new BehaviorSubject(new ObjectToConfigAdapter({})), + new BehaviorSubject( + new ObjectToConfigAdapter({ plugins: { paths: [TEST_EXTRA_PLUGIN_PATH] } }) + ), env, logger ); @@ -126,12 +133,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); @@ -174,4 +182,12 @@ test('properly iterates through plugin search locations', async () => { 'kibana.json' )})`, ]); + + expect(loggingServiceMock.collect(logger).warn).toMatchInlineSnapshot(` +Array [ + Array [ + "Explicit plugin paths [${TEST_EXTRA_PLUGIN_PATH}] are only supported in development. Relative imports will not work in production.", + ], +] +`); }); diff --git a/src/core/server/plugins/discovery/plugins_discovery.ts b/src/core/server/plugins/discovery/plugins_discovery.ts index bbd115071215..8bf28eeb2d50 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,18 @@ 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( + if (config.additionalPluginPaths.length) { + log.warn( + `Explicit plugin paths [${ + config.additionalPluginPaths + }] are only supported in development. Relative imports will not work in production.` + ); + } + + const discoveryResults$ = merge( + from(config.additionalPluginPaths), + 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 cbdfad840aa6..9e440748dff4 100644 --- a/src/core/server/plugins/plugins_config.ts +++ b/src/core/server/plugins/plugins_config.ts @@ -22,6 +22,12 @@ import { Env } from '../config'; const pluginsSchema = schema.object({ initialize: schema.boolean({ defaultValue: true }), + + /** + * Defines an array of directories where another plugin should be loaded from. + * Should only be used in a development environment. + */ + paths: schema.arrayOf(schema.string(), { defaultValue: [] }), }); type PluginsConfigType = TypeOf; @@ -40,8 +46,15 @@ export class PluginsConfig { */ public readonly pluginSearchPaths: ReadonlyArray; + /** + * Defines directories where an additional plugin exists. + */ + public readonly additionalPluginPaths: ReadonlyArray; + constructor(config: PluginsConfigType, env: Env) { this.initialize = config.initialize; this.pluginSearchPaths = env.pluginSearchPaths; + // Only allow custom plugin paths in dev. + this.additionalPluginPaths = env.mode.dev ? config.paths : []; } } diff --git a/src/core/server/plugins/plugins_service.test.ts b/src/core/server/plugins/plugins_service.test.ts index 2a3ce3a4f88d..a7dc8bd5e003 100644 --- a/src/core/server/plugins/plugins_service.test.ts +++ b/src/core/server/plugins/plugins_service.test.ts @@ -302,6 +302,7 @@ test('`setup` properly invokes `discover` and ignores non-critical errors.', asy expect(mockDiscover).toHaveBeenCalledTimes(1); expect(mockDiscover).toHaveBeenCalledWith( { + additionalPluginPaths: [], initialize: true, pluginSearchPaths: [ resolve(process.cwd(), 'src', 'plugins'),