From db0b872435cc3ef41157fdd745c1365c4a56ebe7 Mon Sep 17 00:00:00 2001 From: peter Date: Tue, 27 Aug 2019 16:26:09 +0200 Subject: [PATCH] npm --- src/backend/Extension.ts | 136 +++++++++++++++++++++++++-------- src/backend/FrontblockAdmin.ts | 4 +- src/backend/UpdateManger.ts | 29 +++---- 3 files changed, 122 insertions(+), 47 deletions(-) diff --git a/src/backend/Extension.ts b/src/backend/Extension.ts index 51fa10e..7eec3ed 100644 --- a/src/backend/Extension.ts +++ b/src/backend/Extension.ts @@ -83,30 +83,30 @@ export type FSStatus = SharedStatus & { export abstract class FSExtension extends Extension{ constructor( name: string, - protected readonly prefix: string){ + protected readonly path: string){ super(name) } public async status(): Promise{ const shdStatus = await super.status() const empty = await this.isEmpty() - return {...shdStatus, prefix: this.prefix, empty: empty} + return {...shdStatus, prefix: this.path, empty: empty} } public async install():Promise{ const installed = await this.isInstalled() if (!installed) { - logger.info('Installing extension to', path.resolve(this.prefix, this.name)) - await fs.mkdir(path.resolve(this.prefix, this.name), {recursive: true}) + logger.info('Installing extension to', path.resolve(this.path, this.name)) + await fs.mkdir(path.resolve(this.path, this.name), {recursive: true}) return true } - logger.warn('Extension already installed at', path.resolve(this.prefix, this.name)) + logger.error('Extension already installed at', path.resolve(this.path, this.name)) return false } public async uninstall(): Promise{ - logger.info('Uninstalling extension from', path.resolve(this.prefix, this.name)) - return await trash(path.resolve(this.prefix, this.name)) + logger.info('Uninstalling extension from', path.resolve(this.path, this.name)) + return await trash(path.resolve(this.path, this.name)) } public async update(force?: boolean): Promise{ @@ -117,17 +117,17 @@ export abstract class FSExtension extends Extension{ if (!this.isInstalled()) return true try { - const files = await fs.readdir(path.resolve(this.prefix, this.name)) + const files = await fs.readdir(path.resolve(this.path, this.name)) return files.length === 0 } catch (error) { - logger.warn('TODO') + logger.error("fs read error", error) return } } public async isInstalled(): Promise{ try { - await fs.access(path.resolve(this.prefix, this.name)) + await fs.access(path.resolve(this.path, this.name)) return true } catch (error) { return false @@ -139,39 +139,48 @@ type NPMStatus = FSStatus & { latest?: string, current?: string, author?: string + license?: string, + description?: string } export class NPMExtension extends FSExtension{ constructor( pkgName: string, - prefix: string){ - super(pkgName, prefix) + private version: string, + private prefix: string + ){ + super(pkgName, path.resolve(prefix, "node_modules")) } public async status(): Promise { - const fsStatus = await super.status() - const latest = await this.getLatestVersion() - const author = await this.getAuthor() - const current = await this.getCurrentVersion() + const fsStatus = await super.status() + const latest = await this.getLatestVersion() + const author = await this.getAuthor() + const current = await this.getCurrentVersion() + const license = await this.getLicense() + const description = await this.getDescription() + return { ...fsStatus, latest: latest, author: author, - current: current + current: current, + license: license, + description: description } } public async install(): Promise { super.install() logger.info("npm install", this.name, 'to', path.resolve(this.prefix, this.name)) - const { error, stdout, stderr } = await exec('npm install --prefix '+ this.prefix + ' ' + this.name) - if (error !== null) { - logger.warn('npm install', this.name, 'from prefix', this.prefix, 'stderr:', stderr) + const { error, stdout, stderr } = await exec('npm install --prefix '+ this.prefix + ' ' + this.name+"@"+this.version) + if (error) { + logger.error('npm install', this.name, "@", this.version, ' from prefix', this.prefix, 'stderr:', stderr) return false } else { - logger.info('npm install', this.name, 'from prefix', this.prefix, 'stdout:', stdout) + logger.info('npm install', this.name, "@", this.version, 'from prefix', this.prefix, 'stdout:', stdout) return true } } @@ -181,7 +190,7 @@ export class NPMExtension extends FSExtension{ logger.info("npm uninstall", this.name, 'from', path.resolve(this.prefix, this.name)) const { error, stdout, stderr } = await exec('npm uninstall --prefix '+ this.prefix + ' ' + this.name) if (error) { - logger.warn('npm uninstall', this.name, 'from prefix', this.prefix, 'stderr:', stderr) + logger.error('npm uninstall', this.name, 'from prefix', this.prefix, 'stderr:', stderr) } else { logger.info('npm uninstall', this.name, 'from prefix', this.prefix, 'stdout:', stdout) } @@ -192,7 +201,7 @@ export class NPMExtension extends FSExtension{ logger.info("npm update", path.resolve(this.prefix, this.name)) const { error, stdout, stderr } = await exec('npm update --prefix '+ this.prefix + ' ' + this.name) if (error) { - logger.warn('npm update', this.name, 'from prefix', this.prefix, 'stderr:', stderr) + logger.error('npm update', this.name, 'from prefix', this.prefix, 'stderr:', stderr) return false } else { logger.info('npm update', this.name, 'from prefix', this.prefix, 'stdout:', stdout) @@ -210,7 +219,7 @@ export class NPMExtension extends FSExtension{ if (Object.keys(JSON.parse(stdout)).length > 0) return true else return false } catch (error) { - logger.warn('npm outdated', this.name, 'from prefix', this.prefix, 'stderr:', error) + logger.error('npm outdated', this.name, 'from prefix', this.prefix, 'stderr:', error) return } } @@ -222,7 +231,7 @@ export class NPMExtension extends FSExtension{ stderr } = await exec('npm author ls --prefix ' + this.prefix + ' ' + this.name) if(error){ - logger.warn(stderr) + logger.error(stderr) return } else { logger.info(stdout) @@ -231,22 +240,84 @@ export class NPMExtension extends FSExtension{ } private async getLatestVersion(): Promise{ - const { + try{ + const { error, stdout, stderr } = await exec('npm view --prefix ' + this.prefix + ' ' + this.name + " version") - if(error){ - logger.warn(stderr) + if(error){ + logger.error(stderr) + return + } else { + logger.info(stdout) + return stdout + } + }catch(error){ + logger.error(error) return - } else { - logger.info(stdout) - return stdout } } private async getCurrentVersion(): Promise{ - return //TODO + try{ + const { + error, + stdout, + stderr } = await exec('npm list --json --prefix ' + this.prefix + ' ' + this.name) + + if(error){ + logger.error(stderr) + return + } else { + logger.info(stdout) + return JSON.parse(stdout)['dependencies'][this.name]['version'] + } + }catch(error){ + logger.error(error) + return + } + } + + private async getDescription(): Promise{ + try{ + const { + error, + stdout, + stderr } = await exec('npm show --prefix ' + this.prefix + ' ' + this.name+" description") + + if(error){ + logger.error(stderr) + return + } else { + logger.info(stdout) + return stdout + } + }catch(error){ + logger.error(error) + return + } + } + + private async getLicense(): Promise{ + try{ + + const { + error, + stdout, + stderr } = await exec('npm show --prefix ' + this.prefix + ' ' + this.name+" license") + + if(error){ + logger.error(stderr) + return + } else { + logger.info(stdout) + return stdout + } + }catch(error){ + logger.error(error) + return + } } } @@ -288,6 +359,7 @@ export class GitExtension extends FSExtension{ } else { } + return false; } diff --git a/src/backend/FrontblockAdmin.ts b/src/backend/FrontblockAdmin.ts index 96e26f4..a7368b7 100644 --- a/src/backend/FrontblockAdmin.ts +++ b/src/backend/FrontblockAdmin.ts @@ -2,7 +2,7 @@ import * as Logger from 'log4js' import * as Knex from 'knex' -import { FrontblockApiClient } from 'frontblock'; +import { FrontblockApiClient, FrontblockApiConf } from 'frontblock'; import { socketioRPC, rpcHooker, ExtendedRpcInfo } from 'frontblock-generic/RPC'; import { ApiClientBase, AdminBase } from 'frontblock-generic/Admin'; import express = require('express'); @@ -11,7 +11,7 @@ import bsock = require('bsock'); import { promises as fs } from "fs" import * as path from "path" import { UpdateManager } from './UpdateManger'; -import { FrontblockApiConf, FrontblockApi } from 'frontblock-generic/Api'; +import { FrontblockApi } from 'frontblock-generic/Api'; import { Plugin } from 'frontblock-generic/Plugin'; var exec = require('child-process-promise').exec; diff --git a/src/backend/UpdateManger.ts b/src/backend/UpdateManger.ts index 6243ee7..847c4e3 100644 --- a/src/backend/UpdateManger.ts +++ b/src/backend/UpdateManger.ts @@ -3,15 +3,9 @@ import { socketioRPC } from "frontblock-generic/RPC"; import { GitUpdater, RepoFolderStatus } from "./GitUpdater"; import { FrontblockCherryPicker } from "git-cherrypicker"; import * as Logger from 'log4js' -import * as path from "path"; -import * as rmrf from "rimraf" import { FrontblockAdmin } from "./FrontblockAdmin"; +import { NPMExtension } from "./Extension"; import { TableDefiniton } from "frontblock-generic/Admin"; -import { promises as fs, mkdirSync as mkdir } from "fs" -import { version } from "punycode"; -import * as git from "simple-git/promise" -import * as trash from "trash" -import { type } from "os"; var exec = require('child-process-promise').exec; @@ -30,6 +24,7 @@ const logger = Logger.getLogger("admin/updatemanager") export class UpdateManager extends Plugin{ + private loadedPlugins:{[name in string]:Plugin} = {} private dashboardUpdater:GitUpdater private adminUpdater:GitUpdater @@ -46,7 +41,7 @@ export class UpdateManager extends Plugin{ exportRPCs(): socketioRPC[] { return [{ name: 'installPlugin', - func: async (name:string, force = false) => {return await this.installPlugin(name, force)}, + func: async (name:string, force = false) => { }, type: 'call', visibility: 'private' },{ @@ -80,7 +75,7 @@ export class UpdateManager extends Plugin{ getTableDefinitions(): TableDefiniton[] { return [] } - + async updatePlatformDependencies(){ logger.info("installing npm stuff") @@ -90,10 +85,18 @@ export class UpdateManager extends Plugin{ logger.warn(res.stderr) logger.info(res.stdout) */ - await Promise.all([ - new NPMExtension("knex@0.19.2", "./plugins").install(), - new NPMExtension("sqlite3@4.1.0", "./plugins").install() - ]) + + const extensions = [ + new NPMExtension("knex", "0.19.2", "./plugins"), + new NPMExtension("sqlite3", "4.1.0", "./plugins"), + new NPMExtension("frontblock", "latest", "./plugins") + ] + + + + await Promise.all(extensions.map(e => e.install())) + const status = await Promise.all(extensions.map(e => e.status())) + console.log(status) } async updateAdmin(force:boolean = false){