Console command connect to ipc

This commit is contained in:
Anthony Laibe 2018-08-08 13:42:45 +01:00 committed by Iuri Matias
parent b1498164a1
commit 27933774a9
15 changed files with 191 additions and 103 deletions

View File

@ -65,6 +65,7 @@ class EmbarkController {
let self = this; let self = this;
self.context = options.context || [constants.contexts.run, constants.contexts.build]; self.context = options.context || [constants.contexts.run, constants.contexts.build];
let Dashboard = require('./dashboard/dashboard.js'); let Dashboard = require('./dashboard/dashboard.js');
let REPL = require('./dashboard/repl.js');
let webServerConfig = { let webServerConfig = {
enabled: options.runWebserver enabled: options.runWebserver
@ -101,6 +102,13 @@ class EmbarkController {
async.parallel([ async.parallel([
function startDashboard(callback) { function startDashboard(callback) {
if (!options.useDashboard) { if (!options.useDashboard) {
new REPL({
env: engine.env,
plugins: engine.plugins,
version: engine.version,
events: engine.events,
ipc: engine.ipc
}).startConsole();
return callback(); return callback();
} }
@ -109,7 +117,8 @@ class EmbarkController {
logger: engine.logger, logger: engine.logger,
plugins: engine.plugins, plugins: engine.plugins,
version: self.version, version: self.version,
env: engine.env env: engine.env,
ipc: engine.ipc
}); });
dashboard.start(function () { dashboard.start(function () {
engine.logger.info(__('dashboard start')); engine.logger.info(__('dashboard start'));
@ -243,7 +252,7 @@ class EmbarkController {
console(options) { console(options) {
this.context = options.context || [constants.contexts.run, constants.contexts.console]; this.context = options.context || [constants.contexts.run, constants.contexts.console];
const REPL = require('../lib/dashboard/repl.js'); const REPL = require('./dashboard/repl.js');
const Engine = require('../lib/core/engine.js'); const Engine = require('../lib/core/engine.js');
const engine = new Engine({ const engine = new Engine({
env: options.env, env: options.env,
@ -253,7 +262,8 @@ class EmbarkController {
embarkConfig: options.embarkConfig || 'embark.json', embarkConfig: options.embarkConfig || 'embark.json',
logFile: options.logFile, logFile: options.logFile,
logLevel: options.logLevel, logLevel: options.logLevel,
context: this.context context: this.context,
ipcRole: 'client'
}); });
engine.init(); engine.init();
async.waterfall([ async.waterfall([
@ -263,25 +273,58 @@ class EmbarkController {
engine.logger.info(__("loaded plugins") + ": " + pluginList.join(", ")); engine.logger.info(__("loaded plugins") + ": " + pluginList.join(", "));
} }
engine.ipc.connect((err) => {
if (err) {
engine.startService("processManager"); engine.startService("processManager");
engine.startService("serviceMonitor"); engine.startService("serviceMonitor");
engine.startService("libraryManager"); engine.startService("libraryManager");
engine.startService("codeRunner"); engine.startService("codeRunner");
engine.startService("web3"); engine.startService("web3");
engine.startService("pipeline"); engine.startService("pipeline");
engine.startService("deployment", {onlyCompile: false}); engine.startService("deployment");
engine.startService("storage"); engine.startService("storage");
engine.startService("codeGenerator"); engine.startService("codeGenerator");
engine.startService("fileWatcher"); engine.startService("webServer");
return callback();
}
engine.startService("codeRunner");
callback(); callback();
});
},
function web3IPC(callback) {
if(!engine.ipc.connected || engine.ipc.isServer()) {
return callback();
}
const Web3 = require('web3');
let web3 = new Web3();
engine.ipc.request("runcode:getCommands", null, (_, {web3Config, commands}) => {
web3.setProvider(web3Config.provider.host);
web3.eth.defaultAccount = web3Config.defaultAccount;
engine.events.emit("runcode:register", "web3", web3);
async.each(commands, ({varName, code}, next) => {
if (varName) {
engine.events.emit("runcode:register", varName, code);
} else {
engine.events.request("runcode:eval", code);
}
next();
}, callback);
});
}, },
function deploy(callback) { function deploy(callback) {
if(engine.ipc.connected && engine.ipc.isClient()) {
return callback();
}
engine.events.request('deploy:contracts', function (err) { engine.events.request('deploy:contracts', function (err) {
callback(err); callback(err);
}); });
}, },
function waitForWriteFinish(callback) { function waitForWriteFinish(callback) {
if(engine.ipc.connected && engine.ipc.isClient()) {
return callback();
}
engine.logger.info("Finished deploying".underline); engine.logger.info("Finished deploying".underline);
engine.events.once('outputDone', (err) => { engine.events.once('outputDone', (err) => {
engine.logger.info(__("finished building").underline); engine.logger.info(__("finished building").underline);
@ -293,7 +336,8 @@ class EmbarkController {
env: engine.env, env: engine.env,
plugins: engine.plugins, plugins: engine.plugins,
version: engine.version, version: engine.version,
events: engine.events events: engine.events,
ipc: engine.ipc
}); });
repl.start(callback); repl.start(callback);
} }

View File

@ -5,11 +5,11 @@ class Console {
this.events = options.events; this.events = options.events;
this.plugins = options.plugins; this.plugins = options.plugins;
this.version = options.version; this.version = options.version;
this.contractsConfig = options.contractsConfig; this.ipc = options.ipc;
}
runCode(code) { if (this.ipc.isServer()) {
this.events.request('runcode:eval', code); this.ipc.on('console:executeCmd', this.executeCmd.bind(this));
}
} }
processEmbarkCmd (cmd) { processEmbarkCmd (cmd) {
@ -37,26 +37,25 @@ class Console {
executeCmd(cmd, callback) { executeCmd(cmd, callback) {
var pluginCmds = this.plugins.getPluginsProperty('console', 'console'); var pluginCmds = this.plugins.getPluginsProperty('console', 'console');
for (let pluginCmd of pluginCmds) { for (let pluginCmd of pluginCmds) {
let pluginOutput = pluginCmd.call(this, cmd, {}); let pluginResult = pluginCmd.call(this, cmd, {});
if (pluginOutput !== false && pluginOutput !== 'false' && pluginOutput !== undefined) return callback(pluginOutput); if (pluginResult.match()) {
return pluginResult.process(callback);
}
} }
let output = this.processEmbarkCmd(cmd); let output = this.processEmbarkCmd(cmd);
if (output) { if (output) {
return callback(output); return callback(null, output);
} }
try { try {
this.events.request('runcode:eval', cmd, (err, result) => { this.events.request('runcode:eval', cmd, callback, true);
callback(result);
});
} }
catch (e) { catch (e) {
if (e.message.indexOf('not defined') > 0) { if (this.ipc.connected && this.ipc.isClient()) {
return callback(("error: " + e.message).red + ("\n" + __("Type") + " " + "help".bold + " " + __("to see the list of available commands")).cyan); return this.ipc.request('console:executeCmd', cmd, callback);
} else {
return callback(e.message);
} }
return callback(e.message);
} }
} }
} }

View File

@ -11,6 +11,7 @@ class Dashboard {
this.plugins = options.plugins; this.plugins = options.plugins;
this.version = options.version; this.version = options.version;
this.env = options.env; this.env = options.env;
this.ipc = options.ipc;
this.events.on('firstDeploymentDone', this.checkWindowSize.bind(this)); this.events.on('firstDeploymentDone', this.checkWindowSize.bind(this));
this.events.on('outputDone', this.checkWindowSize.bind(this)); this.events.on('outputDone', this.checkWindowSize.bind(this));
@ -32,7 +33,8 @@ class Dashboard {
console = new Console({ console = new Console({
events: self.events, events: self.events,
plugins: self.plugins, plugins: self.plugins,
version: self.version version: self.version,
ipc: self.ipc
}); });
callback(); callback();
}, },

View File

@ -368,7 +368,7 @@ class Monitor {
executeCmd(cmd, cb) { executeCmd(cmd, cb) {
const self = this; const self = this;
self.logText.log('console> '.bold.green + cmd); self.logText.log('console> '.bold.green + cmd);
self.console.executeCmd(cmd, function (result) { self.console.executeCmd(cmd, function (_, result) {
self.logText.log(result); self.logText.log(result);
if (cb) { if (cb) {
cb(result); cb(result);

View File

@ -8,17 +8,21 @@ class REPL {
this.env = options.env; this.env = options.env;
this.plugins = options.plugins; this.plugins = options.plugins;
this.events = options.events; this.events = options.events;
this.version = options.version;
this.ipc = options.ipc;
}
startConsole(){
this.console = new Console({ this.console = new Console({
events: this.events, events: this.events,
plugins: this.plugins, plugins: this.plugins,
version: options.version version: this.version,
ipc: this.ipc
}); });
} }
enhancedEval(cmd, context, filename, callback) { enhancedEval(cmd, context, filename, callback) {
this.console.executeCmd(cmd.trim(), (result) => { this.console.executeCmd(cmd.trim(), callback);
callback(null, result);
});
} }
enhancedWriter(output) { enhancedWriter(output) {
@ -30,6 +34,7 @@ class REPL {
} }
start(done) { start(done) {
this.startConsole();
this.replServer = repl.start({ this.replServer = repl.start({
prompt: "Embark (" + this.env + ") > ", prompt: "Embark (" + this.env + ") > ",
useGlobal: true, useGlobal: true,

View File

@ -17,6 +17,7 @@ class Engine {
this.context = options.context; this.context = options.context;
this.useDashboard = options.useDashboard; this.useDashboard = options.useDashboard;
this.webServerConfig = options.webServerConfig; this.webServerConfig = options.webServerConfig;
this.ipcRole = options.ipcRole;
} }
init(_options) { init(_options) {
@ -35,6 +36,11 @@ class Engine {
if (this.interceptLogs || this.interceptLogs === undefined) { if (this.interceptLogs || this.interceptLogs === undefined) {
utils.interceptLogs(console, this.logger); utils.interceptLogs(console, this.logger);
} }
this.ipc = new IPC({logger: this.logger, ipcRole: this.ipcRole});
if (this.ipc.isServer()) {
this.ipc.serve();
}
} }
registerModule(moduleName, options) { registerModule(moduleName, options) {
@ -126,7 +132,8 @@ class Engine {
this.codeRunner = new CodeRunner({ this.codeRunner = new CodeRunner({
plugins: this.plugins, plugins: this.plugins,
events: this.events, events: this.events,
logger: this.logger logger: this.logger,
ipc: this.ipc
}); });
} }
@ -157,18 +164,13 @@ class Engine {
let self = this; let self = this;
this.registerModule('compiler', {plugins: self.plugins}); this.registerModule('compiler', {plugins: self.plugins});
this.registerModule('solidity', {ipc: self.ipc, useDashboard: this.useDashboard});
this.ipc = new IPC({logger: this.logger, ipcRole: options.ipcRole});
if (this.ipc.isServer()) {
this.ipc.serve();
}
this.registerModule('solidity', {ipc: this.ipc, useDashboard: this.useDashboard});
this.registerModule('vyper'); this.registerModule('vyper');
this.registerModule('profiler'); this.registerModule('profiler');
this.registerModule('deploytracker'); this.registerModule('deploytracker');
this.registerModule('specialconfigs'); this.registerModule('specialconfigs');
this.registerModule('console_listener', {ipc: this.ipc}); this.registerModule('specialconfigs');
this.registerModule('console_listener', {ipc: self.ipc});
this.registerModule('contracts_manager'); this.registerModule('contracts_manager');
this.registerModule('deployment', {plugins: this.plugins, onlyCompile: options.onlyCompile}); this.registerModule('deployment', {plugins: this.plugins, onlyCompile: options.onlyCompile});

View File

@ -52,7 +52,7 @@ class IPC {
return; return;
} }
let reply = function(_err, replyData) { let reply = function(_err, replyData) {
self.reply(socket, 'compile', replyData); self.reply(socket, action, replyData);
}; };
done(data.message, reply, socket); done(data.message, reply, socket);
}); });
@ -62,6 +62,14 @@ class IPC {
ipc.server.emit(client, 'message', {action: action, message: data}); ipc.server.emit(client, 'message', {action: action, message: data});
} }
listenTo(action, callback) {
ipc.of['embark'].on(action, callback);
}
broadcast(action, data) {
ipc.server.broadcast(action, data);
}
once(action, cb) { once(action, cb) {
ipc.of['embark'].once('message', function(msg) { ipc.of['embark'].once('message', function(msg) {
if (msg.action !== action) { if (msg.action !== action) {

View File

@ -6,27 +6,50 @@ class CodeRunner {
this.plugins = options.plugins; this.plugins = options.plugins;
this.logger = options.logger; this.logger = options.logger;
this.events = options.events; this.events = options.events;
this.ipc = options.ipc;
this.commands = [];
let self = this;
// necessary to init the context // necessary to init the context
RunCode.initContext(); RunCode.initContext();
if (this.ipc.isServer()) {
this.ipc.on('runcode:getCommands', (_, callback) => {
let result = {web3Config: RunCode.getWeb3Config(), commands: self.commands};
callback(null, result);
});
}
if (this.ipc.isClient() && this.ipc.connected) {
this.ipc.listenTo('runcode:newCommand', function (command) {
if (command.varName) {
self.events.emit("runcode:register", command.varName, command.code);
} else {
self.events.request("runcode:eval", command.code);
}
});
}
this.events.on("runcode:register", (varName, code) => { this.events.on("runcode:register", (varName, code) => {
if (self.ipc.isServer() && varName !== 'web3') {
self.commands.push({varName, code});
self.ipc.broadcast("runcode:newCommand", {varName, code});
}
RunCode.registerVar(varName, code); RunCode.registerVar(varName, code);
}); });
this.events.setCommandHandler('runcode:eval', (code, cb) => { this.events.setCommandHandler('runcode:eval', (code, cb, dashboard = false) => {
if (!cb) { if (!cb) {
cb = function() {}; cb = function() {};
} }
try {
let result = RunCode.doEval(code); let result = RunCode.doEval(code);
cb(null, result); if (!dashboard && self.ipc.isServer()) {
} catch (e) { self.commands.push({code});
cb(e); self.ipc.broadcast("runcode:newCommand", {code});
} }
cb(null, result);
}); });
} }
} }
module.exports = CodeRunner; module.exports = CodeRunner;

View File

@ -23,8 +23,13 @@ function registerVar(varName, code) {
__mainContext[varName] = code; __mainContext[varName] = code;
} }
function getWeb3Config() {
return {defaultAccount:__mainContext.web3.eth.defaultAccount, provider: __mainContext.web3.currentProvider};
}
module.exports = { module.exports = {
doEval: doEval, doEval,
registerVar: registerVar, registerVar,
initContext: initContext initContext,
getWeb3Config
}; };

View File

@ -1,13 +1,3 @@
let async = require('async');
const constants = require('./constants');
require('colors');
// Set PWD to CWD since Windows doesn't have a value for PWD
if (!process.env.PWD) {
process.env.PWD = process.cwd();
}
let version = require('../package.json').version; let version = require('../package.json').version;
class Embark { class Embark {
@ -29,7 +19,6 @@ class Embark {
this.config.loadConfigFiles(options); this.config.loadConfigFiles(options);
this.plugins = this.config.plugins; this.plugins = this.config.plugins;
} }
} }
module.exports = Embark; module.exports = Embark;

View File

@ -38,14 +38,16 @@ class LibraryManager {
registerCommands() { registerCommands() {
const self = this; const self = this;
this.embark.registerConsoleCommand((cmd, _options) => { this.embark.registerConsoleCommand((cmd, _options) => {
if (cmd === "versions" || cmd === __('versions')) { return {
match: () => cmd === "versions" || cmd === __('versions'),
process: (callback) => {
let text = [__('versions in use') + ':']; let text = [__('versions in use') + ':'];
for (let lib in self.versions) { for (let lib in self.versions) {
text.push(lib + ": " + self.versions[lib]); text.push(lib + ": " + self.versions[lib]);
} }
return text.join('\n'); callback(null, text.join('\n'));
} }
return false; };
}); });
} }

View File

@ -11,7 +11,7 @@ class Profiler {
this.registerConsoleCommand(); this.registerConsoleCommand();
} }
profile(contractName, contract) { profile(contractName, contract, callback) {
const self = this; const self = this;
let table = new asciiTable(contractName); let table = new asciiTable(contractName);
table.setHeading('Function', 'Payable', 'Mutability', 'Inputs', 'Outputs', 'Gas Estimates'); table.setHeading('Function', 'Payable', 'Mutability', 'Inputs', 'Outputs', 'Gas Estimates');
@ -33,7 +33,7 @@ class Profiler {
table.addRow(abiMethod.name, abiMethod.payable, abiMethod.stateMutability, self.formatParams(abiMethod.inputs), self.formatParams(abiMethod.outputs), gastimates[abiMethod.name]); table.addRow(abiMethod.name, abiMethod.payable, abiMethod.stateMutability, self.formatParams(abiMethod.inputs), self.formatParams(abiMethod.outputs), gastimates[abiMethod.name]);
} }
}); });
self.logger.info(table.toString()); callback(null, table.toString());
}); });
} }
@ -53,18 +53,18 @@ class Profiler {
self.embark.registerConsoleCommand((cmd, _options) => { self.embark.registerConsoleCommand((cmd, _options) => {
let cmdName = cmd.split(' ')[0]; let cmdName = cmd.split(' ')[0];
let contractName = cmd.split(' ')[1]; let contractName = cmd.split(' ')[1];
if (cmdName === 'profile') {
return {
match: () => cmdName === 'profile',
process: (callback) => {
self.events.request('contracts:contract', contractName, (contract) => { self.events.request('contracts:contract', contractName, (contract) => {
if (!contract || !contract.deployedAddress) { if (!contract || !contract.deployedAddress) {
self.logger.info("-- couldn't profile " + contractName + " - it's not deployed or could be an interface"); return "-- couldn't profile " + contractName + " - it's not deployed or could be an interface";
return "";
} }
self.logger.info("-- profile for " + contractName); this.profile(contractName, contract, callback);
this.profile(contractName, contract);
}); });
return "";
} }
return false; };
}); });
} }
} }

View File

@ -50,18 +50,25 @@ class WebServer {
registerConsoleCommands() { registerConsoleCommands() {
const self = this; const self = this;
self.embark.registerConsoleCommand((cmd, _options) => { self.embark.registerConsoleCommand((cmd, _options) => {
if (cmd === 'webserver start') { return {
match: () => cmd === "webserver start",
process: (callback) => {
self.events.request("start-webserver"); self.events.request("start-webserver");
return " "; callback(null, "OK");
} }
if (cmd === 'webserver stop') { };
});
self.embark.registerConsoleCommand((cmd, _options) => {
return {
match: () => cmd === "webserver stop",
process: (callback) => {
self.events.request("stop-webserver"); self.events.request("stop-webserver");
return __("stopping webserver") + "..."; callback(null, "OK");
} }
return false; };
}); });
} }
} }
module.exports = WebServer; module.exports = WebServer;

View File

@ -116,8 +116,7 @@ class Test {
web3: this.web3 web3: this.web3
}); });
this.engine.startService("deployment", { this.engine.startService("deployment", {
trackContracts: false, trackContracts: false
ipcRole: 'client'
}); });
this.events.request('deploy:setGasLimit', 6000000); this.events.request('deploy:setGasLimit', 6000000);
this.engine.startService("codeCoverage"); this.engine.startService("codeCoverage");
@ -128,7 +127,8 @@ class Test {
env: this.options.env || 'test', env: this.options.env || 'test',
// TODO: config will need to detect if this is a obj // TODO: config will need to detect if this is a obj
embarkConfig: this.options.embarkConfig || 'embark.json', embarkConfig: this.options.embarkConfig || 'embark.json',
interceptLogs: false interceptLogs: false,
ipcRole: 'client'
}); });
this.engine.init({ this.engine.init({

View File

@ -1,19 +1,21 @@
/*globals describe, it*/ /*globals describe, it*/
let Console = require('../cmd/dashboard/console.js'); let Console = require('../cmd/dashboard/console.js');
let Plugins = require('../lib/core/plugins.js'); let Plugins = require('../lib/core/plugins.js');
let IPC = require('../lib/core/ipc.js');
let assert = require('assert'); let assert = require('assert');
let version = require('../package.json').version; let version = require('../package.json').version;
describe('embark.Console', function() { describe('embark.Console', function() {
let ipc = new IPC({ipcRole: 'none'});
let plugins = new Plugins({plugins: {}}); let plugins = new Plugins({plugins: {}});
let console = new Console({plugins: plugins, version: version}); let console = new Console({plugins, version, ipc});
describe('#executeCmd', function() { describe('#executeCmd', function() {
describe('command: help', function() { describe('command: help', function() {
it('it should provide a help text', function(done) { it('it should provide a help text', function(done) {
console.executeCmd('help', function(output) { console.executeCmd('help', function(_err, output) {
let lines = output.split('\n'); let lines = output.split('\n');
assert.equal(lines[0], 'Welcome to Embark ' + version); assert.equal(lines[0], 'Welcome to Embark ' + version);
assert.equal(lines[2], 'possible commands are:'); assert.equal(lines[2], 'possible commands are:');