From bc29221b9cfc318ba6b0cfc2c4b0ecde0828430c Mon Sep 17 00:00:00 2001 From: MiaoWoo Date: Fri, 15 May 2020 14:28:40 +0800 Subject: [PATCH] feat: support config auto save Signed-off-by: MiaoWoo --- packages/i18n/languages/en.yml | 2 + packages/i18n/languages/zh_cn.yml | 2 + packages/plugin/src/config.ts | 2 +- packages/plugin/src/interfaces.ts | 4 ++ packages/plugin/src/manager.ts | 67 ++++++++++++++++++++----------- 5 files changed, 53 insertions(+), 24 deletions(-) diff --git a/packages/i18n/languages/en.yml b/packages/i18n/languages/en.yml index 02076024..b3e88bb2 100644 --- a/packages/i18n/languages/en.yml +++ b/packages/i18n/languages/en.yml @@ -43,4 +43,6 @@ ms.plugin.manager.build.error: "§6Load Plugin From §b{file} §6failed. §4Erro ms.plugin.manager.build.update: "Auto Update Plugin {name} ..." ms.plugin.manager.build.not.extends: "§4Found error plugin §b{source} §4it's not extends interfaces.Plugin, the plugin will be ignore!" ms.plugin.manager.build.exists: "§4Found duplicate plugin §b{exists} §4and §b{source}§4. the first plugin will be ignore!" +ms.plugin.manager.config.load.error: "[{plugin}] config {name}.{format} load failed. Error: {error}" +ms.plugin.manager.config.save.error: "[{plugin}] config {name}.{format} save failed. Error: {error}" ms.plugin.manager.config.save.default: "[{plugin}] config {name}.{format} not exists. auto create from default variable..." diff --git a/packages/i18n/languages/zh_cn.yml b/packages/i18n/languages/zh_cn.yml index e0182c21..9fe1b3a0 100644 --- a/packages/i18n/languages/zh_cn.yml +++ b/packages/i18n/languages/zh_cn.yml @@ -43,4 +43,6 @@ ms.plugin.manager.build.error: "§6从文件 §b{file} §6加载插件失败 §4 ms.plugin.manager.build.update: "自动更新插件 {name} ..." ms.plugin.manager.build.not.extends: "§4发现错误的插件 §b{source} §4未继承接口 interfaces.Plugin, 将不会被载入到服务器!" ms.plugin.manager.build.duplicate: "§4发现已存在插件 §b{exists} §4和 §b{source}§4 存在冲突. 已存在插件将会被替换!" +ms.plugin.manager.config.load.error: "[{plugin}] 配置 {name}.{format} 加载失败. 错误: {error}" +ms.plugin.manager.config.save.error: "[{plugin}] 配置 {name}.{format} 保存失败. 错误: {error}" ms.plugin.manager.config.save.default: "[{plugin}] 配置 {name}.{format} 不存在. 从默认值自动创建保存..." diff --git a/packages/plugin/src/config.ts b/packages/plugin/src/config.ts index 258e4259..4f049059 100644 --- a/packages/plugin/src/config.ts +++ b/packages/plugin/src/config.ts @@ -10,7 +10,7 @@ export class YamlPluginConfig implements PluginConfigLoader { return yaml.safeLoad(content); } dump(variable: any): string { - return yaml.safeDump(variable); + return yaml.safeDump(variable, { skipInvalid: true }); } } diff --git a/packages/plugin/src/interfaces.ts b/packages/plugin/src/interfaces.ts index f449700a..d02dfc20 100644 --- a/packages/plugin/src/interfaces.ts +++ b/packages/plugin/src/interfaces.ts @@ -100,6 +100,10 @@ export namespace interfaces { * 配置文件格式 默认 yml */ format?: string; + /** + * 是否为只读(关闭时将不会自动保存) + */ + readonly?: boolean; } export type PluginLike = Plugin | string; } diff --git a/packages/plugin/src/manager.ts b/packages/plugin/src/manager.ts index f4af10aa..a1e43b28 100644 --- a/packages/plugin/src/manager.ts +++ b/packages/plugin/src/manager.ts @@ -16,7 +16,7 @@ export class PluginManagerImpl implements plugin.PluginManager { @inject(plugin.PluginInstance) private pluginInstance: any @inject(plugin.PluginFolder) - private pluginFolder: string; + private pluginFolder: string @inject(server.ServerType) private serverType: string @inject(command.Command) @@ -33,11 +33,11 @@ export class PluginManagerImpl implements plugin.PluginManager { if (this.pluginInstance !== null && this.initialized !== true) { // 如果plugin不等于null 则代表是正式环境 console.i18n('ms.plugin.initialize', { plugin: this.pluginInstance, loader: Thread.currentThread().contextClassLoader }) - console.i18n('ms.plugin.event.map', { count: this.EventManager.mapEventName().toFixed(0), type: this.serverType }); + console.i18n('ms.plugin.event.map', { count: this.EventManager.mapEventName().toFixed(0), type: this.serverType }) this.pluginRequireMap = new Map() this.pluginInstanceMap = new Map() - this.pluginMetadataMap = getPluginSources(); - this.initialized = true; + this.pluginMetadataMap = getPluginSources() + this.initialized = true } } @@ -69,11 +69,11 @@ export class PluginManagerImpl implements plugin.PluginManager { * @param file java.io.File */ loadFromFile(file: string): interfaces.Plugin { - let metadata = this.loadPlugin(file); + let metadata = this.loadPlugin(file) let plugin = this.buildPlugin(metadata && metadata.description ? metadata.description : this.pluginMetadataMap.get(file.toString())) this.load(plugin) this.enable(plugin) - return plugin; + return plugin } load(...args: any[]): void { @@ -96,6 +96,7 @@ export class PluginManagerImpl implements plugin.PluginManager { disable(...args: any[]): void { this.checkAndGet(args[0]).forEach((plugin: interfaces.Plugin) => { this.runPluginStage(plugin, 'disable', () => { + this.saveConfig(plugin) this.unregistryCommand(plugin) this.unregistryListener(plugin) }) @@ -197,14 +198,14 @@ export class PluginManagerImpl implements plugin.PluginManager { private createPlugin(file: string) { //@ts-ignore let instance = require(file, { cache: false }) - this.pluginRequireMap.set(file, instance); - return instance; + this.pluginRequireMap.set(file, instance) + return instance } private buildPlugins() { - let metadatas = []; + let metadatas = [] let pluginMetadatas = getPluginMetadatas() - for (const [_, metadata] of pluginMetadatas) { metadatas.push(metadata); } + for (const [_, metadata] of pluginMetadatas) { metadatas.push(metadata) } for (const [_, instance] of this.pluginRequireMap) { if (instance.description) { this.buildPlugin(instance.description) } } for (const metadata of metadatas) { if (!this.allowProcess(metadata.servers)) { continue } @@ -213,7 +214,7 @@ export class PluginManagerImpl implements plugin.PluginManager { } private buildPlugin(metadata: interfaces.PluginMetadata) { - let pluginInstance: interfaces.Plugin; + let pluginInstance: interfaces.Plugin switch (metadata.type) { case "ioc": try { @@ -227,15 +228,15 @@ export class PluginManagerImpl implements plugin.PluginManager { console.i18n("ms.plugin.manager.initialize.error", { name: metadata.name, ex }) console.ex(ex) } - break; + break case "basic": pluginInstance = this.pluginRequireMap.get(metadata.source.toString()) - break; + break default: throw new Error('§4不支持的插件类型 请检查加载器是否正常启用!') } this.pluginInstanceMap.set(metadata.name, pluginInstance) - return pluginInstance; + return pluginInstance } private bindPlugin(metadata: interfaces.PluginMetadata) { @@ -251,15 +252,35 @@ export class PluginManagerImpl implements plugin.PluginManager { } private loadConfig(plugin: interfaces.Plugin) { - let configs = getPluginConfigMetadata(plugin); + let configs = getPluginConfigMetadata(plugin) for (let [_, config] of configs) { - let configFile = fs.concat(root, this.pluginFolder, plugin.description.name, config.name + '.' + config.format) - let configFactory = getConfigLoader(config.format); - if (!fs.exists(configFile)) { - base.save(configFile, configFactory.dump(plugin[config.variable])) - console.i18n("ms.plugin.manager.config.save.default", { plugin: plugin.description.name, name: config.name, format: config.format }) - } else { - plugin[config.variable] = configFactory.load(base.read(configFile)); + try { + let configFile = fs.concat(root, this.pluginFolder, plugin.description.name, config.name + '.' + config.format) + let configFactory = getConfigLoader(config.format) + if (!fs.exists(configFile)) { + base.save(configFile, configFactory.dump(plugin[config.variable])) + console.i18n("ms.plugin.manager.config.save.default", { plugin: plugin.description.name, name: config.name, format: config.format }) + } else { + plugin[config.variable] = configFactory.load(base.read(configFile)) + plugin[config.variable].save = () => base.save(configFile, configFactory.dump(plugin[config.variable])) + } + } catch (error) { + console.i18n("ms.plugin.manager.config.load.error", { plugin: plugin.description.name, name: config.name, format: config.format, error }) + console.ex(error) + } + } + } + + private saveConfig(plugin: interfaces.Plugin) { + let configs = getPluginConfigMetadata(plugin) + for (let [_, config] of configs) { + try { + let configFile = fs.concat(root, this.pluginFolder, plugin.description.name, config.name + '.' + config.format) + let configFactory = getConfigLoader(config.format) + if (!config.readonly) { base.save(configFile, configFactory.dump(plugin[config.variable])) } + } catch (error) { + console.i18n("ms.plugin.manager.config.save.error", { plugin: plugin.description.name, name: config.name, format: config.format, error }) + console.ex(error) } } } @@ -299,7 +320,7 @@ export class PluginManagerImpl implements plugin.PluginManager { } private execPluginStage(pluginInstance: interfaces.Plugin, stageName: string) { - let stages = getPluginStageMetadata(pluginInstance, stageName); + let stages = getPluginStageMetadata(pluginInstance, stageName) for (const stage of stages) { if (!this.allowProcess(stage.servers)) { continue } console.i18n("ms.plugin.manager.stage.exec", { plugin: pluginInstance.description.name, name: stage.executor, stage: stageName, servers: stage.servers })