Merge pull request #6 from JsSucks/plugin-manager

Plugin manager
This commit is contained in:
Alexei Stukov 2018-01-16 08:33:57 +02:00 committed by GitHub
commit 602258b6d8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 27961 additions and 26 deletions

File diff suppressed because it is too large Load Diff

View File

@ -9,18 +9,28 @@
*/ */
const { Module } = require('./modulebase'); const { Module } = require('./modulebase');
const { BDIpc } = require('./bdipc'); const { FileUtils } = require('./utils');
const { Utils, FileUtils } = require('./utils'); const { Global } = require('./global');
const fs = window.require('fs');
const path = window.require('path'); const path = window.require('path');
class Plugin { class Plugin {
constructor(args) { constructor(pluginInternals) {
this.__pluginInternals = pluginInternals;
} }
get configs() { return this.__pluginInternals.configs }
get info() { return this.__pluginInternals.info }
get paths() { return this.__pluginInternals.paths }
get main() { return this.__pluginInternals.main }
get defaultConfig() { return this.configs.defaultConfig }
get userConfig() { return this.configs.userConfig }
get name() { return this.info.name }
get authors() { return this.info.authors }
get version() { return this.info.version }
get pluginPath() { return this.paths.pluginPath }
get enabled() { return this.userConfig.enabled }
start() { start() {
if (this.onStart) return this.onStart(); if (this.onStart) return this.onStart();
return true; //Assume plugin started since it doesn't have onStart return true; //Assume plugin started since it doesn't have onStart
@ -40,24 +50,21 @@ class PluginManager extends Module {
this.setState({ this.setState({
plugins: [] plugins: []
}); });
tests();
} }
get plugins() { get plugins() {
return this.state.plugins; return this.state.plugins;
} }
async pluginsPath() { pluginsPath() {
//TODO Get this from config module return Global.getObject('paths').find(path => path.id === 'plugins').path;
const config = await BDIpc.send('getConfig');
return config.paths.find(path => 'plugins' in path).plugins;
} }
async loadPlugin(pluginPath) { async loadPlugin(pluginPath) {
const { plugins } = this.state; const { plugins } = this.state;
try { try {
const pluginsPath = await this.pluginsPath(); const pluginsPath = this.pluginsPath();
pluginPath = path.join(pluginsPath, pluginPath); pluginPath = path.join(pluginsPath, pluginPath);
const loaded = plugins.find(plugin => plugin.pluginPath === pluginPath); const loaded = plugins.find(plugin => plugin.pluginPath === pluginPath);
@ -68,18 +75,29 @@ class PluginManager extends Module {
const readConfig = await this.readConfig(pluginPath); const readConfig = await this.readConfig(pluginPath);
const mainPath = path.join(pluginPath, readConfig.main); const mainPath = path.join(pluginPath, readConfig.main);
const plugin = window.require(mainPath)(Plugin, {}, {}); //TODO Read plugin user config and call onStart if enabled
const instance = new plugin(); const userConfigPath = path.join(pluginPath, 'user.config.json');
plugins.push(Object.assign({ let userConfig = readConfig.defaultConfig;
pluginPath, try {
instance const readUserConfig = await FileUtils.readJsonFromFile(userConfigPath);
}, readConfig)); userConfig = Object.assign(userConfig, readUserConfig);
} catch (err) {/*We don't care if this fails it either means that user config doesn't exist or there's something wrong with it so we revert to default config*/}
const configs = {
defaultConfig: readConfig.defaultConfig,
userConfig
};
const plugin = window.require(mainPath)(Plugin, {}, {});
const instance = new plugin({configs, info: readConfig.info, main: readConfig.main, paths: { pluginPath }});
if (instance.enabled) instance.start();
plugins.push(instance);
this.setState(plugins); this.setState(plugins);
//TODO Read plugin user config and call onStart if enabled
return instance; return instance;
} catch (err) { } catch (err) {
throw err; throw err;
@ -115,7 +133,7 @@ class PluginManager extends Module {
const _instance = new PluginManager(); const _instance = new PluginManager();
async function tests() { async function pluginManager() {
const pluginName = 'Example'; const pluginName = 'Example';
@ -124,9 +142,15 @@ async function tests() {
const plugin = await _instance.loadPlugin(pluginName); const plugin = await _instance.loadPlugin(pluginName);
//Attempt to load the same plugin again //Attempt to load the same plugin again
const plugin2 = await _instance.loadPlugin(pluginName); const plugin2 = await _instance.loadPlugin(pluginName);
return true;
} catch (err) { } catch (err) {
console.log(`Failed to load plugin! ${err.message}`); console.log(`Failed to load plugin! ${err.message}`);
throw err;
} }
} }
if (window.bdTests) window.bdTests.pluginManager = pluginManager;
else window.bdTests = { pluginManager };
module.exports = { PluginManager: _instance } module.exports = { PluginManager: _instance }

2
core/dist/main.js vendored
View File

@ -34,7 +34,7 @@ const Common = {};
const dummyArgs = { const dummyArgs = {
'version': '0.3.1', 'version': '0.3.1',
'paths': [{ 'base': 'basePath' }, { 'plugins': __pluginPath }, { 'themes': __themePath }] 'paths': [{ 'id': 'base', 'path': 'basePath' }, { 'id': 'plugins', 'path': __pluginPath }, { 'id': 'themes', 'path': __themePath }]
}; };
console.log(dummyArgs); console.log(dummyArgs);

View File

@ -1,6 +1,11 @@
{ {
"info": {
"name": "Example Plugin", "name": "Example Plugin",
"authors": [ "Jiiks" ], "authors": ["Jiiks"],
"version": 1.0, "version": 1.0
"main": "index.js" },
"main": "index.js",
"defaultConfig": {
"foo": "bar"
}
} }