this changes Embark to an EventEmitter and adds more event handling for loading and fetching plugins. It introduces a dependency on underscore and underscore string. It adds defenses against null/invalid options objects.

This commit is contained in:
Todd Baur 2017-03-30 00:37:30 +09:00
parent 7ed493d1a2
commit 2f5c647c39
11 changed files with 256 additions and 223 deletions

View File

@ -1,30 +1,29 @@
var async = require('async'); let async = require('async');
var Deploy = require('./deploy.js'); let Deploy = require('./deploy.js');
var ContractsManager = require('./contracts.js'); let ContractsManager = require('./contracts.js');
var DeployManager = function(options) { let DeployManager = function(options) {
this.config = options.config; this.config = options.config;
this.logger = options.logger; this.logger = options.logger;
this.blockchainConfig = this.config.blockchainConfig; this.blockchainConfig = this.config.blockchainConfig;
this.plugins = options.plugins; this.plugins = options.plugins;
this.events = options.events;
this.web3 = options.web3; this.web3 = options.web3;
this.chainConfig = (options.trackContracts !== false) ? this.config.chainTracker : false; this.chainConfig = (options.trackContracts !== false) ? this.config.chainTracker : false;
}; };
DeployManager.prototype.deployContracts = function(done) { DeployManager.prototype.deployContracts = function(done) {
var self = this; let self = this;
if (self.blockchainConfig === {} || self.blockchainConfig.enabled === false) { if (self.blockchainConfig === {} || self.blockchainConfig.enabled === false) {
self.logger.info("Blockchain component is disabled in the config".underline); self.logger.info("Blockchain component is disabled in the config".underline);
self.events.emit('blockchainDisabled', {}); Embark.emit('blockchainDisabled', {});
return done(); return done();
} }
async.waterfall([ async.waterfall([
function buildContracts(callback) { function buildContracts(callback) {
var contractsManager = new ContractsManager({ let contractsManager = new ContractsManager({
contractFiles: self.config.contractsFiles, contractFiles: self.config.contractsFiles,
contractsConfig: self.config.contractsConfig, contractsConfig: self.config.contractsConfig,
logger: self.logger, logger: self.logger,
@ -57,14 +56,14 @@ DeployManager.prototype.deployContracts = function(done) {
if (err) { if (err) {
return callback(new Error(err)); return callback(new Error(err));
} }
var accountConfig = self.config.blockchainConfig.account; let accountConfig = self.config.blockchainConfig.account;
var selectedAccount = accountConfig && accountConfig.address; let selectedAccount = accountConfig && accountConfig.address;
web3.eth.defaultAccount = (selectedAccount || accounts[0]); web3.eth.defaultAccount = (selectedAccount || accounts[0]);
callback(null, contractsManager, web3); callback(null, contractsManager, web3);
}); });
}, },
function deployAllContracts(contractsManager, web3, callback) { function deployAllContracts(contractsManager, web3, callback) {
var deploy = new Deploy({ let deploy = new Deploy({
web3: web3, web3: web3,
contractsManager: contractsManager, contractsManager: contractsManager,
logger: self.logger, logger: self.logger,
@ -72,7 +71,7 @@ DeployManager.prototype.deployContracts = function(done) {
env: self.config.env env: self.config.env
}); });
deploy.deployAll(function() { deploy.deployAll(function() {
self.events.emit('contractsDeployed', contractsManager); Embark.emit('contractsDeployed', contractsManager);
callback(null, contractsManager); callback(null, contractsManager);
}); });
} }

View File

@ -1,10 +1,10 @@
var fs = require('./fs.js'); let fs = require('./fs.js');
var Plugins = require('./plugins.js'); let Plugins = require('./plugins.js');
var utils = require('../utils/utils.js'); let utils = require('../utils/utils.js');
// TODO: add wrapper for fs so it can also work in the browser // TODO: add wrapper for fs so it can also work in the browser
// can work with both read and save // can work with both read and save
var Config = function(options) { let Config = function(options) {
this.env = options.env; this.env = options.env;
this.blockchainConfig = {}; this.blockchainConfig = {};
this.contractsConfig = {}; this.contractsConfig = {};
@ -21,13 +21,13 @@ var Config = function(options) {
}; };
Config.prototype.loadConfigFiles = function(options) { Config.prototype.loadConfigFiles = function(options) {
var interceptLogs = options.interceptLogs; let interceptLogs = options.interceptLogs;
if (options.interceptLogs === undefined) { if (options.interceptLogs === undefined) {
interceptLogs = true; interceptLogs = true;
} }
//Check if the config file exists //Check if the config file exists
var embarkConfigExists = fs.existsSync(options.embarkConfig); let embarkConfigExists = fs.existsSync(options.embarkConfig);
if(!embarkConfigExists){ if(!embarkConfigExists){
this.logger.error('Cannot find file ' + options.embarkConfig + '. Please ensure you are running this command inside the Dapp folder'); this.logger.error('Cannot find file ' + options.embarkConfig + '. Please ensure you are running this command inside the Dapp folder');
process.exit(1); process.exit(1);
@ -39,20 +39,10 @@ Config.prototype.loadConfigFiles = function(options) {
this.plugins = new Plugins({plugins: this.embarkConfig.plugins, logger: this.logger, interceptLogs: interceptLogs, events: this.events, config: this}); this.plugins = new Plugins({plugins: this.embarkConfig.plugins, logger: this.logger, interceptLogs: interceptLogs, events: this.events, config: this});
this.plugins.loadPlugins(); this.plugins.loadPlugins();
this.loadEmbarkConfigFile(); this.load();
this.loadBlockchainConfigFile();
this.loadStorageConfigFile();
this.loadCommunicationConfigFile();
this.loadPipelineConfigFile();
this.loadContractsConfigFile();
this.loadWebServerConfigFile();
this.loadChainTrackerFile();
this.loadPluginContractFiles();
}; };
Config.prototype.reloadConfig = function() { Config.prototype.load = Config.prototype.reloadConfig = function() {
this.loadEmbarkConfigFile(); this.loadEmbarkConfigFile();
this.loadBlockchainConfigFile(); this.loadBlockchainConfigFile();
this.loadStorageConfigFile(); this.loadStorageConfigFile();
@ -63,7 +53,7 @@ Config.prototype.reloadConfig = function() {
}; };
Config.prototype.loadBlockchainConfigFile = function() { Config.prototype.loadBlockchainConfigFile = function() {
var defaultBlockchainConfig = fs.readJSONSync(this.configDir + "blockchain.json"); let defaultBlockchainConfig = fs.readJSONSync(this.configDir + "blockchain.json");
this.blockchainConfig = defaultBlockchainConfig[this.env] || {}; this.blockchainConfig = defaultBlockchainConfig[this.env] || {};
if (this.blockchainConfig.enabled === undefined) { if (this.blockchainConfig.enabled === undefined) {
@ -73,9 +63,11 @@ Config.prototype.loadBlockchainConfigFile = function() {
Config.prototype.loadContractsConfigFile = function() { Config.prototype.loadContractsConfigFile = function() {
var configObject = {}; let configObject = {};
let configPlugins = [];
var configPlugins = this.plugins.getPluginsFor('contractsConfig'); this.plugins.emit('get', 'contractsConfig', (kinds) => {
configPlugins = kinds;
});
if (configPlugins.length > 0) { if (configPlugins.length > 0) {
configPlugins.forEach(function(plugin) { configPlugins.forEach(function(plugin) {
plugin.contractsConfigs.forEach(function(pluginConfig) { plugin.contractsConfigs.forEach(function(pluginConfig) {
@ -84,18 +76,17 @@ Config.prototype.loadContractsConfigFile = function() {
}); });
} }
var contractsConfig = fs.readJSONSync(this.configDir + "contracts.json"); let contractsConfig = fs.readJSONSync(this.configDir + "contracts.json");
configObject = utils.recursiveMerge(configObject, contractsConfig); configObject = utils.recursiveMerge(configObject, contractsConfig);
var defaultContractsConfig = configObject['default']; let defaultContractsConfig = configObject['default'];
var envContractsConfig = configObject[this.env]; let envContractsConfig = configObject[this.env];
var mergedConfig = utils.recursiveMerge(defaultContractsConfig, envContractsConfig); this.contractsConfig = utils.recursiveMerge(defaultContractsConfig, envContractsConfig);
this.contractsConfig = mergedConfig;
}; };
Config.prototype.loadStorageConfigFile = function() { Config.prototype.loadStorageConfigFile = function() {
var configObject = { let configObject = {
"default": { "default": {
"enabled": true, "enabled": true,
"available_providers": ["ipfs"], "available_providers": ["ipfs"],
@ -108,7 +99,7 @@ Config.prototype.loadStorageConfigFile = function() {
} }
}; };
//var configPlugins = this.plugins.getPluginsFor('storageConfig'); //let configPlugins = this.plugins.getPluginsFor('storageConfig');
//if (configPlugins.length > 0) { //if (configPlugins.length > 0) {
// configPlugins.forEach(function(plugin) { // configPlugins.forEach(function(plugin) {
// plugin.contractsConfigs.forEach(function(pluginConfig) { // plugin.contractsConfigs.forEach(function(pluginConfig) {
@ -117,16 +108,16 @@ Config.prototype.loadStorageConfigFile = function() {
// }); // });
//} //}
var storageConfig; let storageConfig;
if (fs.existsSync(this.configDir + "storage.json")) { if (fs.existsSync(this.configDir + "storage.json")) {
storageConfig = fs.readJSONSync(this.configDir + "storage.json"); storageConfig = fs.readJSONSync(this.configDir + "storage.json");
configObject = utils.recursiveMerge(configObject, storageConfig); configObject = utils.recursiveMerge(configObject, storageConfig);
} }
var defaultStorageConfig = configObject['default']; let defaultStorageConfig = configObject['default'];
var envStorageConfig = configObject[this.env]; let envStorageConfig = configObject[this.env];
var mergedConfig = utils.recursiveMerge(defaultStorageConfig, envStorageConfig); let mergedConfig = utils.recursiveMerge(defaultStorageConfig, envStorageConfig);
this.storageConfig = mergedConfig || {}; this.storageConfig = mergedConfig || {};
if (this.storageConfig.enabled === undefined) { if (this.storageConfig.enabled === undefined) {
@ -138,7 +129,7 @@ Config.prototype.loadStorageConfigFile = function() {
}; };
Config.prototype.loadCommunicationConfigFile = function() { Config.prototype.loadCommunicationConfigFile = function() {
var configObject = { let configObject = {
"default": { "default": {
"enabled": true, "enabled": true,
"provider": "whisper", "provider": "whisper",
@ -146,7 +137,7 @@ Config.prototype.loadCommunicationConfigFile = function() {
} }
}; };
//var configPlugins = this.plugins.getPluginsFor('communicationConfig'); //let configPlugins = this.plugins.getPluginsFor('communicationConfig');
//if (configPlugins.length > 0) { //if (configPlugins.length > 0) {
// configPlugins.forEach(function(plugin) { // configPlugins.forEach(function(plugin) {
// plugin.contractsConfigs.forEach(function(pluginConfig) { // plugin.contractsConfigs.forEach(function(pluginConfig) {
@ -155,17 +146,17 @@ Config.prototype.loadCommunicationConfigFile = function() {
// }); // });
//} //}
var communicationConfig; let communicationConfig;
if (fs.existsSync(this.configDir + "communication.json")) { if (fs.existsSync(this.configDir + "communication.json")) {
communicationConfig = fs.readJSONSync(this.configDir + "communication.json"); communicationConfig = fs.readJSONSync(this.configDir + "communication.json");
configObject = utils.recursiveMerge(configObject, communicationConfig); configObject = utils.recursiveMerge(configObject, communicationConfig);
} }
var defaultCommunicationConfig = configObject['default']; let defaultCommunicationConfig = configObject['default'];
var envCommunicationConfig = configObject[this.env]; let envCommunicationConfig = configObject[this.env];
var mergedConfig = utils.recursiveMerge(defaultCommunicationConfig, envCommunicationConfig); let mergedConfig = utils.recursiveMerge(defaultCommunicationConfig, envCommunicationConfig);
this.communicationConfig = mergedConfig || {}; this.communicationConfig = mergedConfig || {};
// TODO: probably not necessary if the default object is done right // TODO: probably not necessary if the default object is done right
@ -178,13 +169,13 @@ Config.prototype.loadCommunicationConfigFile = function() {
}; };
Config.prototype.loadWebServerConfigFile = function() { Config.prototype.loadWebServerConfigFile = function() {
var webServerConfigJSON; let webServerConfigJSON;
if (fs.existsSync(this.configDir + "webserver.json")) { if (fs.existsSync(this.configDir + "webserver.json")) {
webServerConfigJSON = fs.readJSONSync(this.configDir + "webserver.json"); webServerConfigJSON = fs.readJSONSync(this.configDir + "webserver.json");
} else { } else {
webServerConfigJSON = {}; webServerConfigJSON = {};
} }
var defaultWebConfig = { let defaultWebConfig = {
"enabled": true, "enabled": true,
"host": "localhost", "host": "localhost",
"port": 8000 "port": 8000
@ -193,7 +184,7 @@ Config.prototype.loadWebServerConfigFile = function() {
}; };
Config.prototype.loadEmbarkConfigFile = function() { Config.prototype.loadEmbarkConfigFile = function() {
var contracts = this.embarkConfig.contracts; let contracts = this.embarkConfig.contracts;
this.contractsFiles = this.loadFiles(contracts); this.contractsFiles = this.loadFiles(contracts);
this.buildDir = this.embarkConfig.buildDir; this.buildDir = this.embarkConfig.buildDir;
@ -201,15 +192,15 @@ Config.prototype.loadEmbarkConfigFile = function() {
}; };
Config.prototype.loadPipelineConfigFile = function() { Config.prototype.loadPipelineConfigFile = function() {
var assets = this.embarkConfig.app; let assets = this.embarkConfig.app;
for(var targetFile in assets) { for(let targetFile in assets) {
this.assetFiles[targetFile] = this.loadFiles(assets[targetFile]); this.assetFiles[targetFile] = this.loadFiles(assets[targetFile]);
} }
}; };
Config.prototype.loadChainTrackerFile = function() { Config.prototype.loadChainTrackerFile = function() {
//var self = this; //let self = this;
var chainTracker; let chainTracker;
try { try {
chainTracker = fs.readJSONSync(this.chainsFile); chainTracker = fs.readJSONSync(this.chainsFile);
} }
@ -222,9 +213,9 @@ Config.prototype.loadChainTrackerFile = function() {
}; };
Config.prototype.loadFiles = function(files) { Config.prototype.loadFiles = function(files) {
var self = this; let self = this;
var originalFiles = utils.filesMatchingPattern(files); let originalFiles = utils.filesMatchingPattern(files);
var readFiles = []; let readFiles = [];
// get embark.js object first // get embark.js object first
originalFiles.filter(function(file) { originalFiles.filter(function(file) {
@ -251,16 +242,16 @@ Config.prototype.loadFiles = function(files) {
}); });
// get plugins // get plugins
var filesFromPlugins = []; let filesFromPlugins = [];
var filePlugins = self.plugins.getPluginsFor('pipelineFiles'); let filePlugins = self.plugins.getPluginsFor('pipelineFiles');
if (filePlugins.length > 0) { if (filePlugins.length > 0) {
filePlugins.forEach(function(plugin) { filePlugins.forEach(function(plugin) {
try { try {
var fileObjects = plugin.runFilePipeline(); let fileObjects = plugin.runFilePipeline();
for (var i=0; i < fileObjects.length; i++) { for (let i=0; i < fileObjects.length; i++) {
var fileObject = fileObjects[i]; let fileObject = fileObjects[i];
filesFromPlugins.push(fileObject); filesFromPlugins.push(fileObject);
} }
} }
@ -293,13 +284,13 @@ Config.prototype.loadFiles = function(files) {
}; };
Config.prototype.loadPluginContractFiles = function() { Config.prototype.loadPluginContractFiles = function() {
var self = this; let self = this;
var contractsPlugins = this.plugins.getPluginsFor('contractFiles'); let contractsPlugins = this.plugins.getPluginsFor('contractFiles');
if (contractsPlugins.length > 0) { if (contractsPlugins.length > 0) {
contractsPlugins.forEach(function(plugin) { contractsPlugins.forEach(function(plugin) {
plugin.contractsFiles.forEach(function(file) { plugin.contractsFiles.forEach(function(file) {
var filename = file.replace('./',''); let filename = file.replace('./','');
self.contractsFiles.push({filename: filename, content: plugin.loadPluginFile(file), path: plugin.pathToFile(file)}); self.contractsFiles.push({filename: filename, content: plugin.loadPluginFile(file), path: plugin.pathToFile(file)});
}); });
}); });

View File

@ -1,3 +1,4 @@
var EventEmitter = require('events'); //TODO: This is deprecated because Embark extends EventEmitter now
let EventEmitter = require('events');
module.exports = EventEmitter; module.exports = EventEmitter;

View File

@ -1,14 +1,23 @@
/*jshint esversion: 6, loopfunc: true */ /*jshint esversion: 6, loopfunc: true */
var fs = require('./fs.js'); let fs = require('./fs.js');
var utils = require('../utils/utils.js'); let utils = require('../utils/utils.js');
let camelcase = require("underscore.string").camelcase;
let Plugin = function(options) {
this.config = {};
for (let opt in options) {
if (options.hasOwnProperty(opt)) {
this.config[opt] = options[opt];
}
}
let requiredOptions = ['name', 'pluginModule', 'pluginPath', 'config', 'interceptLogs', 'logger'];
for (let i = 0; requiredOptions.length > i; i++) {
if (!(utils.contains(Object.keys(this.config), requiredOptions[i]))) {
throw new Error('Missing required plugin configuration key: ' + requiredOptions[i]);
}
}
// TODO: pass other params like blockchainConfig, contract files, etc..
var Plugin = function(options) {
this.name = options.name;
this.pluginModule = options.pluginModule;
this.pluginPath = options.pluginPath;
this.pluginConfig = options.pluginConfig;
this.shouldInterceptLogs = options.interceptLogs;
this.clientWeb3Providers = []; this.clientWeb3Providers = [];
this.contractsGenerators = []; this.contractsGenerators = [];
this.pipeline = []; this.pipeline = [];
@ -19,16 +28,18 @@ var Plugin = function(options) {
this.compilers = []; this.compilers = [];
this.serviceChecks = []; this.serviceChecks = [];
this.pluginTypes = []; this.pluginTypes = [];
this.logger = options.logger;
this.events = options.events; if (!(this instanceof Plugin)) {
this.config = options.config; return new Plugin();
}
}; };
Plugin.prototype.loadPlugin = function() { Plugin.prototype.runPlugin = Plugin.prototype.run = function() {
if (this.shouldInterceptLogs) { if (this.shouldInterceptLogs) {
this.interceptLogs(this.pluginModule); this.interceptLogs(this.pluginModule);
} }
(this.pluginModule.call(this, this)); let fullyQualifiedPath = this.pathToFile(this.config.pluginModule);
this.call(this.loadPluginFile(fullyQualifiedPath), this);
}; };
Plugin.prototype.loadPluginFile = function(filename) { Plugin.prototype.loadPluginFile = function(filename) {
@ -40,7 +51,7 @@ Plugin.prototype.pathToFile = function(filename) {
}; };
Plugin.prototype.interceptLogs = function(context) { Plugin.prototype.interceptLogs = function(context) {
var self = this; let self = this;
// TODO: this is a bit nasty, figure out a better way // TODO: this is a bit nasty, figure out a better way
context.console = context.console || console; context.console = context.console || console;
@ -67,6 +78,19 @@ Plugin.prototype.interceptLogs = function(context) {
}; };
}; };
Plugin.prototype.register = function (classname, cb) {
let camelCasedClassname = camelcase(classname);
this[camelCasedClassname].push(cb);
this.pluginTypes.push({class: classname, call: cb});
};
["ClientWeb3Provider", "ContractsGeneration", "Pipeline", "Deployer",
"ConsoleCommand", "ServiceCheck", "ContractConfiguration", "Compiler"].forEach(function (name) {
Plugin.prototype["register" + name] = function (cb) {
Plugin.prototype.register.call(name, cb);
};
});
// TODO: add deploy provider // TODO: add deploy provider
Plugin.prototype.registerClientWeb3Provider = function(cb) { Plugin.prototype.registerClientWeb3Provider = function(cb) {
this.clientWeb3Providers.push(cb); this.clientWeb3Providers.push(cb);
@ -137,10 +161,10 @@ Plugin.prototype.runCommands = function(cmd, options) {
}; };
Plugin.prototype.runFilePipeline = function() { Plugin.prototype.runFilePipeline = function() {
var self = this; let self = this;
return this.pipelineFiles.map(function(file) { return this.pipelineFiles.map(function(file) {
var obj = {}; let obj = {};
obj.filename = file.file.replace('./',''); obj.filename = file.file.replace('./','');
obj.content = self.loadPluginFile(file.file).toString(); obj.content = self.loadPluginFile(file.file).toString();
obj.intendedPath = file.intendedPath; obj.intendedPath = file.intendedPath;
@ -153,8 +177,8 @@ Plugin.prototype.runFilePipeline = function() {
Plugin.prototype.runPipeline = function(args) { Plugin.prototype.runPipeline = function(args) {
// TODO: should iterate the pipelines // TODO: should iterate the pipelines
var pipeline = this.pipeline[0]; let pipeline = this.pipeline[0];
var shouldRunPipeline = utils.fileMatchesPattern(pipeline.matcthingFiles, args.targetFile); let shouldRunPipeline = utils.fileMatchesPattern(pipeline.matcthingFiles, args.targetFile);
if (shouldRunPipeline) { if (shouldRunPipeline) {
return pipeline.cb.call(this, args); return pipeline.cb.call(this, args);
} else { } else {

View File

@ -1,45 +1,52 @@
var Plugin = require('./plugin.js'); const _ = require('underscore');
var utils = require('../utils/utils.js'); const EventEmitter = require('events').EventEmitter;
let Plugins = function (options) {
//TODO: put an observer on this.plugins and call loadPlugin when a new item is added
this.config = {};
for (let opt in options) {
if (options.hasOwnProperty(opt)) {
this.config[opt] = options[opt];
}
}
let requiredOptions = ['interceptLogs', 'plugins', 'logger'];
for (let i = 0; requiredOptions.length > i; i++) {
if (!(_.contains(Object.keys(this.config), requiredOptions[i]))) {
console.log('Warning: missing required plugin configuration key: ' + requiredOptions[i]);
}
}
this.on('load', () => {
this.load();
});
this.on('get', (pluginType, cb) => {
let pluginTypes = getPluginsFor(pluginType, this.config.plugins);
return cb(pluginTypes);
});
var Plugins = function(options) {
this.pluginList = options.plugins || [];
this.interceptLogs = options.interceptLogs;
this.plugins = [];
// TODO: need backup 'NullLogger'
this.logger = options.logger;
this.events = options.events;
this.config = options.config;
}; };
Plugins.prototype.loadPlugins = function() { Plugins.prototype.load = Plugins.prototype.loadPlugins = function () {
var pluginConfig; let pluginConfig;
for (var pluginName in this.pluginList) { for (let i = 0; this.config.plugins.length > i; i++) {
pluginConfig = this.pluginList[pluginName]; pluginConfig = this.config.plugins[i].config;
this.loadPlugin(pluginName, pluginConfig); let Plugin = require('./plugin');
let plugin = new Plugin(pluginConfig);
plugin.run();
} }
}; };
Plugins.prototype.listPlugins = function () { Plugins.prototype.listPlugins = function () {
var list = []; return this.config.plugins.join(', ');
for (var className in this.pluginList) {
list.push(className);
}
return list;
}; };
Plugins.prototype.loadPlugin = function(pluginName, pluginConfig) { let getPluginsFor = function (pluginType, plugins) {
var pluginPath = utils.joinPath(process.env.PWD, 'node_modules', pluginName); return _.filter(plugins, pluginType);
var plugin = require(pluginPath);
var pluginWrapper = new Plugin({name: pluginName, pluginModule: plugin, pluginConfig: pluginConfig, logger: this.logger, pluginPath: pluginPath, interceptLogs: this.interceptLogs, events: this.events, config: this.config});
pluginWrapper.loadPlugin();
this.plugins.push(pluginWrapper);
}; };
Plugins.prototype.getPluginsFor = function(pluginType) { Plugins.prototype.getPluginsFor = getPluginsFor;
return this.plugins.filter(function(plugin) {
return plugin.has(pluginType); Plugins.prototype = Object.create(EventEmitter.prototype);
});
};
module.exports = Plugins; module.exports = Plugins;

View File

@ -1,7 +1,7 @@
var utils = require('../utils/utils.js'); let utils = require('../utils/utils.js');
var RunCode = require('../core/runCode.js'); let RunCode = require('../core/runCode.js');
var Console = function(options) { let Console = function(options) {
this.plugins = options.plugins; this.plugins = options.plugins;
this.version = options.version; this.version = options.version;
}; };
@ -12,7 +12,7 @@ Console.prototype.runCode = function(code) {
Console.prototype.processEmbarkCmd = function(cmd) { Console.prototype.processEmbarkCmd = function(cmd) {
if (cmd === 'help') { if (cmd === 'help') {
var helpText = [ let helpText = [
'Welcome to Embark ' + this.version, 'Welcome to Embark ' + this.version,
'', '',
'possible commands are:', 'possible commands are:',
@ -31,21 +31,24 @@ Console.prototype.processEmbarkCmd = function(cmd) {
}; };
Console.prototype.executeCmd = function(cmd, callback) { Console.prototype.executeCmd = function(cmd, callback) {
var plugin, pluginOutput; let plugin, pluginOutput;
var plugins = this.plugins.getPluginsFor('console'); let plugins = [];
for (var i = 0; i < plugins.length; i++) { this.plugins.emit('get', 'console', (list) => {
plugins = list;
});
for (let i = 0; i < plugins.length; i++) {
plugin = plugins[i]; plugin = plugins[i];
pluginOutput = plugin.runCommands(cmd, {}); pluginOutput = plugin.runCommands(cmd, {});
if (pluginOutput !== false && pluginOutput !== 'false') return callback(pluginOutput); if (pluginOutput !== false && pluginOutput !== 'false') return callback(pluginOutput);
} }
var output = this.processEmbarkCmd(cmd); let output = this.processEmbarkCmd(cmd);
if (output) { if (output) {
return callback(output); return callback(output);
} }
try { try {
var result = RunCode.doEval(cmd); let result = RunCode.doEval(cmd);
return callback(result); return callback(result);
} }
catch(e) { catch(e) {

View File

@ -1,55 +1,54 @@
/*jshint esversion: 6 */ /*jshint esversion: 6 */
var async = require('async'); let async = require('async');
// require("./utils/debug_util.js")(__filename, async); // require("./utils/debug_util.js")(__filename, async);
var colors = require('colors'); let colors = require('colors');
var Engine = require('./core/engine.js'); let IPFS = require('./upload/ipfs.js');
let Swarm = require('./upload/swarm.js');
var IPFS = require('./upload/ipfs.js'); let EventEmitter = require('events').EventEmitter;
var Swarm = require('./upload/swarm.js'); let Config = require('./core/config');
/**
* Initialize a new `Embark` instance.
*
* @return {Embark}
* @api public
*/
var version = require('../package.json').version; let Embark = function (options) {
this.version = require('../package.json').version;
var Embark = (function () { this.env = options.environment || options.env || "development";
function initConfig (env, options) {
var Events = require('./core/events.js');
var Logger = require('./core/logger.js');
var Config = require('./core/config.js');
this.events = new Events(); this.config = new Config({env: this.env, logger: this.logger, events: this.events});
this.logger = new Logger({logLevel: 'debug'});
this.config = new Config({env: env, logger: this.logger, events: this.events});
this.config.loadConfigFiles(options); this.config.loadConfigFiles(options);
this.plugins = this.config.plugins; this.plugins = this.config.plugins;
}
function blockchain (env, client) { this.blockchain = function (env, client) {
return require('./cmds/blockchain/blockchain.js')(this.config.blockchainConfig, client, env).run(); return require('./cmds/blockchain/blockchain.js')(Embark.prototype.config.blockchainConfig, client, env).run();
} };
function simulator (options) { this.simulator = function (options) {
var Simulator = require('./cmds/simulator.js'); let Simulator = require('./cmds/simulator.js');
var simulator = new Simulator({blockchainConfig: this.config.blockchainConfig}); let simulator = new Simulator({blockchainConfig: Embark.prototype.config.blockchainConfig});
simulator.run(options); simulator.run(options);
} };
function generateTemplate (templateName, destinationFolder, name) { this.generateTemplate = function (templateName, destinationFolder, name) {
var TemplateGenerator = require('./cmds/template_generator.js'); let TemplateGenerator = require('./cmds/template_generator.js');
var templateGenerator = new TemplateGenerator(templateName); let templateGenerator = new TemplateGenerator(templateName);
templateGenerator.generate(destinationFolder, name); templateGenerator.generate(destinationFolder, name);
} };
function run (options) { this.run = function (options) {
var Dashboard = require('./dashboard/dashboard.js'); let Dashboard = require('./dashboard/dashboard.js');
let Engine = require('./core/engine');
var env = options.env; let engine = new Engine({
var engine = new Engine({
env: options.env, env: options.env,
embarkConfig: 'embark.json' embarkConfig: 'embark.json'
}); });
engine.init(); engine.init();
if (!options.useDashboard) { if (!options.useDashboard) {
@ -64,19 +63,19 @@ var Embark = (function () {
return callback(); return callback();
} }
var dashboard = new Dashboard({ let dashboard = new Dashboard({
logger: engine.logger, logger: engine.logger,
plugins: engine.plugins, plugins: engine.plugins,
version: engine.version, version: engine.version,
env: engine.env env: engine.env
}); });
dashboard.start(function () { dashboard.start(function () {
engine.events.on('abi-vanila', function(abi) { Embark.on('abi-vanila', function (abi) {
dashboard.console.runCode(abi); dashboard.console.runCode(abi);
}); });
engine.logger.info('dashboard start'); engine.logger.info('dashboard start');
engine.events.on('servicesState', function(servicesState) { Embark.on('servicesState', function (servicesState) {
dashboard.monitor.availableServices(servicesState); dashboard.monitor.availableServices(servicesState);
}); });
@ -84,7 +83,7 @@ var Embark = (function () {
}); });
}, },
function (callback) { function (callback) {
var pluginList = engine.plugins.listPlugins(); let pluginList = engine.plugins.listPlugins();
if (pluginList.length > 0) { if (pluginList.length > 0) {
engine.logger.info("loaded plugins: " + pluginList.join(", ")); engine.logger.info("loaded plugins: " + pluginList.join(", "));
} }
@ -96,7 +95,7 @@ var Embark = (function () {
engine.startService("deployment"); engine.startService("deployment");
engine.startService("ipfs"); engine.startService("ipfs");
engine.events.on('check:backOnline:Ethereum', function() { Embark.on('check:backOnline:Ethereum', function () {
engine.logger.info('Ethereum node detected..'); engine.logger.info('Ethereum node detected..');
engine.config.reloadConfig(); engine.config.reloadConfig();
engine.deployManager.deployContracts(function () { engine.deployManager.deployContracts(function () {
@ -115,21 +114,22 @@ var Embark = (function () {
callback(); callback();
}); });
} }
], function(err, result) { ], function (err) {
if (err) { if (err) {
engine.logger.error(err.message); engine.logger.error(err.message);
} else { } else {
engine.logger.setStatus("Ready".green); engine.logger.setStatus("Ready".green);
engine.logger.info("Looking for documentation? you can find it at ".cyan + "http://embark.readthedocs.io/".green.underline); engine.logger.info("Looking for documentation? you can find it at ".cyan + "http://embark.readthedocs.io/".green.underline);
engine.logger.info("Ready".underline); engine.logger.info("Ready".underline);
engine.events.emit('firstDeploymentDone'); Embark.emit('firstDeploymentDone');
} }
}); });
} };
function build (options) { this.build = function (options) {
let Engine = require('./core/engine');
var engine = new Engine({ let engine = new Engine({
env: options.env, env: options.env,
embarkConfig: 'embark.json', embarkConfig: 'embark.json',
interceptLogs: false interceptLogs: false
@ -138,7 +138,7 @@ var Embark = (function () {
async.waterfall([ async.waterfall([
function startServices(callback) { function startServices(callback) {
var pluginList = engine.plugins.listPlugins(); let pluginList = engine.plugins.listPlugins();
if (pluginList.length > 0) { if (pluginList.length > 0) {
engine.logger.info("loaded plugins: " + pluginList.join(", ")); engine.logger.info("loaded plugins: " + pluginList.join(", "));
} }
@ -153,7 +153,7 @@ var Embark = (function () {
callback(); callback();
}); });
} }
], function(err, result) { ], function (err) {
if (err) { if (err) {
engine.logger.error(err.message); engine.logger.error(err.message);
} else { } else {
@ -162,40 +162,34 @@ var Embark = (function () {
// needed due to child processes // needed due to child processes
process.exit(); process.exit();
}); });
} };
function initTests (options) { this.initTests = function (options) {
var Test = require('./core/test.js'); let Test = require('./core/test.js');
return new Test(options); return new Test(options);
} };
// TODO: should deploy if it hasn't already // TODO: should deploy if it hasn't already
function upload (platform) { this.upload = function (platform) {
if (platform === 'ipfs') { if (platform === 'ipfs') {
var ipfs = new IPFS({buildDir: 'dist/', plugins: this.plugins, storageConfig: this.config.storageConfig}); let ipfs = new IPFS({buildDir: 'dist/', plugins: Embark.prototype.plugins, storageConfig: Embark.prototype.config.storageConfig});
ipfs.deploy(); ipfs.deploy();
} else if (platform === 'swarm') { } else if (platform === 'swarm') {
var swarm = new Swarm({buildDir: 'dist/', plugins: this.plugins, storageConfig: this.config.storageConfig}); let swarm = new Swarm({buildDir: 'dist/', plugins: Embark.prototype.plugins, storageConfig: Embark.prototype.config.storageConfig});
swarm.deploy(); swarm.deploy();
} else { } else {
console.log(("unknown platform: " + platform).red); console.log(("unknown platform: " + platform).red);
console.log('try "embark upload ipfs" or "embark upload swarm"'.green); console.log('try "embark upload ipfs" or "embark upload swarm"'.green);
} }
}
return {
version: version,
initConfig: initConfig,
blockchain: blockchain,
simulator: simulator,
generateTemplate: generateTemplate,
run: run,
build: build,
initTests: initTests,
upload: upload
}; };
})(); if (!(this instanceof Embark)) {
return new Embark();
}
return this;
};
Embark.prototype = Object.create(EventEmitter.prototype);
module.exports = Embark; module.exports = Embark;

View File

@ -1,9 +1,9 @@
/*global exit */ /*global exit */
var path = require('path'); let path = require('path');
var globule = require('globule'); let globule = require('globule');
var merge = require('merge'); let merge = require('merge');
var http = require('http'); let http = require('http');
var shelljs = require('shelljs'); let shelljs = require('shelljs');
function joinPath() { function joinPath() {
return path.join.apply(path.join, arguments); return path.join.apply(path.join, arguments);
@ -30,7 +30,7 @@ function checkIsAvailable(url, callback) {
} }
function runCmd(cmd, options) { function runCmd(cmd, options) {
var result = shelljs.exec(cmd, options || {silent: true}); let result = shelljs.exec(cmd, options || {silent: true});
if (result.code !== 0) { if (result.code !== 0) {
console.log("error doing.. " + cmd); console.log("error doing.. " + cmd);
console.log(result.output); console.log(result.output);
@ -53,6 +53,7 @@ function exit(code) {
process.exit(code); process.exit(code);
} }
//TODO: Maybe desired to just `module.exports = this` ?
module.exports = { module.exports = {
joinPath: joinPath, joinPath: joinPath,
filesMatchingPattern: filesMatchingPattern, filesMatchingPattern: filesMatchingPattern,

View File

@ -31,6 +31,8 @@
"shelljs": "^0.5.0", "shelljs": "^0.5.0",
"solc": "0.4.8", "solc": "0.4.8",
"toposort": "^1.0.0", "toposort": "^1.0.0",
"underscore": "^1.8.3",
"underscore.string": "^3.3.4",
"web3": "^0.18.2" "web3": "^0.18.2"
}, },
"author": "Iuri Matias <iuri.matias@gmail.com>", "author": "Iuri Matias <iuri.matias@gmail.com>",
@ -59,5 +61,16 @@
"mocha-sinon": "^1.1.4", "mocha-sinon": "^1.1.4",
"sinon": "^1.15.4", "sinon": "^1.15.4",
"toposort": "^1.0.0" "toposort": "^1.0.0"
},
"jshintConfig": {
"indent": 2,
"white": true,
"node": true,
"undef": true,
"unused": true,
"-W058": true,
"-W014": true,
"expr": true,
"esversion": 6
} }
} }

View File

@ -32,6 +32,7 @@ describe('embark.Cmd', function () {
assert.equal(lines[2], pl[2]); assert.equal(lines[2], pl[2]);
assert.equal(lines[3], 'App ready at ./' + appname); assert.equal(lines[3], 'App ready at ./' + appname);
}); });
done();
}); });
it('it should prompt when given an empty app name', function (done) { it('it should prompt when given an empty app name', function (done) {
@ -44,8 +45,8 @@ describe('embark.Cmd', function () {
console.log(lines); console.log(lines);
sendLine(appname + '\n'); sendLine(appname + '\n');
assert.equal(lines[0], pl[0]); assert.equal(lines[0], pl[0]);
});
done(); done();
}); });
}); });
})
}); });

View File

@ -1,11 +1,10 @@
/*globals describe, it*/ /*globals describe, it*/
var Config = require('../lib/core/config.js'); let Config = require('../lib/core/config.js');
var Plugins = require('../lib/core/plugins.js'); let Plugins = require('../lib/core/plugins.js');
var assert = require('assert'); let assert = require('assert');
var fs = require('fs');
describe('embark.Config', function() { describe('embark.Config', function() {
var config = new Config({ let config = new Config({
env: 'myenv', env: 'myenv',
configDir: './test/test1/config/' configDir: './test/test1/config/'
}); });
@ -14,7 +13,7 @@ describe('embark.Config', function() {
describe('#loadBlockchainConfigFile', function() { describe('#loadBlockchainConfigFile', function() {
it('should load blockchain config correctly', function() { it('should load blockchain config correctly', function() {
config.loadBlockchainConfigFile(); config.loadBlockchainConfigFile();
var expectedConfig = { let expectedConfig = {
"enabled": true, "enabled": true,
"networkType": "custom", "networkType": "custom",
"genesisBlock": "config/development/genesis.json", "genesisBlock": "config/development/genesis.json",
@ -36,7 +35,7 @@ describe('embark.Config', function() {
describe('#loadContractsConfigFile', function() { describe('#loadContractsConfigFile', function() {
it('should load contract config correctly', function() { it('should load contract config correctly', function() {
config.loadContractsConfigFile(); config.loadContractsConfigFile();
var expectedConfig = { let expectedConfig = {
"gas": "auto", "gas": "auto",
"contracts": { "contracts": {
"SimpleStorage": { "SimpleStorage": {