Add --plugin-path support for new platform plugins in dev (#33865)

* Add --plugin-path support for new platform plugins

* PR comments

* PR review comments
This commit is contained in:
Josh Dover 2019-04-01 13:20:26 -05:00 committed by GitHub
parent d62513657f
commit 39eb3aff16
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 49 additions and 7 deletions

View file

@ -72,10 +72,11 @@ export class LegacyObjectToConfigAdapter extends ObjectToConfigAdapter {
}
private static transformPlugins(configValue: Record<string, any>) {
// 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,
};
}

View file

@ -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<Config>(new ObjectToConfigAdapter({})),
new BehaviorSubject<Config>(
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.",
],
]
`);
});

View file

@ -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)

View file

@ -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<typeof pluginsSchema>;
@ -40,8 +46,15 @@ export class PluginsConfig {
*/
public readonly pluginSearchPaths: ReadonlyArray<string>;
/**
* Defines directories where an additional plugin exists.
*/
public readonly additionalPluginPaths: ReadonlyArray<string>;
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 : [];
}
}

View file

@ -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'),