diff --git a/cmd/cmd_controller.js b/cmd/cmd_controller.js index 6e35d3b2b..d965cfe1d 100644 --- a/cmd/cmd_controller.js +++ b/cmd/cmd_controller.js @@ -127,6 +127,7 @@ class EmbarkController { engine.startService("codeGenerator"); engine.startService("namingSystem"); engine.startService("console"); + engine.startService("pluginCommand"); engine.events.on('check:backOnline:Ethereum', function () { engine.logger.info(__('Ethereum node detected') + '..'); @@ -280,7 +281,7 @@ class EmbarkController { engine.startService("webServer"); engine.startService("namingSystem"); engine.startService("console"); - + engine.startService("pluginCommand"); return callback(); } diff --git a/lib/core/engine.js b/lib/core/engine.js index 7554d43f2..23af30e40 100644 --- a/lib/core/engine.js +++ b/lib/core/engine.js @@ -70,7 +70,8 @@ class Engine { "processManager": this.processManagerService, "storage": this.storageService, "graph": this.graphService, - "codeCoverage": this.codeCoverageService + "codeCoverage": this.codeCoverageService, + "pluginCommand": this.pluginCommandService }; let service = services[serviceName]; @@ -130,6 +131,10 @@ class Engine { this.servicesMonitor.startMonitor(); } + pluginCommandService() { + this.registerModule('plugin_cmd', {embarkConfigFile: this.embarkConfig, embarkConfig: this.config.embarkConfig, packageFile: 'package.json'}); + } + namingSystem(_options) { this.registerModule('ens'); } diff --git a/lib/modules/plugin_cmd/index.js b/lib/modules/plugin_cmd/index.js new file mode 100644 index 000000000..b840c51a7 --- /dev/null +++ b/lib/modules/plugin_cmd/index.js @@ -0,0 +1,58 @@ +let fs = require('./../../core/fs.js'); +let utils = require('./../../utils/utils.js'); +let async = require('async'); +class PluginCommand { + constructor(embark) { + this.embark = embark; + this.config = this.embark.pluginConfig; + this.embarkConfig = this.config.embarkConfig; + this.registerCommand(); + } + registerCommand() { + const self = this; + self.embark.registerConsoleCommand((cmd, _options) => { + let cmdArray = cmd.split(' '); + cmdArray = cmdArray.filter(cmd => cmd.trim().length > 0); + let cmdName = cmdArray[0]; + return { + match: () => cmdName === 'plugin', + process: (callback) => { + if(cmdArray.length < 3 || cmdArray[1] !== 'install' || typeof cmdArray[2] === 'undefined') { + return callback('invalid use of plugin command. Please use plugin install '); + } + let npmInstall = ['npm', 'install', '--save']; + npmInstall = npmInstall.concat(cmdArray.slice(2)); + let npmPackage = npmInstall[3]; + self.embark.logger.info(`Installing npm package ${npmPackage} ...`); + async.waterfall([ + function npmInstallAsync(cb) { + utils.runCmd(npmInstall.join(' '), {silent: false, exitOnError: false}, (err) => { + if(err) { + return cb(err); + } + cb(); + }); + }, + function addToEmbarkConfig(cb) { + // get the installed package from package.json + let packageFile = fs.readJSONSync(self.config.packageFile); + let dependencies = Object.keys(packageFile.dependencies); + let installedPackage = dependencies.filter((dep) => npmPackage.indexOf(dep) >=0); + self.embarkConfig.plugins[installedPackage[0]] = {}; + fs.writeFile(self.config.embarkConfigFile, JSON.stringify(self.embarkConfig, null, 2), cb); + } + ], (err) => { + if(err) { + let errorMessage = `Error installing npm package ${npmPackage}. Please visit https://embark.status.im/plugins/ for all supported plugins`; + self.embark.logger.error(errorMessage); + return callback('Error occurred'); + } + callback(null, `npm package ${npmPackage} successfully installed as a plugin`); + }); + } + }; + }); + } +} + +module.exports = PluginCommand; diff --git a/lib/utils/utils.js b/lib/utils/utils.js index acc2ade9c..293c06b5c 100644 --- a/lib/utils/utils.js +++ b/lib/utils/utils.js @@ -129,17 +129,37 @@ function pingEndpoint(host, port, type, protocol, origin, callback) { }); } -function runCmd(cmd, options) { +function runCmd(cmd, options, callback) { const shelljs = require('shelljs'); - let result = shelljs.exec(cmd, options || {silent: true}); - if (result.code !== 0) { - console.log("error doing.. " + cmd); - console.log(result.output); - if (result.stderr !== undefined) { - console.log(result.stderr); + options = Object.assign({silent: true, exitOnError: true, async: true}, options || {}); + const outputToConsole = !options.silent; + options.silent = true; + let result = shelljs.exec(cmd, options, function (code, stdout) { + if(code !== 0) { + if (options.exitOnError) { + return exit(); + } + if(typeof callback === 'function') { + callback(`shell returned code ${code}`); + } + } else { + if(typeof callback === 'function') { + return callback(null, stdout); + } } - exit(); - } + }); + + result.stdout.on('data', function(data) { + if(outputToConsole) { + console.log(data); + } + }); + + result.stderr.on('data', function(data) { + if (outputToConsole) { + console.log(data); + } + }); } function cd(folder) {