[pluginDiscovery] fail early if multiple plugins have conflicting ids (#17311) (#17445)

This commit is contained in:
Spencer 2018-03-28 13:37:36 -07:00 committed by GitHub
parent b36e7aff43
commit 773051732a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 63 additions and 0 deletions

View file

@ -5,6 +5,7 @@ import { findPluginSpecs } from '../find_plugin_specs';
import { PluginSpec } from '../plugin_spec';
const PLUGIN_FIXTURES = resolve(__dirname, 'fixtures/plugins');
const CONFLICT_FIXTURES = resolve(__dirname, 'fixtures/conflicts');
describe('plugin discovery', () => {
describe('findPluginSpecs()', function () {
@ -92,5 +93,26 @@ describe('plugin discovery', () => {
expect(specs.map(s => s.getId()).sort())
.to.eql(['bar:one', 'bar:two', 'foo']);
});
describe('conflicting plugin spec ids', () => {
it('fails with informative message', async () => {
const { spec$ } = findPluginSpecs({
plugins: {
scanDirs: [],
paths: [
resolve(CONFLICT_FIXTURES, 'foo'),
],
}
});
try {
await spec$.toArray().toPromise();
throw new Error('expected spec$ to throw an error');
} catch (error) {
expect(error.message).to.contain('Multple plugins found with the id "foo"');
expect(error.message).to.contain(CONFLICT_FIXTURES);
}
});
});
});
});

View file

@ -0,0 +1,8 @@
export default function (kibana) {
return [
// two plugins exported without ids will both inherit
// the id of the pack and conflict
new kibana.Plugin({}),
new kibana.Plugin({}),
];
}

View file

@ -0,0 +1,4 @@
{
"name": "foo",
"version": "kibana"
}

View file

@ -53,6 +53,19 @@ function getDistinctKeyForFindResult(result) {
return result;
}
function groupSpecsById(specs) {
const specsById = new Map();
for (const spec of specs) {
const id = spec.getId();
if (specsById.has(id)) {
specsById.get(id).push(spec);
} else {
specsById.set(id, [spec]);
}
}
return specsById;
}
/**
* Creates a collection of observables for discovering pluginSpecs
* using Kibana's defaults, settings, and config service
@ -76,6 +89,22 @@ export function findPluginSpecs(settings, config = defaultConfig(settings)) {
.mergeMap(({ pack }) => (
pack ? pack.getPluginSpecs() : []
))
// make sure that none of the plugin specs have conflicting ids, fail
// early if conflicts detected or merge the specs back into the stream
.toArray()
.mergeMap(allSpecs => {
for (const [id, specs] of groupSpecsById(allSpecs)) {
if (specs.length > 1) {
throw new Error(
`Multple plugins found with the id "${id}":\n${
specs.map(spec => ` - ${id} at ${spec.getPath()}`).join('\n')
}`
);
}
}
return allSpecs;
})
.mergeMap(async (spec) => {
// extend the config service with this plugin spec and
// collect its deprecations messages if some of its