Skip to content

Commit

Permalink
Merge pull request #7069 from lukasolson/plugin/preInit
Browse files Browse the repository at this point in the history
Plugins: Add preInit capability
  • Loading branch information
epixa committed Apr 27, 2016
2 parents d2b758e + 0e947a5 commit 4ff67e0
Show file tree
Hide file tree
Showing 4 changed files with 121 additions and 27 deletions.
77 changes: 77 additions & 0 deletions src/server/plugins/__tests__/plugin_init.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import {values} from 'lodash';
import expect from 'expect.js';
import sinon from 'auto-release-sinon';
import pluginInit from '../plugin_init';

describe('Plugin init', () => {
const getPluginCollection = (plugins) => ({
byId: plugins,
toArray: () => values(plugins)
});

it('should call preInit before init', async () => {
const plugins = {
foo: {
id: 'foo',
init: sinon.spy(),
preInit: sinon.spy(),
requiredIds: []
},
bar: {
id: 'bar',
init: sinon.spy(),
preInit: sinon.spy(),
requiredIds: []
},
baz: {
id: 'baz',
init: sinon.spy(),
preInit: sinon.spy(),
requiredIds: []
}
};

await pluginInit(getPluginCollection(plugins));

expect(plugins.foo.preInit.calledBefore(plugins.foo.init)).to.be.ok();
expect(plugins.foo.preInit.calledBefore(plugins.bar.init)).to.be.ok();
expect(plugins.foo.preInit.calledBefore(plugins.baz.init)).to.be.ok();

expect(plugins.bar.preInit.calledBefore(plugins.foo.init)).to.be.ok();
expect(plugins.bar.preInit.calledBefore(plugins.bar.init)).to.be.ok();
expect(plugins.bar.preInit.calledBefore(plugins.baz.init)).to.be.ok();

expect(plugins.baz.preInit.calledBefore(plugins.foo.init)).to.be.ok();
expect(plugins.baz.preInit.calledBefore(plugins.bar.init)).to.be.ok();
expect(plugins.baz.preInit.calledBefore(plugins.baz.init)).to.be.ok();
});

it('should call preInits in correct order based on requirements', async () => {
const plugins = {
foo: {
id: 'foo',
init: sinon.spy(),
preInit: sinon.spy(),
requiredIds: ['bar', 'baz']
},
bar: {
id: 'bar',
init: sinon.spy(),
preInit: sinon.spy(),
requiredIds: []
},
baz: {
id: 'baz',
init: sinon.spy(),
preInit: sinon.spy(),
requiredIds: ['bar']
}
};

await pluginInit(getPluginCollection(plugins));

expect(plugins.bar.preInit.firstCall.calledBefore(plugins.foo.init.firstCall)).to.be.ok();
expect(plugins.bar.preInit.firstCall.calledBefore(plugins.baz.init.firstCall)).to.be.ok();
expect(plugins.baz.preInit.firstCall.calledBefore(plugins.foo.init.firstCall)).to.be.ok();
});
});
30 changes: 3 additions & 27 deletions src/server/plugins/initialize.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { includes, keys } from 'lodash';
import pluginInit from './plugin_init';

module.exports = async function (kbnServer, server, config) {

if (!config.get('plugins.initialize')) {
Expand All @@ -17,30 +18,5 @@ module.exports = async function (kbnServer, server, config) {

});


let path = [];
const initialize = async function (id) {
let plugin = plugins.byId[id];

if (includes(path, id)) {
throw new Error(`circular dependencies found: "${path.concat(id).join(' -> ')}"`);
}

path.push(id);

for (let reqId of plugin.requiredIds) {
if (!plugins.byId[reqId]) {
throw new Error(`Unmet requirement "${reqId}" for plugin "${id}"`);
}

await initialize(reqId);
}

await plugin.init();
path.pop();
};

for (let {id} of plugins) {
await initialize(id);
}
await pluginInit(plugins);
};
6 changes: 6 additions & 0 deletions src/server/plugins/plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,11 @@ module.exports = class Plugin {
this.uiExportsSpecs = opts.uiExports || {};
this.requiredIds = opts.require || [];
this.version = opts.version || pkg.version;
this.externalPreInit = opts.preInit || _.noop;
this.externalInit = opts.init || _.noop;
this.configPrefix = opts.configPrefix || this.id;
this.getConfigSchema = opts.config || _.noop;
this.preInit = _.once(this.preInit);
this.init = _.once(this.init);
this[extendInitFns] = [];

Expand Down Expand Up @@ -100,6 +102,10 @@ module.exports = class Plugin {
}
}

async preInit() {
return await this.externalPreInit(this.kbnServer.server);
}

async init() {
let { id, version, kbnServer, configPrefix } = this;
let { config } = kbnServer;
Expand Down
35 changes: 35 additions & 0 deletions src/server/plugins/plugin_init.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { includes } from 'lodash';

export default async (plugins) => {
let path = [];

const initialize = async function (id, fn) {
let plugin = plugins.byId[id];

if (includes(path, id)) {
throw new Error(`circular dependencies found: "${path.concat(id).join(' -> ')}"`);
}

path.push(id);

for (let reqId of plugin.requiredIds) {
if (!plugins.byId[reqId]) {
throw new Error(`Unmet requirement "${reqId}" for plugin "${id}"`);
}

await initialize(reqId, fn);
}

await plugin[fn]();
path.pop();
};

const collection = plugins.toArray();
for (let {id} of collection) {
await initialize(id, 'preInit');
}

for (let {id} of collection) {
await initialize(id, 'init');
}
};

0 comments on commit 4ff67e0

Please sign in to comment.