flatmap works

This commit is contained in:
peter
2019-08-28 01:30:31 +02:00
parent 3f3b13c5cb
commit 844b1939dc
4 changed files with 107 additions and 158 deletions
+95 -3
View File
@@ -7,8 +7,7 @@ import { AdminBase } from 'frontblock-generic/Admin';
import { FrontblockApi } from 'frontblock-generic/Api'; import { FrontblockApi } from 'frontblock-generic/Api';
import { Plugin } from 'frontblock-generic/Plugin'; import { Plugin } from 'frontblock-generic/Plugin';
import { socketioRPC } from 'frontblock-generic/RPC'; import { socketioRPC } from 'frontblock-generic/RPC';
import { GitUpdater } from './GitUpdater'; import { GitUpdater, RepoFolderStatus } from './GitUpdater';
import { UpdateManager } from './UpdateManger';
Logger.configure({ Logger.configure({
appenders: appenders:
@@ -28,9 +27,10 @@ export type AdminConf = { httpPort: number}
export class FrontblockAdmin extends AdminBase<AdminConf>{ export class FrontblockAdmin extends AdminBase<AdminConf>{
private pluginUpdaters:{[name in string]:GitUpdater} = {}
constructor(runningPlugins: Plugin[] = []){ constructor(runningPlugins: Plugin[] = []){
super(runningPlugins) super(runningPlugins)
this.addPlugin(new UpdateManager(this))
} }
getDefaultConfig(): { apiConf: FrontblockApiConf; } & AdminConf & { dbConf:Knex.Config; } { getDefaultConfig(): { apiConf: FrontblockApiConf; } & AdminConf & { dbConf:Knex.Config; } {
@@ -66,6 +66,31 @@ export class FrontblockAdmin extends AdminBase<AdminConf>{
return [ return [
...super.exportRPCs(), ...super.exportRPCs(),
{ {
name: 'installPlugin',
func: async (name:string, force = false) => {return await this.installPlugin(name, force)},
type: 'call',
visibility: 'private'
},{
name: 'startPlugin',
func: async (name:string) => {return await this.startPlugin(name)},
type: 'call',
visibility: 'private'
},{
name: 'updatePlugin',
func: async (name) => {return await this.updatePlugin(name)},
type: 'call',
visibility: 'private'
},{
name: 'setPluginVersion',
func: async (name, tag) => {return await this.setPluginVersion(name, tag)},
type: 'call',
visibility: 'private'
},{
name: 'getLoadedPluginNames',
func: async () => {return await this.getPlugins().map(p => p.name)},
type: 'call',
visibility: 'private'
},{
name: 'selfUpdate', name: 'selfUpdate',
type:'call', type:'call',
func: async (force: boolean) => {return await this.selfUpdate(force)}, func: async (force: boolean) => {return await this.selfUpdate(force)},
@@ -87,6 +112,73 @@ export class FrontblockAdmin extends AdminBase<AdminConf>{
} }
return status return status
} }
async installPlugin(name: string, force:boolean = false):Promise<RepoFolderStatus>{
logger.warn("Cloning fb-dist/"+name+".git into ./plugins/"+name+" ..."+(force?" USING FORCE!":""))
this.pluginUpdaters[name] = new GitUpdater("./plugins/"+name)
const status = await this.pluginUpdaters[name].cloneRepo("https://gitea.frontblock.me/fb-dist/"+name.toLowerCase()+".git", force)
return status
}
async startPlugin(name:string):Promise<boolean>{
if(!this.pluginUpdaters[name]) return false
const status = await this.pluginUpdaters[name].getStatus()
if(!status.exists || status.empty || !status.tags || status.tags.length === 0){
if(status.currentTag && !status.latestTag){
//git glitches sometimes if you check immediately after clone
logger.warn("re-fetching tag for "+name+"...")
return await this.startPlugin(name)
}
logger.error("Bad repo status", name, status)
return false
}
/* if(this.loadedPlugins[name]){
logger.error("Plugin", name, "is already started")
return false
}
*/
let str = "../plugins/"+name+"/Plugin"
const pluginClass = await eval('require')(str)
const pluginObj = new pluginClass.default()
await pluginObj.start()
this.addPlugin(pluginObj)
return true
}
async updatePlugin(name:string):Promise<boolean>{
if(!this.pluginUpdaters[name]) return false
const status = await this.pluginUpdaters[name].getStatus()
if(!status.exists || status.empty || !status.tags || status.tags.length === 0){
logger.error("Bad repo status", name, status)
return false
}
if(status.currentTag == status.latestTag){
logger.warn(name, "already at latest tag")
return false
}
/*
if(this.loadedPlugins[name]){
logger.error("Plugin", name, "is running. Stop it first")
return false
}
*/
this.pluginUpdaters[name].checkoutTag(status.latestTag!)
return true
}
async setPluginVersion(pluginName:string, tag:string):Promise<RepoFolderStatus>{
const status = await this.pluginUpdaters[pluginName].getStatus()
if(!status.exists || !status.tags || status.tags.length === 0 || !status.tags.includes(tag)){
logger.error("Bad repo status", pluginName, status)
return status
}
return await this.pluginUpdaters[pluginName].checkoutTag(tag)
}
} }
process.on( 'SIGINT', function() { process.on( 'SIGINT', function() {
+9 -9
View File
@@ -89,20 +89,20 @@ export class FrontblockConfigLib{
} }
window['fb'] = new FrontblockConfigLib() window['fb'] = new FrontblockConfigLib()
declare const fb:{UpdateManager:any} declare const fb:{Admin:any}
window['setup'] = async() => { window['setup'] = async() => {
const i = await Promise.all([ const i = await Promise.all([
fb.UpdateManager.installPlugin("ApiClient"), fb.Admin.installPlugin("ApiClient"),
fb.UpdateManager.installPlugin("HtmlSupplier"), fb.Admin.installPlugin("HtmlSupplier"),
fb.UpdateManager.installPlugin("PaymentManager"), fb.Admin.installPlugin("PaymentManager"),
fb.UpdateManager.installPlugin("Wallet"), fb.Admin.installPlugin("Wallet"),
]) ])
console.log(i) console.log(i)
const s = await Promise.all([ const s = await Promise.all([
fb.UpdateManager.startPlugin("ApiClient"), fb.Admin.startPlugin("ApiClient"),
fb.UpdateManager.startPlugin("HtmlSupplier"), fb.Admin.startPlugin("HtmlSupplier"),
fb.UpdateManager.startPlugin("PaymentManager"), fb.Admin.startPlugin("PaymentManager"),
fb.UpdateManager.startPlugin("Wallet"), fb.Admin.startPlugin("Wallet"),
]) ])
if(s.reduce((p,c) => p && c), true) if(s.reduce((p,c) => p && c), true)
location.reload(); location.reload();
-143
View File
@@ -1,143 +0,0 @@
import { Plugin } from "frontblock-generic/Plugin";
import { socketioRPC } from "frontblock-generic/RPC";
import { GitUpdater, RepoFolderStatus } from "./GitUpdater";
import { FrontblockCherryPicker } from "git-cherrypicker";
import * as Logger from 'log4js'
import { FrontblockAdmin } from "./Admin";
import { TableDefiniton } from "frontblock-generic/Admin";
Logger.configure({
appenders:
{
"admin/updatemanager": { type: 'stdout' },
//app: { type: 'file', filename: 'application.log' }
},
categories:
{
default: { appenders: [ 'admin/updatemanager' ], level: 'debug' }
}
})
const logger = Logger.getLogger("admin/updatemanager")
export class UpdateManager extends Plugin{
private loadedPlugins:{[name in string]:Plugin} = {}
private dashboardUpdater:GitUpdater
private adminUpdater:GitUpdater
private pluginUpdaters:{[name in string]:GitUpdater} = {}
constructor(admin:FrontblockAdmin){
super(admin, "UpdateManager")
}
getDefaultConfig(): {} {
return {}
}
exportRPCs(): socketioRPC[] {
return [{
name: 'installPlugin',
func: async (name:string, force = false) => {return await this.installPlugin(name, force)},
type: 'call',
visibility: 'private'
},{
name: 'startPlugin',
func: async (name:string) => {return await this.startPlugin(name)},
type: 'call',
visibility: 'private'
},{
name: 'updatePlugin',
func: async (name) => {return await this.updatePlugin(name)},
type: 'call',
visibility: 'private'
},{
name: 'setPluginVersion',
func: async (name, tag) => {return await this.setPluginVersion(name, tag)},
type: 'call',
visibility: 'private'
},{
name: 'getLoadedPluginNames',
func: async () => {return await this.getLoadedPluginNames()},
type: 'call',
visibility: 'private'
}]
}
getTableDefinitions(): TableDefiniton[] {
return []
}
async installPlugin(name: string, force:boolean = false):Promise<RepoFolderStatus>{
logger.warn("Cloning fb-dist/"+name+".git into ./plugins/"+name+" ..."+(force?" USING FORCE!":""))
this.pluginUpdaters[name] = new GitUpdater("./plugins/"+name)
const status = await this.pluginUpdaters[name].cloneRepo("https://gitea.frontblock.me/fb-dist/"+name.toLowerCase()+".git", force)
return status
}
async startPlugin(name:string):Promise<boolean>{
if(!this.pluginUpdaters[name]) return false
const status = await this.pluginUpdaters[name].getStatus()
if(!status.exists || status.empty || !status.tags || status.tags.length === 0){
if(status.currentTag && !status.latestTag){
//git glitches sometimes if you check immediately after clone
logger.warn("re-fetching tag for "+name+"...")
return await this.startPlugin(name)
}
logger.error("Bad repo status", name, status)
return false
}
if(this.loadedPlugins[name]){
logger.error("Plugin", name, "is already started")
return false
}
let str = "../plugins/"+name+"/Plugin"
const pluginClass = await eval('require')(str)
const pluginObj = new pluginClass.default()
await pluginObj.start()
this.admin.addPlugin(pluginObj)
this.loadedPlugins[name] = pluginObj
return true
}
async updatePlugin(name:string):Promise<boolean>{
if(!this.pluginUpdaters[name]) return false
const status = await this.pluginUpdaters[name].getStatus()
if(!status.exists || status.empty || !status.tags || status.tags.length === 0){
logger.error("Bad repo status", name, status)
return false
}
if(status.currentTag == status.latestTag){
logger.warn(name, "already at latest tag")
return false
}
if(this.loadedPlugins[name]){
logger.error("Plugin", name, "is running. Stop it first")
return false
}
this.pluginUpdaters[name].checkoutTag(status.latestTag!)
return true
}
async setPluginVersion(pluginName:string, tag:string):Promise<RepoFolderStatus>{
const status = await this.pluginUpdaters[pluginName].getStatus()
if(!status.exists || !status.tags || status.tags.length === 0 || !status.tags.includes(tag)){
logger.error("Bad repo status", pluginName, status)
return status
}
return await this.pluginUpdaters[pluginName].checkoutTag(tag)
}
getLoadedPlugins():Plugin<any>[]{
return Object.values(this.loadedPlugins)
}
getLoadedPluginNames():string[]{
return Object.keys(this.loadedPlugins)
}
}
@@ -52,7 +52,7 @@ import { FrontendPlugin, SidebarEntries, SidebarEntry } from "frontblock-generic
import { environment } from "../../environments/environment" import { environment } from "../../environments/environment"
const fb = environment.production ? window["fb"] : { const fb = environment.production ? window["fb"] : {
UpdateManager: { Admin: {
getLoadedPluginNames: () => ["ApiClient", "Wallet"] getLoadedPluginNames: () => ["ApiClient", "Wallet"]
} }
} }
@@ -78,10 +78,10 @@ export class DynamicLoaderComponent implements AfterViewInit {
} }
private async loadWidgets() { private async loadWidgets() {
while (!fb.UpdateManager) { while (!fb.Admin) {
await new Promise((resolve) => setTimeout(resolve, 50)) await new Promise((resolve) => setTimeout(resolve, 50))
} }
const pluginNames = await fb.UpdateManager.getLoadedPluginNames() const pluginNames = await fb.Admin.getLoadedPluginNames()
pluginNames.forEach(element => this.installWidget(element)); pluginNames.forEach(element => this.installWidget(element));
} }