From 67f325f5a0cdf4f7c6566b4268b60aa6f5284dd9 Mon Sep 17 00:00:00 2001 From: Todd Baur Date: Thu, 30 Mar 2017 20:12:39 +0900 Subject: [PATCH] migrate all the code to ES6 --- lib/cmd.js | 290 ++++++------- lib/cmds/blockchain/blockchain.js | 156 +++---- lib/cmds/blockchain/geth_commands.js | 278 ++++++------ lib/cmds/simulator.js | 22 +- lib/cmds/template_generator.js | 54 +-- lib/contracts/abi.js | 181 ++++---- lib/contracts/compiler.js | 178 ++++---- lib/contracts/contracts.js | 428 +++++++++---------- lib/contracts/deploy.js | 280 ++++++------ lib/contracts/deploy_manager.js | 154 +++---- lib/contracts/deploy_tracker.js | 94 +++-- lib/contracts/solcP.js | 4 +- lib/contracts/solcW.js | 52 +-- lib/core/config.js | 137 +++--- lib/core/core.js | 4 +- lib/core/engine.js | 110 ++--- lib/core/events.js | 10 +- lib/core/fs.js | 2 +- lib/core/logger.js | 49 ++- lib/core/plugin.js | 128 +++--- lib/core/plugins.js | 87 ++-- lib/core/runCode.js | 2 +- lib/core/services_monitor.js | 43 +- lib/core/test.js | 88 +--- lib/core/test_logger.js | 87 ++-- lib/dashboard/command_history.js | 47 ++- lib/dashboard/console.js | 104 ++--- lib/dashboard/dashboard.js | 65 +-- lib/dashboard/monitor.js | 608 ++++++++++++++------------- lib/index.js | 312 +++++++------- lib/pipeline/pipeline.js | 129 +++--- lib/pipeline/server.js | 33 +- lib/pipeline/watch.js | 171 ++++---- lib/upload/ipfs.js | 88 ++-- lib/upload/swarm.js | 84 ++-- lib/utils/async_extend.js | 3 +- lib/utils/debug_util.js | 6 +- lib/utils/utils.js | 4 +- test/blockchain.js | 49 ++- test/contracts.js | 2 +- 40 files changed, 2349 insertions(+), 2274 deletions(-) diff --git a/lib/cmd.js b/lib/cmd.js index b92e0043f..024af9cb4 100644 --- a/lib/cmd.js +++ b/lib/cmd.js @@ -5,164 +5,166 @@ let promptly = require('promptly'); let path = require('path'); let Embark = require('../lib/index'); -let Cmd = function() { - program.version(Embark.version); -}; - - -Cmd.prototype.process = function(args) { - this.newApp(); - this.demo(); - this.build(); - this.run(); - this.blockchain(); - this.simulator(); - this.test(); - this.upload(); - this.otherCommands(); - - //If no arguments are passed display help by default - if (!process.argv.slice(2).length) { - program.help(); +class Cmd { + constructor() { + program.version(Embark.version); } - - program.parse(args); -}; -Cmd.prototype.newApp = function(name) { + process(args) { + this.newApp(); + this.demo(); + this.build(); + this.run(); + this.blockchain(); + this.simulator(); + this.test(); + this.upload(); + this.otherCommands(); - let validateName = function (value) { - try { - if(value.match(/^[a-zA-Z\s\-]+$/)) return value; - } catch (e) { - throw new Error('Name must be only letters, spaces, or dashes'); + //If no arguments are passed display help by default + if (!process.argv.slice(2).length) { + program.help(); } - }; - program - .command('new [name]') - .description('new application') - .action(function (name) { - if (name === undefined) { - let parentDirectory = path.dirname(__dirname).split("/").pop(); - return promptly.prompt("Name your app (default is " + parentDirectory + "):", { - default: parentDirectory, - validator: validateName - }, function (err, inputvalue) { - if (err) { - console.error('Invalid name:', err.message); - // Manually call retry - // The passed error has a retry method to easily prompt again. - err.retry(); - } else { - //slightly different assignment of name since it comes from child prompt - Embark.generateTemplate('boilerplate', './', inputvalue); - } - }); - } else { - Embark.generateTemplate('boilerplate', './', name); + program.parse(args); + } + + newApp(name) { + + let validateName = function (value) { + try { + if (value.match(/^[a-zA-Z\s\-]+$/)) return value; + } catch (e) { + throw new Error('Name must be only letters, spaces, or dashes'); } + }; - }); -}; + program + .command('new [name]') + .description('new application') + .action(function (name) { + if (name === undefined) { + let parentDirectory = path.dirname(__dirname).split("/").pop(); + return promptly.prompt("Name your app (default is " + parentDirectory + "):", { + default: parentDirectory, + validator: validateName + }, function (err, inputvalue) { + if (err) { + console.error('Invalid name:', err.message); + // Manually call retry + // The passed error has a retry method to easily prompt again. + err.retry(); + } else { + //slightly different assignment of name since it comes from child prompt + Embark.generateTemplate('boilerplate', './', inputvalue); + } + }); + } else { + Embark.generateTemplate('boilerplate', './', name); + } -Cmd.prototype.demo = function() { - program - .command('demo') - .description('create a working dapp with a SimpleStorage contract') - .action(function() { - Embark.generateTemplate('demo', './', 'embark_demo'); - }); -}; + }); + } -Cmd.prototype.build = function() { - program - .command('build [environment]') - .description('deploy and build dapp at dist/ (default: development)') - .action(function(env, options) { - Embark.build({env: env || 'development'}); - }); -}; + demo() { + program + .command('demo') + .description('create a working dapp with a SimpleStorage contract') + .action(function () { + Embark.generateTemplate('demo', './', 'embark_demo'); + }); + } -Cmd.prototype.run = function() { - program - .command('run [environment]') - .option('-p, --port [port]', 'port to run the dev webserver (default: 8000)') - .option('-b, --host [host]', 'host to run the dev webserver (default: localhost)') - .option('--noserver', 'disable the development webserver') - .option('--nodashboard', 'simple mode, disables the dashboard') - .option('--no-color', 'no colors in case it\'s needed for compatbility purposes') - .description('run dapp (default: development)') - .action(function(env, options) { - Embark.run({ - env: env || 'development', - serverPort: options.port, - serverHost: options.host, - runWebserver: !options.noserver, - useDashboard: !options.nodashboard - }); - }); -}; + build() { + program + .command('build [environment]') + .description('deploy and build dapp at dist/ (default: development)') + .action(function (env, options) { + Embark.build({env: env || 'development'}); + }); + } -Cmd.prototype.blockchain = function() { - program - .command('blockchain [environment]') - .option('-c, --client [client]', 'Use a specific ethereum client or simulator (supported: geth, parity, ethersim, testrpc') - .description('run blockchain server (default: development)') - .action(function(env ,options) { - Embark.initConfig(env || 'development', { - embarkConfig: 'embark.json', - interceptLogs: false - }); - Embark.blockchain(env || 'development', options.client || 'geth'); - }); -}; + run() { + program + .command('run [environment]') + .option('-p, --port [port]', 'port to run the dev webserver (default: 8000)') + .option('-b, --host [host]', 'host to run the dev webserver (default: localhost)') + .option('--noserver', 'disable the development webserver') + .option('--nodashboard', 'simple mode, disables the dashboard') + .option('--no-color', 'no colors in case it\'s needed for compatbility purposes') + .description('run dapp (default: development)') + .action(function (env, options) { + Embark.run({ + env: env || 'development', + serverPort: options.port, + serverHost: options.host, + runWebserver: !options.noserver, + useDashboard: !options.nodashboard + }); + }); + } -Cmd.prototype.simulator = function() { - program - .command('simulator [environment]') - .description('run a fast ethereum rpc simulator') - .option('--testrpc', 'use testrpc as the rpc simulator [default]') - .option('-p, --port [port]', 'port to run the rpc simulator (default: 8000)') - .option('-h, --host [host]', 'host to run the rpc simulator (default: localhost)') - .action(function(env, options) { - Embark.initConfig(env || 'development', { - embarkConfig: 'embark.json', - interceptLogs: false - }); - Embark.simulator({port: options.port, host: options.host}); - }); -}; + blockchain() { + program + .command('blockchain [environment]') + .option('-c, --client [client]', 'Use a specific ethereum client or simulator (supported: geth, parity, ethersim, testrpc') + .description('run blockchain server (default: development)') + .action(function (env, options) { + Embark.initConfig(env || 'development', { + embarkConfig: 'embark.json', + interceptLogs: false + }); + Embark.blockchain(env || 'development', options.client || 'geth'); + }); + } -Cmd.prototype.test = function() { - program - .command('test') - .description('run tests') - .action(function() { - shelljs.exec('mocha test'); - }); -}; + simulator() { + program + .command('simulator [environment]') + .description('run a fast ethereum rpc simulator') + .option('--testrpc', 'use testrpc as the rpc simulator [default]') + .option('-p, --port [port]', 'port to run the rpc simulator (default: 8000)') + .option('-h, --host [host]', 'host to run the rpc simulator (default: localhost)') + .action(function (env, options) { + Embark.initConfig(env || 'development', { + embarkConfig: 'embark.json', + interceptLogs: false + }); + Embark.simulator({port: options.port, host: options.host}); + }); + } -Cmd.prototype.upload = function() { - program - .command('upload [platform] [environment]') - .description('upload your dapp to a decentralized storage. possible options: ipfs, swarm (e.g embark upload swarm)') - .action(function(platform, env, options) { - // TODO: get env in cmd line as well - Embark.initConfig(env || 'development', { - embarkConfig: 'embark.json', interceptLogs: false - }); - Embark.upload(platform); - }); -}; + test() { + program + .command('test') + .description('run tests') + .action(function () { + shelljs.exec('mocha test'); + }); + } -Cmd.prototype.otherCommands = function() { - program - .action(function(env){ - console.log('unknown command "%s"'.red, env); - console.log("type embark --help to see the available commands"); - process.exit(0); - }); -}; + upload() { + program + .command('upload [platform] [environment]') + .description('upload your dapp to a decentralized storage. possible options: ipfs, swarm (e.g embark upload swarm)') + .action(function (platform, env, options) { + // TODO: get env in cmd line as well + Embark.initConfig(env || 'development', { + embarkConfig: 'embark.json', interceptLogs: false + }); + Embark.upload(platform); + }); + } + + otherCommands() { + program + .action(function (env) { + console.log('unknown command "%s"'.red, env); + console.log("type embark --help to see the available commands"); + process.exit(0); + }); + } + +} module.exports = Cmd; diff --git a/lib/cmds/blockchain/blockchain.js b/lib/cmds/blockchain/blockchain.js index 949198c55..06bfdd190 100644 --- a/lib/cmds/blockchain/blockchain.js +++ b/lib/cmds/blockchain/blockchain.js @@ -5,83 +5,6 @@ let fs = require('../../core/fs.js'); let GethCommands = require('./geth_commands.js'); -/*eslint complexity: ["error", 22]*/ -let Blockchain = function(options) { - this.blockchainConfig = options.blockchainConfig; - this.env = options.env || 'development'; - this.client = options.client; - - this.config = { - geth_bin: this.blockchainConfig.geth_bin || 'geth', - networkType: this.blockchainConfig.networkType || 'custom', - genesisBlock: this.blockchainConfig.genesisBlock || false, - datadir: this.blockchainConfig.datadir || false, - mineWhenNeeded: this.blockchainConfig.mineWhenNeeded || false, - rpcHost: this.blockchainConfig.rpcHost || 'localhost', - rpcPort: this.blockchainConfig.rpcPort || 8545, - rpcCorsDomain: this.blockchainConfig.rpcCorsDomain || false, - networkId: this.blockchainConfig.networkId || 12301, - port: this.blockchainConfig.port || 30303, - nodiscover: this.blockchainConfig.nodiscover || false, - mine: this.blockchainConfig.mine || false, - account: this.blockchainConfig.account || {}, - whisper: (this.blockchainConfig.whisper === undefined) || this.blockchainConfig.whisper, - maxpeers: ((this.blockchainConfig.maxpeers === 0) ? 0 : (this.blockchainConfig.maxpeers || 25)), - bootnodes: this.blockchainConfig.bootnodes || "", - rpcApi: (this.blockchainConfig.rpcApi || ['eth', 'web3', 'net']), - vmdebug: this.blockchainConfig.vmdebug || false - }; - - this.client = new options.client({config: this.config, env: this.env}); -}; - -Blockchain.prototype.runCommand = function(cmd) { - console.log(("running: " + cmd.underline).green); - return shelljs.exec(cmd); -}; - -Blockchain.prototype.run = function() { - let self = this; - console.log("===============================================================================".magenta); - console.log("===============================================================================".magenta); - console.log(("Embark Blockchain Using: " + this.client.name.underline).magenta); - console.log("===============================================================================".magenta); - console.log("===============================================================================".magenta); - let address = this.initChainAndGetAddress(); - this.client.mainCommand(address, function(cmd) { - self.runCommand(cmd); - }); -}; - -Blockchain.prototype.initChainAndGetAddress = function() { - let address = null, result; - - // ensure datadir exists, bypassing the interactive liabilities prompt. - this.datadir = '.embark/' + this.env + '/datadir'; - fs.mkdirpSync(this.datadir); - - // copy mining script - fs.copySync(fs.embarkPath("js"), ".embark/" + this.env + "/js", {overwrite: true}); - - // check if an account already exists, create one if not, return address - result = this.runCommand(this.client.listAccountsCommand()); - if (result.output === undefined || result.output === '' || result.output.indexOf("Fatal") >= 0) { - console.log("no accounts found".green); - if (this.config.genesisBlock) { - console.log("initializing genesis block".green); - result = this.runCommand(this.client.initGenesisCommmand()); - } - - result = this.runCommand(this.client.newAccountCommand()); - address = result.output.match(/{(\w+)}/)[1]; - } else { - console.log("already initialized".green); - address = result.output.match(/{(\w+)}/)[1]; - } - - return address; -}; - let BlockchainClient = function(blockchainConfig, client, env) { if (client === 'geth') { return new Blockchain({blockchainConfig: blockchainConfig, client: GethCommands, env: env}); @@ -90,5 +13,82 @@ let BlockchainClient = function(blockchainConfig, client, env) { } }; -module.exports = BlockchainClient; +/*eslint complexity: ["error", 22]*/ +class Blockchain { + constructor(options) { + this.blockchainConfig = options.blockchainConfig; + this.env = options.env || 'development'; + this.client = BlockchainClient(this.blockchainConfig, 'geth', this.env); + + this.config = { + geth_bin: this.blockchainConfig.geth_bin || 'geth', + networkType: this.blockchainConfig.networkType || 'custom', + genesisBlock: this.blockchainConfig.genesisBlock || false, + datadir: this.blockchainConfig.datadir || false, + mineWhenNeeded: this.blockchainConfig.mineWhenNeeded || false, + rpcHost: this.blockchainConfig.rpcHost || 'localhost', + rpcPort: this.blockchainConfig.rpcPort || 8545, + rpcCorsDomain: this.blockchainConfig.rpcCorsDomain || false, + networkId: this.blockchainConfig.networkId || 12301, + port: this.blockchainConfig.port || 30303, + nodiscover: this.blockchainConfig.nodiscover || false, + mine: this.blockchainConfig.mine || false, + account: this.blockchainConfig.account || {}, + whisper: (this.blockchainConfig.whisper === undefined) || this.blockchainConfig.whisper, + maxpeers: ((this.blockchainConfig.maxpeers === 0) ? 0 : (this.blockchainConfig.maxpeers || 25)), + bootnodes: this.blockchainConfig.bootnodes || "", + rpcApi: (this.blockchainConfig.rpcApi || ['eth', 'web3', 'net']), + vmdebug: this.blockchainConfig.vmdebug || false + }; + } + + static runCommand(cmd) { + console.log(("running: " + cmd.underline).green); + return shelljs.exec(cmd); + } + + run() { + let self = this; + console.log("===============================================================================".magenta); + console.log("===============================================================================".magenta); + console.log(("Embark Blockchain Using: " + this.client.name.underline).magenta); + console.log("===============================================================================".magenta); + console.log("===============================================================================".magenta); + let address = this.initChainAndGetAddress(); + this.client.mainCommand(address, function (cmd) { + self.runCommand(cmd); + }); + } + + initChainAndGetAddress() { + let address = null, result; + + // ensure datadir exists, bypassing the interactive liabilities prompt. + this.datadir = '.embark/' + this.env + '/datadir'; + fs.mkdirpSync(this.datadir); + + // copy mining script + fs.copySync(fs.embarkPath("js"), ".embark/" + this.env + "/js", {overwrite: true}); + + // check if an account already exists, create one if not, return address + result = this.runCommand(this.client.listAccountsCommand()); + if (result.output === undefined || result.output === '' || result.output.indexOf("Fatal") >= 0) { + console.log("no accounts found".green); + if (this.config.genesisBlock) { + console.log("initializing genesis block".green); + result = this.runCommand(this.client.initGenesisCommmand()); + } + + result = this.runCommand(this.client.newAccountCommand()); + address = result.output.match(/{(\w+)}/)[1]; + } else { + console.log("already initialized".green); + address = result.output.match(/{(\w+)}/)[1]; + } + + return address; + } +} + +module.exports = Blockchain; diff --git a/lib/cmds/blockchain/geth_commands.js b/lib/cmds/blockchain/geth_commands.js index d6b1e4c5d..bc0b7250c 100644 --- a/lib/cmds/blockchain/geth_commands.js +++ b/lib/cmds/blockchain/geth_commands.js @@ -1,164 +1,166 @@ let async = require('async'); // TODO: make all of this async -let GethCommands = function(options) { - this.config = options.config; - this.env = options.env || 'development'; - this.name = "Go-Ethereum (https://github.com/ethereum/go-ethereum)"; - this.geth_bin = this.config.geth_bin || "geth"; -}; - -GethCommands.prototype.commonOptions = function() { - let config = this.config; - let cmd = ""; - - cmd += this.determineNetworkType(config); - - if (config.datadir) { - cmd += "--datadir=\"" + config.datadir + "\" "; +class GethCommands { + constructor(options) { + this.config = options.config; + this.env = options.env || 'development'; + this.name = "Go-Ethereum (https://github.com/ethereum/go-ethereum)"; + this.geth_bin = this.config.geth_bin || "geth"; } - if (config.light) { - cmd += "--light "; + commonOptions() { + let config = this.config; + let cmd = ""; + + cmd += this.determineNetworkType(config); + + if (config.datadir) { + cmd += "--datadir=\"" + config.datadir + "\" "; + } + + if (config.light) { + cmd += "--light "; + } + + if (config.fast) { + cmd += "--fast "; + } + + if (config.account && config.account.password) { + cmd += "--password " + config.account.password + " "; + } + + return cmd; } - if (config.fast) { - cmd += "--fast "; + determineNetworkType(config) { + let cmd = ""; + if (config.networkType === 'testnet') { + cmd += "--testnet "; + } else if (config.networkType === 'olympic') { + cmd += "--olympic "; + } else if (config.networkType === 'custom') { + cmd += "--networkid " + config.networkId + " "; + } + return cmd; } - if (config.account && config.account.password) { - cmd += "--password " + config.account.password + " "; + initGenesisCommmand() { + let config = this.config; + let cmd = this.geth_bin + " " + this.commonOptions(); + + if (config.genesisBlock) { + cmd += "init \"" + config.genesisBlock + "\" "; + } + + return cmd; } - return cmd; -}; - -GethCommands.prototype.determineNetworkType = function(config) { - let cmd = ""; - if (config.networkType === 'testnet') { - cmd += "--testnet "; - } else if (config.networkType === 'olympic') { - cmd += "--olympic "; - } else if (config.networkType === 'custom') { - cmd += "--networkid " + config.networkId + " "; - } - return cmd; -}; - -GethCommands.prototype.initGenesisCommmand = function() { - let config = this.config; - let cmd = this.geth_bin + " " + this.commonOptions(); - - if (config.genesisBlock) { - cmd += "init \"" + config.genesisBlock + "\" "; + newAccountCommand() { + return this.geth_bin + " " + this.commonOptions() + "account new "; } - return cmd; -}; + listAccountsCommand() { + return this.geth_bin + " " + this.commonOptions() + "account list "; + } -GethCommands.prototype.newAccountCommand = function() { - return this.geth_bin + " " + this.commonOptions() + "account new "; -}; + determineRpcOptions(config) { + let cmd = ""; -GethCommands.prototype.listAccountsCommand = function() { - return this.geth_bin + " " + this.commonOptions() + "account list "; -}; - -GethCommands.prototype.determineRpcOptions = function(config) { - let cmd = ""; - - cmd += "--port " + config.port + " "; - cmd += "--rpc "; - cmd += "--rpcport " + config.rpcPort + " "; - cmd += "--rpcaddr " + config.rpcHost + " "; - if (config.rpcCorsDomain) { - if (config.rpcCorsDomain === '*') { + cmd += "--port " + config.port + " "; + cmd += "--rpc "; + cmd += "--rpcport " + config.rpcPort + " "; + cmd += "--rpcaddr " + config.rpcHost + " "; + if (config.rpcCorsDomain) { + if (config.rpcCorsDomain === '*') { + console.log('=================================='); + console.log('make sure you know what you are doing'); + console.log('=================================='); + } + cmd += "--rpccorsdomain=\"" + config.rpcCorsDomain + "\" "; + } else { console.log('=================================='); - console.log('make sure you know what you are doing'); + console.log('warning: cors is not set'); console.log('=================================='); } - cmd += "--rpccorsdomain=\"" + config.rpcCorsDomain + "\" "; - } else { - console.log('=================================='); - console.log('warning: cors is not set'); - console.log('=================================='); + + return cmd; } - return cmd; -}; + mainCommand(address, done) { + let self = this; + let config = this.config; + let rpc_api = (this.config.rpcApi || ['eth', 'web3', 'net']); -GethCommands.prototype.mainCommand = function(address, done) { - let self = this; - let config = this.config; - let rpc_api = (this.config.rpcApi || ['eth', 'web3', 'net']); - - async.series([ - function commonOptions(callback) { - let cmd = self.commonOptions(); - callback(null, cmd); - }, - function rpcOptions(callback) { - let cmd = self.determineRpcOptions(self.config); - callback(null, cmd); - }, - function dontGetPeers(callback) { - if (config.nodiscover) { - return callback(null, "--nodiscover"); + async.series([ + function commonOptions(callback) { + let cmd = self.commonOptions(); + callback(null, cmd); + }, + function rpcOptions(callback) { + let cmd = self.determineRpcOptions(self.config); + callback(null, cmd); + }, + function dontGetPeers(callback) { + if (config.nodiscover) { + return callback(null, "--nodiscover"); + } + callback(null, ""); + }, + function vmDebug(callback) { + if (config.vmdebug) { + return callback(null, "--vmdebug"); + } + callback(null, ""); + }, + function maxPeers(callback) { + let cmd = "--maxpeers " + config.maxpeers; + callback(null, cmd); + }, + function mining(callback) { + if (config.mineWhenNeeded || config.mine) { + return callback(null, "--mine "); + } + callback(""); + }, + function bootnodes(callback) { + if (config.bootnodes && config.bootnodes !== "" && config.bootnodes !== []) { + return callback(null, "--bootnodes " + config.bootnodes); + } + callback(""); + }, + function whisper(callback) { + if (config.whisper) { + rpc_api.push('shh'); + return callback(null, "--shh "); + } + callback(""); + }, + function rpcApi(callback) { + callback(null, '--rpcapi "' + rpc_api.join(',') + '"'); + }, + function accountToUnlock(callback) { + let accountAddress = config.account.address || address; + if (accountAddress) { + return callback(null, "--unlock=" + accountAddress); + } + callback(null, ""); + }, + function mineWhenNeeded(callback) { + if (config.mineWhenNeeded) { + return callback(null, "js .embark/" + self.env + "/js/mine.js"); + } + callback(null, ""); } - callback(null, ""); - }, - function vmDebug(callback) { - if (config.vmdebug) { - return callback(null, "--vmdebug"); + ], function (err, results) { + if (err) { + throw new Error(err.message); } - callback(null, ""); - }, - function maxPeers(callback) { - let cmd = "--maxpeers " + config.maxpeers; - callback(null, cmd); - }, - function mining(callback) { - if (config.mineWhenNeeded || config.mine) { - return callback(null, "--mine "); - } - callback(""); - }, - function bootnodes(callback) { - if (config.bootnodes && config.bootnodes !== "" && config.bootnodes !== []) { - return callback(null, "--bootnodes " + config.bootnodes); - } - callback(""); - }, - function whisper(callback) { - if (config.whisper) { - rpc_api.push('shh'); - return callback(null, "--shh "); - } - callback(""); - }, - function rpcApi(callback) { - callback(null, '--rpcapi "' + rpc_api.join(',') + '"'); - }, - function accountToUnlock(callback) { - let accountAddress = config.account.address || address; - if (accountAddress) { - return callback(null, "--unlock=" + accountAddress); - } - callback(null, ""); - }, - function mineWhenNeeded(callback) { - if (config.mineWhenNeeded) { - return callback(null, "js .embark/" + self.env + "/js/mine.js"); - } - callback(null, ""); - } - ], function(err, results) { - if (err) { - throw new Error(err.message); - } - done(self.geth_bin + " " + results.join(" ")); - }); -}; + done(self.geth_bin + " " + results.join(" ")); + }); + } +} module.exports = GethCommands; diff --git a/lib/cmds/simulator.js b/lib/cmds/simulator.js index 6a9adde86..fdfeebeed 100644 --- a/lib/cmds/simulator.js +++ b/lib/cmds/simulator.js @@ -1,18 +1,20 @@ let shelljs = require('shelljs'); -let Simulator = function(options) { - this.blockchainConfig = options.blockchainConfig; -}; +class Simulator { + constructor(options) { + this.blockchainConfig = options.blockchainConfig; + } -Simulator.prototype.run = function(options) { - let cmds = []; + run(options) { + let cmds = []; - cmds.push("-p " + (this.blockchainConfig.rpcPort || options.port || 8545)); - cmds.push("-h " + (this.blockchainConfig.rpcHost || options.host || 'localhost')); - cmds.push("-a " + (options.num || 10)); + cmds.push("-p " + (this.blockchainConfig.rpcPort || options.port || 8545)); + cmds.push("-h " + (this.blockchainConfig.rpcHost || options.host || 'localhost')); + cmds.push("-a " + (options.num || 10)); - shelljs.exec('testrpc ' + cmds.join(' ')); -}; + shelljs.exec('testrpc ' + cmds.join(' ')); + } +} module.exports = Simulator; diff --git a/lib/cmds/template_generator.js b/lib/cmds/template_generator.js index d2355a34d..e906ceb28 100644 --- a/lib/cmds/template_generator.js +++ b/lib/cmds/template_generator.js @@ -1,32 +1,34 @@ let fs = require('../core/fs.js'); let utils = require('../utils/utils.js'); -let TemplateGenerator = function(templateName) { - this.templateName = templateName; -}; - -TemplateGenerator.prototype.generate = function(destinationFolder, name) { - let templatePath = fs.embarkPath(this.templateName); - console.log('Initializing Embark Template....'.green); - - fs.copySync(templatePath, destinationFolder + name); - utils.cd(destinationFolder + name); - utils.sed('package.json', '%APP_NAME%', name); - - console.log('Installing packages.. this can take a few seconds'.green); - utils.runCmd('npm install'); - console.log('Init complete'.green); - console.log('\nApp ready at '.green + destinationFolder + name); - - if (name === 'embark_demo') { - console.log('-------------------'.yellow); - console.log('Next steps:'.green); - console.log(('-> ' + ('cd ' + destinationFolder + name).bold.cyan).green); - console.log('-> '.green + 'embark blockchain'.bold.cyan + ' or '.green + 'embark simulator'.bold.cyan); - console.log('open another console in the same directory and run'.green); - console.log('-> '.green + 'embark run'.bold.cyan); - console.log('For more info go to http://github.com/iurimatias/embark-framework'.green); +class TemplateGenerator { + constuctor(templateName) { + this.templateName = templateName; } -}; + + generate(destinationFolder, name) { + let templatePath = fs.embarkPath(this.templateName); + console.log('Initializing Embark Template....'.green); + + fs.copySync(templatePath, destinationFolder + name); + utils.cd(destinationFolder + name); + utils.sed('package.json', '%APP_NAME%', name); + + console.log('Installing packages.. this can take a few seconds'.green); + utils.runCmd('npm install'); + console.log('Init complete'.green); + console.log('\nApp ready at '.green + destinationFolder + name); + + if (name === 'embark_demo') { + console.log('-------------------'.yellow); + console.log('Next steps:'.green); + console.log(('-> ' + ('cd ' + destinationFolder + name).bold.cyan).green); + console.log('-> '.green + 'embark blockchain'.bold.cyan + ' or '.green + 'embark simulator'.bold.cyan); + console.log('open another console in the same directory and run'.green); + console.log('-> '.green + 'embark run'.bold.cyan); + console.log('For more info go to http://github.com/iurimatias/embark-framework'.green); + } + } +} module.exports = TemplateGenerator; diff --git a/lib/contracts/abi.js b/lib/contracts/abi.js index bede90dcd..b167f618c 100644 --- a/lib/contracts/abi.js +++ b/lib/contracts/abi.js @@ -1,117 +1,118 @@ - -let ABIGenerator = function(options) { - this.blockchainConfig = options.blockchainConfig || {}; - this.storageConfig = options.storageConfig || {}; - this.communicationConfig = options.communicationConfig || {}; - this.contractsManager = options.contractsManager; - this.rpcHost = options.blockchainConfig && options.blockchainConfig.rpcHost; - this.rpcPort = options.blockchainConfig && options.blockchainConfig.rpcPort; - this.plugins = options.plugins; -}; - -ABIGenerator.prototype.generateProvider = function() { - let self = this; - let result = ""; - let providerPlugins; - - if (self.blockchainConfig === {} || self.blockchainConfig.enabled === false) { - return ""; +class ABIGenerator { + constructor(options) { + this.blockchainConfig = options.blockchainConfig || {}; + this.storageConfig = options.storageConfig || {}; + this.communicationConfig = options.communicationConfig || {}; + this.contractsManager = options.contractsManager; + this.rpcHost = options.blockchainConfig && options.blockchainConfig.rpcHost; + this.rpcPort = options.blockchainConfig && options.blockchainConfig.rpcPort; + this.plugins = options.plugins; } - if (this.plugins) { - providerPlugins = this.plugins.getPluginsFor('clientWeb3Provider'); + generateProvider() { + let self = this; + let result = ""; + let providerPlugins; + + if (self.blockchainConfig === {} || self.blockchainConfig.enabled === false) { + return ""; + } + + if (this.plugins) { + providerPlugins = this.plugins.getPluginsFor('clientWeb3Provider'); + } + + if (this.plugins && providerPlugins.length > 0) { + providerPlugins.forEach(function (plugin) { + result += plugin.generateProvider(self) + "\n"; + }); + } else { + result += "\nif (typeof web3 !== 'undefined' && typeof Web3 !== 'undefined') {"; + result += '\n\tweb3 = new Web3(web3.currentProvider);'; + result += "\n} else if (typeof Web3 !== 'undefined') {"; + result += '\n\tweb3 = new Web3(new Web3.providers.HttpProvider("http://' + this.rpcHost + ':' + this.rpcPort + '"));'; + result += '\n}'; + result += "\nweb3.eth.defaultAccount = web3.eth.accounts[0];"; + } + + return result; } - if (this.plugins && providerPlugins.length > 0) { - providerPlugins.forEach(function(plugin) { - result += plugin.generateProvider(self) + "\n"; - }); - } else { - result += "\nif (typeof web3 !== 'undefined' && typeof Web3 !== 'undefined') {"; - result += '\n\tweb3 = new Web3(web3.currentProvider);'; - result += "\n} else if (typeof Web3 !== 'undefined') {"; - result += '\n\tweb3 = new Web3(new Web3.providers.HttpProvider("http://' + this.rpcHost + ':' + this.rpcPort + '"));'; - result += '\n}'; - result += "\nweb3.eth.defaultAccount = web3.eth.accounts[0];"; - } + generateContracts(useEmbarkJS) { + let self = this; + let result = "\n"; + let contractsPlugins; - return result; -}; + if (self.blockchainConfig === {} || self.blockchainConfig.enabled === false) { + return ""; + } -ABIGenerator.prototype.generateContracts = function(useEmbarkJS) { - let self = this; - let result = "\n"; - let contractsPlugins; + if (this.plugins) { + contractsPlugins = this.plugins.getPluginsFor('contractGeneration'); + } - if (self.blockchainConfig === {} || self.blockchainConfig.enabled === false) { - return ""; - } + if (this.plugins && contractsPlugins.length > 0) { + contractsPlugins.forEach(function (plugin) { + result += plugin.generateContracts({contracts: self.contractsManager.contracts}); + }); + } else { + for (let className in this.contractsManager.contracts) { + let contract = this.contractsManager.contracts[className]; - if (this.plugins) { - contractsPlugins = this.plugins.getPluginsFor('contractGeneration'); - } + let abi = JSON.stringify(contract.abiDefinition); + let gasEstimates = JSON.stringify(contract.gasEstimates); - if (this.plugins && contractsPlugins.length > 0) { - contractsPlugins.forEach(function(plugin) { - result += plugin.generateContracts({contracts: self.contractsManager.contracts}); - }); - } else { - for(let className in this.contractsManager.contracts) { - let contract = this.contractsManager.contracts[className]; - - let abi = JSON.stringify(contract.abiDefinition); - let gasEstimates = JSON.stringify(contract.gasEstimates); - - if (useEmbarkJS) { - result += "\n" + className + " = new EmbarkJS.Contract({abi: " + abi + ", address: '" + contract.deployedAddress + "', code: '" + contract.code + "', gasEstimates: " + gasEstimates + "});"; - } else { - result += "\n" + className + "Abi = " + abi + ";"; - result += "\n" + className + "Contract = web3.eth.contract(" + className + "Abi);"; - result += "\n" + className + " = " + className + "Contract.at('" + contract.deployedAddress + "');"; + if (useEmbarkJS) { + result += "\n" + className + " = new EmbarkJS.Contract({abi: " + abi + ", address: '" + contract.deployedAddress + "', code: '" + contract.code + "', gasEstimates: " + gasEstimates + "});"; + } else { + result += "\n" + className + "Abi = " + abi + ";"; + result += "\n" + className + "Contract = web3.eth.contract(" + className + "Abi);"; + result += "\n" + className + " = " + className + "Contract.at('" + contract.deployedAddress + "');"; + } } } + + return result; } - return result; -}; + generateStorageInitialization(useEmbarkJS) { + let self = this; + let result = "\n"; -ABIGenerator.prototype.generateStorageInitialization = function(useEmbarkJS) { - let self = this; - let result = "\n"; + if (!useEmbarkJS || self.storageConfig === {}) return ""; - if (!useEmbarkJS || self.storageConfig === {}) return ""; + if (self.storageConfig.provider === 'ipfs' && self.storageConfig.enabled === true) { + result += "\nEmbarkJS.Storage.setProvider('" + self.storageConfig.provider + "', {server: '" + self.storageConfig.host + "', port: '" + self.storageConfig.port + "'});"; + } - if (self.storageConfig.provider === 'ipfs' && self.storageConfig.enabled === true) { - result += "\nEmbarkJS.Storage.setProvider('" + self.storageConfig.provider + "', {server: '" + self.storageConfig.host + "', port: '" + self.storageConfig.port + "'});"; + return result; } - return result; -}; + generateCommunicationInitialization(useEmbarkJS) { + let self = this; + let result = "\n"; -ABIGenerator.prototype.generateCommunicationInitialization = function(useEmbarkJS) { - let self = this; - let result = "\n"; + if (!useEmbarkJS || self.communicationConfig === {}) return ""; - if (!useEmbarkJS || self.communicationConfig === {}) return ""; + if (self.communicationConfig.provider === 'whisper' && self.communicationConfig.enabled === true) { + result += "\nEmbarkJS.Messages.setProvider('" + self.communicationConfig.provider + "');"; + } else if (self.communicationConfig.provider === 'orbit' && self.communicationConfig.enabled === true) { + result += "\nEmbarkJS.Messages.setProvider('" + self.communicationConfig.provider + "', {server: '" + self.communicationConfig.host + "', port: '" + self.communicationConfig.port + "'});"; + } - if (self.communicationConfig.provider === 'whisper' && self.communicationConfig.enabled === true) { - result += "\nEmbarkJS.Messages.setProvider('" + self.communicationConfig.provider + "');"; - } else if (self.communicationConfig.provider === 'orbit' && self.communicationConfig.enabled === true) { - result += "\nEmbarkJS.Messages.setProvider('" + self.communicationConfig.provider + "', {server: '" + self.communicationConfig.host + "', port: '" + self.communicationConfig.port + "'});"; + return result; } - return result; -}; + generateABI(options) { + let result = ""; -ABIGenerator.prototype.generateABI = function(options) { - let result = ""; + result += this.generateProvider(); + result += this.generateContracts(options.useEmbarkJS); + result += this.generateStorageInitialization(options.useEmbarkJS); + result += this.generateCommunicationInitialization(options.useEmbarkJS); - result += this.generateProvider(); - result += this.generateContracts(options.useEmbarkJS); - result += this.generateStorageInitialization(options.useEmbarkJS); - result += this.generateCommunicationInitialization(options.useEmbarkJS); - - return result; -}; + return result; + } +} module.exports = ABIGenerator; diff --git a/lib/contracts/compiler.js b/lib/contracts/compiler.js index cf72d6051..31c0ba33b 100644 --- a/lib/contracts/compiler.js +++ b/lib/contracts/compiler.js @@ -2,105 +2,107 @@ let async = require('../utils/async_extend.js'); let SolcW = require('./solcW.js'); -let Compiler = function(options) { - this.plugins = options.plugins; - this.logger = options.logger; -}; - -Compiler.prototype.compile_contracts = function(contractFiles, cb) { - - let available_compilers = { - //".se": this.compile_serpent - ".sol": this.compile_solidity.bind(this) - }; - - if (this.plugins) { - let compilerPlugins = this.plugins.getPluginsFor('compilers'); - if (compilerPlugins.length > 0) { - compilerPlugins.forEach(function(plugin) { - plugin.compilers.forEach(function(compilerObject) { - available_compilers[compilerObject.extension] = compilerObject.cb; - }); - }); - } +class Compiler { + constructor(options) { + this.plugins = options.plugins; + this.logger = options.logger; } - let compiledObject = {}; + compile_contracts(contractFiles, cb) { - async.eachObject(available_compilers, - function(extension, compiler, callback) { - // TODO: warn about files it doesn't know how to compile - let matchingFiles = contractFiles.filter(function(file) { - return (file.filename.match(/\.[0-9a-z]+$/)[0] === extension); - }); + let available_compilers = { + //".se": this.compile_serpent + ".sol": this.compile_solidity.bind(this) + }; - compiler.call(compiler, matchingFiles || [], function(err, compileResult) { - Object.assign(compiledObject, compileResult); - callback(err, compileResult); - }); - }, - function (err) { - cb(err, compiledObject); + if (this.plugins) { + let compilerPlugins = this.plugins.getPluginsFor('compilers'); + if (compilerPlugins.length > 0) { + compilerPlugins.forEach(function (plugin) { + plugin.compilers.forEach(function (compilerObject) { + available_compilers[compilerObject.extension] = compilerObject.cb; + }); + }); + } } - ); -}; -Compiler.prototype.compile_solidity = function(contractFiles, cb) { - let self = this; - let input = {}; - let solcW; - async.waterfall([ - function prepareInput(callback) { - for (let i = 0; i < contractFiles.length; i++){ - // TODO: this depends on the config - let filename = contractFiles[i].filename.replace('app/contracts/',''); - input[filename] = contractFiles[i].content.toString(); - } - callback(); - }, - function loadCompiler(callback) { - // TODO: there ino need to load this twice - solcW = new SolcW(); - if (solcW.isCompilerLoaded()) { - return callback(); - } + let compiledObject = {}; - self.logger.info("loading solc compiler.."); - solcW.load_compiler(function(){ - callback(); - }); - }, - function compileContracts(callback) { - self.logger.info("compiling contracts..."); - solcW.compile({sources: input}, 1, function(output) { - if (output.errors) { - return callback(new Error ("Solidity errors: " + output.errors).message); + async.eachObject(available_compilers, + function (extension, compiler, callback) { + // TODO: warn about files it doesn't know how to compile + let matchingFiles = contractFiles.filter(function (file) { + return (file.filename.match(/\.[0-9a-z]+$/)[0] === extension); + }); + + compiler.call(compiler, matchingFiles || [], function (err, compileResult) { + Object.assign(compiledObject, compileResult); + callback(err, compileResult); + }); + }, + function (err) { + cb(err, compiledObject); + } + ); + } + + compile_solidity(contractFiles, cb) { + let self = this; + let input = {}; + let solcW; + async.waterfall([ + function prepareInput(callback) { + for (let i = 0; i < contractFiles.length; i++) { + // TODO: this depends on the config + let filename = contractFiles[i].filename.replace('app/contracts/', ''); + input[filename] = contractFiles[i].content.toString(); + } + callback(); + }, + function loadCompiler(callback) { + // TODO: there ino need to load this twice + solcW = new SolcW(); + if (solcW.isCompilerLoaded()) { + return callback(); } - callback(null, output); - }); - }, - function createCompiledObject(output, callback) { - let json = output.contracts; - let compiled_object = {}; + self.logger.info("loading solc compiler.."); + solcW.load_compiler(function () { + callback(); + }); + }, + function compileContracts(callback) { + self.logger.info("compiling contracts..."); + solcW.compile({sources: input}, 1, function (output) { + if (output.errors) { + return callback(new Error("Solidity errors: " + output.errors).message); + } + callback(null, output); + }); + }, + function createCompiledObject(output, callback) { + let json = output.contracts; - for (let className in json) { - let contract = json[className]; + let compiled_object = {}; - compiled_object[className] = {}; - compiled_object[className].code = contract.bytecode; - compiled_object[className].runtimeBytecode = contract.runtimeBytecode; - compiled_object[className].realRuntimeBytecode = contract.runtimeBytecode.slice(0, -68); - compiled_object[className].swarmHash = contract.runtimeBytecode.slice(-68).slice(0,64); - compiled_object[className].gasEstimates = contract.gasEstimates; - compiled_object[className].functionHashes = contract.functionHashes; - compiled_object[className].abiDefinition = JSON.parse(contract.interface); + for (let className in json) { + let contract = json[className]; + + compiled_object[className] = {}; + compiled_object[className].code = contract.bytecode; + compiled_object[className].runtimeBytecode = contract.runtimeBytecode; + compiled_object[className].realRuntimeBytecode = contract.runtimeBytecode.slice(0, -68); + compiled_object[className].swarmHash = contract.runtimeBytecode.slice(-68).slice(0, 64); + compiled_object[className].gasEstimates = contract.gasEstimates; + compiled_object[className].functionHashes = contract.functionHashes; + compiled_object[className].abiDefinition = JSON.parse(contract.interface); + } + callback(null, compiled_object); } - callback(null, compiled_object); - } - ], function(err, result) { - cb(err, result); - }); -}; + ], function (err, result) { + cb(err, result); + }); + }; +} module.exports = Compiler; diff --git a/lib/contracts/contracts.js b/lib/contracts/contracts.js index e6e2dc875..54fb8e896 100644 --- a/lib/contracts/contracts.js +++ b/lib/contracts/contracts.js @@ -5,243 +5,247 @@ let Compiler = require('./compiler.js'); // TODO: create a contract object -let adjustGas = function(contract) { - let maxGas, adjustedGas; - if (contract.gas === 'auto') { - if (contract.deploy || contract.deploy === undefined) { - if (contract.gasEstimates.creation !== undefined) { - // TODO: should sum it instead - maxGas = Math.max(contract.gasEstimates.creation[0], contract.gasEstimates.creation[1], 500000); - } else { - maxGas = 500000; - } - } else { - maxGas = 500000; - } - // TODO: put a check so it doesn't go over the block limit - adjustedGas = Math.round(maxGas * 1.40); - adjustedGas += 25000; - contract.gas = adjustedGas; +class ContractsManager { + constructor(options) { + this.contractFiles = options.contractFiles; + this.contractsConfig = options.contractsConfig; + this.contracts = {}; + this.logger = options.logger; + this.plugins = options.plugins; + + this.contractDependencies = {}; } -}; -let ContractsManager = function(options) { - this.contractFiles = options.contractFiles; - this.contractsConfig = options.contractsConfig; - this.contracts = {}; - this.logger = options.logger; - this.plugins = options.plugins; - - this.contractDependencies = {}; -}; - -ContractsManager.prototype.build = function(done) { - let self = this; - async.waterfall([ - function compileContracts(callback) { - let compiler = new Compiler({plugins: self.plugins, logger: self.logger}); - compiler.compile_contracts(self.contractFiles, function(err, compiledObject) { + build(done) { + let self = this; + async.waterfall([ + function compileContracts(callback) { + let compiler = new Compiler({plugins: self.plugins, logger: self.logger}); + compiler.compile_contracts(self.contractFiles, function (err, compiledObject) { self.compiledContracts = compiledObject; callback(err); }); - }, - function prepareContractsFromConfig(callback) { - let className, contract; - for(className in self.contractsConfig.contracts) { - contract = self.contractsConfig.contracts[className]; + }, + function prepareContractsFromConfig(callback) { + let className, contract; + for (className in self.contractsConfig.contracts) { + contract = self.contractsConfig.contracts[className]; - contract.className = className; - contract.args = contract.args || []; + contract.className = className; + contract.args = contract.args || []; - self.contracts[className] = contract; - } - callback(); - }, - function setDeployIntention(callback) { - let className, contract; - for(className in self.contracts) { - contract = self.contracts[className]; - contract.deploy = (contract.deploy === undefined) || contract.deploy; - } - callback(); - }, - function prepareContractsFromCompilation(callback) { - let className, compiledContract, contractConfig, contract; - for(className in self.compiledContracts) { - compiledContract = self.compiledContracts[className]; - contractConfig = self.contractsConfig.contracts[className]; - - contract = self.contracts[className] || {className: className, args: []}; - - contract.code = compiledContract.code; - contract.runtimeBytecode = compiledContract.runtimeBytecode; - contract.realRuntimeBytecode = (contract.realRuntimeBytecode || contract.runtimeBytecode); - contract.swarmHash = compiledContract.swarmHash; - contract.gasEstimates = compiledContract.gasEstimates; - contract.functionHashes = compiledContract.functionHashes; - contract.abiDefinition = compiledContract.abiDefinition; - - contract.gas = (contractConfig && contractConfig.gas) || self.contractsConfig.gas || 'auto'; - adjustGas(contract); - - contract.gasPrice = contract.gasPrice || self.contractsConfig.gasPrice; - contract.type = 'file'; - contract.className = className; - - self.contracts[className] = contract; - } - callback(); - }, - /*eslint complexity: ["error", 11]*/ - function dealWithSpecialConfigs(callback) { - let className, contract, parentContractName, parentContract; - - for(className in self.contracts) { - contract = self.contracts[className]; - - if (contract.instanceOf === undefined) { continue; } - - parentContractName = contract.instanceOf; - parentContract = self.contracts[parentContractName]; - - if (parentContract === className) { - self.logger.error(className + ": instanceOf is set to itself"); - continue; + self.contracts[className] = contract; } - - if (parentContract === undefined) { - self.logger.error(className + ": couldn't find instanceOf contract " + parentContractName); - continue; + callback(); + }, + function setDeployIntention(callback) { + let className, contract; + for (className in self.contracts) { + contract = self.contracts[className]; + contract.deploy = (contract.deploy === undefined) || contract.deploy; } + callback(); + }, + function prepareContractsFromCompilation(callback) { + let className, compiledContract, contractConfig, contract; + for (className in self.compiledContracts) { + compiledContract = self.compiledContracts[className]; + contractConfig = self.contractsConfig.contracts[className]; - if (parentContract.args && parentContract.args.length > 0 && ((contract.args && contract.args.length === 0) || contract.args === undefined)) { - contract.args = parentContract.args; + contract = self.contracts[className] || {className: className, args: []}; + + contract.code = compiledContract.code; + contract.runtimeBytecode = compiledContract.runtimeBytecode; + contract.realRuntimeBytecode = (contract.realRuntimeBytecode || contract.runtimeBytecode); + contract.swarmHash = compiledContract.swarmHash; + contract.gasEstimates = compiledContract.gasEstimates; + contract.functionHashes = compiledContract.functionHashes; + contract.abiDefinition = compiledContract.abiDefinition; + + contract.gas = (contractConfig && contractConfig.gas) || self.contractsConfig.gas || 'auto'; + self.adjustGas(contract); + + contract.gasPrice = contract.gasPrice || self.contractsConfig.gasPrice; + contract.type = 'file'; + contract.className = className; + + self.contracts[className] = contract; } + callback(); + }, + /*eslint complexity: ["error", 11]*/ + function dealWithSpecialConfigs(callback) { + let className, contract, parentContractName, parentContract; + + for (className in self.contracts) { + contract = self.contracts[className]; + + if (contract.instanceOf === undefined) { + continue; + } + + parentContractName = contract.instanceOf; + parentContract = self.contracts[parentContractName]; + + if (parentContract === className) { + self.logger.error(className + ": instanceOf is set to itself"); + continue; + } + + if (parentContract === undefined) { + self.logger.error(className + ": couldn't find instanceOf contract " + parentContractName); + continue; + } + + if (parentContract.args && parentContract.args.length > 0 && ((contract.args && contract.args.length === 0) || contract.args === undefined)) { + contract.args = parentContract.args; + } + + if (contract.code !== undefined) { + self.logger.error(className + " has code associated to it but it's configured as an instanceOf " + parentContractName); + } + + contract.code = parentContract.code; + contract.runtimeBytecode = parentContract.runtimeBytecode; + contract.gasEstimates = parentContract.gasEstimates; + contract.functionHashes = parentContract.functionHashes; + contract.abiDefinition = parentContract.abiDefinition; + + contract.gas = contract.gas || parentContract.gas; + contract.gasPrice = contract.gasPrice || parentContract.gasPrice; + contract.type = 'instance'; - if (contract.code !== undefined) { - self.logger.error(className + " has code associated to it but it's configured as an instanceOf " + parentContractName); } + callback(); + }, + function removeContractsWithNoCode(callback) { + let className, contract; + for (className in self.contracts) { + contract = self.contracts[className]; - contract.code = parentContract.code; - contract.runtimeBytecode = parentContract.runtimeBytecode; - contract.gasEstimates = parentContract.gasEstimates; - contract.functionHashes = parentContract.functionHashes; - contract.abiDefinition = parentContract.abiDefinition; - - contract.gas = contract.gas || parentContract.gas; - contract.gasPrice = contract.gasPrice || parentContract.gasPrice; - contract.type = 'instance'; - - } - callback(); - }, - function removeContractsWithNoCode(callback) { - let className, contract; - for(className in self.contracts) { - contract = self.contracts[className]; - - if (contract.code === undefined) { - self.logger.error(className + " has no code associated"); - delete self.contracts[className]; - } - } - self.logger.trace(self.contracts); - callback(); - }, - function determineDependencies(callback) { - let className, contract; - for(className in self.contracts) { - contract = self.contracts[className]; - - if (contract.args === []) continue; - - let ref = contract.args; - for (let j = 0; j < ref.length; j++) { - let arg = ref[j]; - if (arg[0] === "$") { - self.contractDependencies[className] = self.contractDependencies[className] || []; - self.contractDependencies[className].push(arg.substr(1)); + if (contract.code === undefined) { + self.logger.error(className + " has no code associated"); + delete self.contracts[className]; } } + self.logger.trace(self.contracts); + callback(); + }, + function determineDependencies(callback) { + let className, contract; + for (className in self.contracts) { + contract = self.contracts[className]; + + if (contract.args === []) continue; + + let ref = contract.args; + for (let j = 0; j < ref.length; j++) { + let arg = ref[j]; + if (arg[0] === "$") { + self.contractDependencies[className] = self.contractDependencies[className] || []; + self.contractDependencies[className].push(arg.substr(1)); + } + } + } + callback(); } - callback(); - } - ], function(err, result) { - if (err) { - self.logger.error("Error Compiling/Building contracts: " + err); - } - self.logger.trace("finished".underline); - done(err, self); - }); -}; - -ContractsManager.prototype.getContract = function(className) { - return this.contracts[className]; -}; - -ContractsManager.prototype.sortContracts = function(contractList) { - let converted_dependencies = [], i; - - for(let contract in this.contractDependencies) { - let dependencies = this.contractDependencies[contract]; - for(i=0; i < dependencies.length; i++) { - converted_dependencies.push([contract, dependencies[i]]); - } + ], function (err, result) { + if (err) { + self.logger.error("Error Compiling/Building contracts: " + err); + } + self.logger.trace("finished".underline); + done(err, self); + }); } - let orderedDependencies = toposort(converted_dependencies).reverse(); - - let newList = contractList.sort(function(a,b) { - let order_a = orderedDependencies.indexOf(a.className); - let order_b = orderedDependencies.indexOf(b.className); - return order_a - order_b; - }); - - return newList; -}; - -// TODO: should be built contracts -ContractsManager.prototype.listContracts = function() { - let contracts = []; - for(let className in this.contracts) { - let contract = this.contracts[className]; - contracts.push(contract); + getContract(className) { + return this.contracts[className]; } - return this.sortContracts(contracts); -}; -ContractsManager.prototype.contractsState = function() { - let data = []; + sortContracts(contractList) { + let converted_dependencies = [], i; - for(let className in this.contracts) { - let contract = this.contracts[className]; - - let contractData; - - if (contract.deploy === false) { - contractData = [ - className.green, - 'Interface or set to not deploy'.green, - "\t\tn/a".green - ]; - } else if (contract.error) { - contractData = [ - className.green, - (contract.error).red, - '\t\tError'.red - ]; - } else { - contractData = [ - className.green, - (contract.deployedAddress || '...').green, - ((contract.deployedAddress !== undefined) ? "\t\tDeployed".green : "\t\tPending".magenta) - ]; + for (let contract in this.contractDependencies) { + let dependencies = this.contractDependencies[contract]; + for (i = 0; i < dependencies.length; i++) { + converted_dependencies.push([contract, dependencies[i]]); + } } - data.push(contractData); + let orderedDependencies = toposort(converted_dependencies).reverse(); + + let newList = contractList.sort(function (a, b) { + let order_a = orderedDependencies.indexOf(a.className); + let order_b = orderedDependencies.indexOf(b.className); + return order_a - order_b; + }); + + return newList; } - return data; -}; + // TODO: should be built contracts + listContracts() { + let contracts = []; + for (let className in this.contracts) { + let contract = this.contracts[className]; + contracts.push(contract); + } + return this.sortContracts(contracts); + } + + contractsState() { + let data = []; + + for (let className in this.contracts) { + let contract = this.contracts[className]; + + let contractData; + + if (contract.deploy === false) { + contractData = [ + className.green, + 'Interface or set to not deploy'.green, + "\t\tn/a".green + ]; + } else if (contract.error) { + contractData = [ + className.green, + (contract.error).red, + '\t\tError'.red + ]; + } else { + contractData = [ + className.green, + (contract.deployedAddress || '...').green, + ((contract.deployedAddress !== undefined) ? "\t\tDeployed".green : "\t\tPending".magenta) + ]; + } + + data.push(contractData); + } + + return data; + } + + adjustGas(contract) { + let maxGas, adjustedGas; + if (contract.gas === 'auto') { + if (contract.deploy || contract.deploy === undefined) { + if (contract.gasEstimates.creation !== undefined) { + // TODO: should sum it instead + maxGas = Math.max(contract.gasEstimates.creation[0], contract.gasEstimates.creation[1], 500000); + } else { + maxGas = 500000; + } + } else { + maxGas = 500000; + } + // TODO: put a check so it doesn't go over the block limit + adjustedGas = Math.round(maxGas * 1.40); + adjustedGas += 25000; + contract.gas = adjustedGas; + } + } +} module.exports = ContractsManager; diff --git a/lib/contracts/deploy.js b/lib/contracts/deploy.js index 42c33e47b..489d66f6e 100644 --- a/lib/contracts/deploy.js +++ b/lib/contracts/deploy.js @@ -5,162 +5,164 @@ let RunCode = require('../core/runCode.js'); let DeployTracker = require('./deploy_tracker.js'); let ABIGenerator = require('./abi.js'); -let Deploy = function(options) { - this.web3 = options.web3; - this.contractsManager = options.contractsManager; - this.logger = options.logger; - this.env = options.env; +class Deploy { + constructor(options) { + this.web3 = options.web3; + this.contractsManager = options.contractsManager; + this.logger = options.logger; + this.env = options.env; - this.deployTracker = new DeployTracker({ - logger: options.logger, chainConfig: options.chainConfig, web3: options.web3, env: this.env - }); -}; - -Deploy.prototype.determineArguments = function(suppliedArgs) { - let realArgs = [], l, arg, contractName, referedContract; - - for (l = 0; l < suppliedArgs.length; l++) { - arg = suppliedArgs[l]; - if (arg[0] === "$") { - contractName = arg.substr(1); - referedContract = this.contractsManager.getContract(contractName); - realArgs.push(referedContract.deployedAddress); - } else { - realArgs.push(arg); - } + this.deployTracker = new DeployTracker({ + logger: options.logger, chainConfig: options.chainConfig, web3: options.web3, env: this.env + }); } - return realArgs; -}; + determineArguments(suppliedArgs) { + let realArgs = [], l, arg, contractName, referedContract; -Deploy.prototype.checkAndDeployContract = function(contract, params, callback) { - let self = this; - let suppliedArgs; - let realArgs; - let arg; - let l; - let contractName; - let referedContract; - contract.error = false; - - if (contract.deploy === false) { - self.logger.contractsState(self.contractsManager.contractsState()); - return callback(); - } - - if (contract.address !== undefined) { - - realArgs = self.determineArguments(params || contract.args); - - contract.deployedAddress = contract.address; - self.deployTracker.trackContract(contract.className, contract.realRuntimeBytecode, realArgs, contract.address); - self.deployTracker.save(); - self.logger.contractsState(self.contractsManager.contractsState()); - return callback(); - } - - let trackedContract = self.deployTracker.getContract(contract.className, contract.realRuntimeBytecode, contract.args); - - if (trackedContract && this.web3.eth.getCode(trackedContract.address) !== "0x") { - self.logger.info(contract.className.bold.cyan + " already deployed at ".green + trackedContract.address.bold.cyan); - contract.deployedAddress = trackedContract.address; - self.logger.contractsState(self.contractsManager.contractsState()); - return callback(); - } else { - - realArgs = self.determineArguments(params || contract.args); - - this.deployContract(contract, realArgs, function(err, address) { - if (err) { - return callback(new Error(err)); + for (l = 0; l < suppliedArgs.length; l++) { + arg = suppliedArgs[l]; + if (arg[0] === "$") { + contractName = arg.substr(1); + referedContract = this.contractsManager.getContract(contractName); + realArgs.push(referedContract.deployedAddress); + } else { + realArgs.push(arg); } - self.deployTracker.trackContract(contract.className, contract.realRuntimeBytecode, realArgs, address); + } + + return realArgs; + } + + checkAndDeployContract(contract, params, callback) { + let self = this; + let suppliedArgs; + let realArgs; + let arg; + let l; + let contractName; + let referedContract; + contract.error = false; + + if (contract.deploy === false) { + self.logger.contractsState(self.contractsManager.contractsState()); + return callback(); + } + + if (contract.address !== undefined) { + + realArgs = self.determineArguments(params || contract.args); + + contract.deployedAddress = contract.address; + self.deployTracker.trackContract(contract.className, contract.realRuntimeBytecode, realArgs, contract.address); self.deployTracker.save(); self.logger.contractsState(self.contractsManager.contractsState()); + return callback(); + } - if (contract.onDeploy !== undefined) { - self.logger.info('executing onDeploy commands'); - let abiGenerator = new ABIGenerator({contractsManager: self.contractsManager}); - let abi = abiGenerator.generateContracts(false); - let cmds = contract.onDeploy.join(';\n'); + let trackedContract = self.deployTracker.getContract(contract.className, contract.realRuntimeBytecode, contract.args); - RunCode.doEval(abi + "\n" + cmds, self.web3); + if (trackedContract && this.web3.eth.getCode(trackedContract.address) !== "0x") { + self.logger.info(contract.className.bold.cyan + " already deployed at ".green + trackedContract.address.bold.cyan); + contract.deployedAddress = trackedContract.address; + self.logger.contractsState(self.contractsManager.contractsState()); + return callback(); + } else { + + realArgs = self.determineArguments(params || contract.args); + + this.deployContract(contract, realArgs, function (err, address) { + if (err) { + return callback(new Error(err)); + } + self.deployTracker.trackContract(contract.className, contract.realRuntimeBytecode, realArgs, address); + self.deployTracker.save(); + self.logger.contractsState(self.contractsManager.contractsState()); + + if (contract.onDeploy !== undefined) { + self.logger.info('executing onDeploy commands'); + let abiGenerator = new ABIGenerator({contractsManager: self.contractsManager}); + let abi = abiGenerator.generateContracts(false); + let cmds = contract.onDeploy.join(';\n'); + + RunCode.doEval(abi + "\n" + cmds, self.web3); + } + + callback(); + }); + } + + } + + deployContract(contract, params, callback) { + let self = this; + let contractObject = this.web3.eth.contract(contract.abiDefinition); + + let contractParams = (params || contract.args).slice(); + + this.web3.eth.getAccounts(function (err, accounts) { + if (err) { + return callback(new Error(err)); } - callback(); + // TODO: probably needs to be defaultAccount + // TODO: it wouldn't necessary be the first address + // use defined blockchain address or first address + contractParams.push({ + //from: this.web3.eth.coinbase, + from: accounts[0], + data: "0x" + contract.code, + gas: contract.gas, + gasPrice: contract.gasPrice + }); + + self.logger.info("deploying " + contract.className.bold.cyan + " with ".green + contract.gas + " gas".green); + contractParams.push(function (err, transaction) { + self.logger.contractsState(self.contractsManager.contractsState()); + + if (err) { + self.logger.error("error deploying contract: " + contract.className.cyan); + let errMsg = err.toString(); + if (errMsg === 'Error: The contract code couldn\'t be stored, please check your gas amount.') { + errMsg = 'The contract code couldn\'t be stored, out of gas or constructor error'; + } + self.logger.error(errMsg); + contract.error = errMsg; + return callback(new Error(err)); + } else if (transaction.address !== undefined) { + self.logger.info(contract.className.bold.cyan + " deployed at ".green + transaction.address.bold.cyan); + contract.deployedAddress = transaction.address; + contract.transactionHash = transaction.transactionHash; + return callback(null, transaction.address); + } + }); + + contractObject["new"].apply(contractObject, contractParams); }); } -}; + deployAll(done) { + let self = this; + this.logger.info("deploying contracts"); -Deploy.prototype.deployContract = function(contract, params, callback) { - let self = this; - let contractObject = this.web3.eth.contract(contract.abiDefinition); - - let contractParams = (params || contract.args).slice(); - - this.web3.eth.getAccounts(function(err, accounts) { - if (err) { - return callback(new Error(err)); - } - - // TODO: probably needs to be defaultAccount - // TODO: it wouldn't necessary be the first address - // use defined blockchain address or first address - contractParams.push({ - //from: this.web3.eth.coinbase, - from: accounts[0], - data: "0x" + contract.code, - gas: contract.gas, - gasPrice: contract.gasPrice - }); - - self.logger.info("deploying " + contract.className.bold.cyan + " with ".green + contract.gas + " gas".green); - contractParams.push(function(err, transaction) { - self.logger.contractsState(self.contractsManager.contractsState()); - - if (err) { - self.logger.error("error deploying contract: " + contract.className.cyan); - let errMsg = err.toString(); - if (errMsg === 'Error: The contract code couldn\'t be stored, please check your gas amount.') { - errMsg = 'The contract code couldn\'t be stored, out of gas or constructor error'; + async.eachOfSeries(this.contractsManager.listContracts(), + function (contract, key, callback) { + self.logger.trace(arguments); + self.checkAndDeployContract(contract, null, callback); + }, + function (err, results) { + if (err) { + self.logger.error("error deploying contracts"); + self.logger.error(err.message); + self.logger.debug(err.stack); } - self.logger.error(errMsg); - contract.error = errMsg; - return callback(new Error(err)); - } else if (transaction.address !== undefined) { - self.logger.info(contract.className.bold.cyan + " deployed at ".green + transaction.address.bold.cyan); - contract.deployedAddress = transaction.address; - contract.transactionHash = transaction.transactionHash; - return callback(null, transaction.address); + self.logger.info("finished deploying contracts"); + self.logger.trace(arguments); + done(); } - }); + ); - contractObject["new"].apply(contractObject, contractParams); - }); -}; - -Deploy.prototype.deployAll = function(done) { - let self = this; - this.logger.info("deploying contracts"); - - async.eachOfSeries(this.contractsManager.listContracts(), - function(contract, key, callback) { - self.logger.trace(arguments); - self.checkAndDeployContract(contract, null, callback); - }, - function(err, results) { - if (err) { - self.logger.error("error deploying contracts"); - self.logger.error(err.message); - self.logger.debug(err.stack); - } - self.logger.info("finished deploying contracts"); - self.logger.trace(arguments); - done(); - } - ); - -}; + }; +} module.exports = Deploy; diff --git a/lib/contracts/deploy_manager.js b/lib/contracts/deploy_manager.js index 73dbce58d..86e41ca2e 100644 --- a/lib/contracts/deploy_manager.js +++ b/lib/contracts/deploy_manager.js @@ -1,91 +1,91 @@ let async = require('async'); - let Deploy = require('./deploy.js'); let ContractsManager = require('./contracts.js'); -const EventEmitter = require('events').EventEmitter; +let EventEmitter = require('events'); -let DeployManager = function(options) { - this.config = options.config; - this.logger = options.logger; - this.blockchainConfig = this.config.blockchainConfig; - this.plugins = options.plugins; - this.web3 = options.web3; - this.chainConfig = (options.trackContracts !== false) ? this.config.chainTracker : false; -}; - -DeployManager.prototype = Object.create(EventEmitter.prototype); - - -DeployManager.prototype.deployContracts = function(done) { - let self = this; - - if (self.blockchainConfig === {} || self.blockchainConfig.enabled === false) { - self.logger.info("Blockchain component is disabled in the config".underline); - this.emit('blockchainDisabled', {}); - return done(); +class DeployManager { + constructor(options) { + this.config = options.config; + this.logger = options.logger; + this.blockchainConfig = this.config.blockchainConfig; + this.plugins = options.plugins; + this.web3 = options.web3; + this.chainConfig = (options.trackContracts !== false) ? this.config.chainTracker : false; + Object.create(EventEmitter.prototype); } - async.waterfall([ - function buildContracts(callback) { - let contractsManager = new ContractsManager({ - contractFiles: self.config.contractsFiles, - contractsConfig: self.config.contractsConfig, - logger: self.logger, - plugins: self.plugins - }); - contractsManager.build(callback); - }, - function checkWeb3IsConnected(contractsManager, callback) { - if (!self.web3) { - return callback(Error("no web3 instance found")); + deployContracts(done) { + let self = this; + + if (self.blockchainConfig === {} || self.blockchainConfig.enabled === false) { + self.logger.info("Blockchain component is disabled in the config".underline); + this.emit('blockchainDisabled', {}); + return done(); } - if (self.web3.currentProvider.isConnected !== undefined && !self.web3.isConnected()) { - self.logger.error(("Couldn't connect to an Ethereum node are you sure it's on?").red); - self.logger.info("make sure you have an Ethereum node or simulator running. e.g 'embark blockchain'".magenta); - return callback(Error("error connecting to blockchain node")); - } - if (self.web3.currentProvider.isConnected === undefined) { - self.web3.version.getNode(function(err, version) { - if (err) { + + async.waterfall([ + function buildContracts(callback) { + let contractsManager = new ContractsManager({ + contractFiles: self.config.contractsFiles, + contractsConfig: self.config.contractsConfig, + logger: self.logger, + plugins: self.plugins + }); + contractsManager.build(callback); + }, + function checkWeb3IsConnected(contractsManager, callback) { + if (!self.web3) { + return callback(Error("no web3 instance found")); + } + if (self.web3.currentProvider.isConnected !== undefined && !self.web3.isConnected()) { + self.logger.error(("Couldn't connect to an Ethereum node are you sure it's on?").red); + self.logger.info("make sure you have an Ethereum node or simulator running. e.g 'embark blockchain'".magenta); return callback(Error("error connecting to blockchain node")); } - return callback(null, contractsManager, self.web3); - }); - } else { - return callback(null, contractsManager, self.web3); - } - }, - function setDefaultAccount(contractsManager, web3, callback) { - web3.eth.getAccounts(function(err, accounts) { - if (err) { - return callback(new Error(err)); + if (self.web3.currentProvider.isConnected === undefined) { + self.web3.version.getNode(function (err, version) { + if (err) { + return callback(Error("error connecting to blockchain node")); + } + return callback(null, contractsManager, self.web3); + }); + } else { + return callback(null, contractsManager, self.web3); + } + }, + function setDefaultAccount(contractsManager, web3, callback) { + web3.eth.getAccounts(function (err, accounts) { + if (err) { + return callback(new Error(err)); + } + let accountConfig = self.config.blockchainConfig.account; + let selectedAccount = accountConfig && accountConfig.address; + web3.eth.defaultAccount = (selectedAccount || accounts[0]); + callback(null, contractsManager, web3); + }); + }, + function deployAllContracts(contractsManager, web3, callback) { + let deploy = new Deploy({ + web3: web3, + contractsManager: contractsManager, + logger: self.logger, + chainConfig: self.chainConfig, + env: self.config.env + }); + deploy.deployAll(function () { + self.emit('contractsDeployed', contractsManager); + callback(null, contractsManager); + }); + } + ], function (err, result) { + if (err) { + done(err, null); + } else { + done(null, result); } - let accountConfig = self.config.blockchainConfig.account; - let selectedAccount = accountConfig && accountConfig.address; - web3.eth.defaultAccount = (selectedAccount || accounts[0]); - callback(null, contractsManager, web3); - }); - }, - function deployAllContracts(contractsManager, web3, callback) { - let deploy = new Deploy({ - web3: web3, - contractsManager: contractsManager, - logger: self.logger, - chainConfig: self.chainConfig, - env: self.config.env - }); - deploy.deployAll(function() { - self.emit('contractsDeployed', contractsManager); - callback(null, contractsManager); }); } - ], function(err, result) { - if (err) { - done(err, null); - } else { - done(null, result); - } - }); -}; + +} module.exports = DeployManager; diff --git a/lib/contracts/deploy_tracker.js b/lib/contracts/deploy_tracker.js index 931a4ee12..c7168b0e9 100644 --- a/lib/contracts/deploy_tracker.js +++ b/lib/contracts/deploy_tracker.js @@ -1,56 +1,62 @@ let fs = require('../core/fs.js'); -let DeployTracker = function(options) { - this.logger = options.logger; - this.env = options.env; - this.chainConfig = options.chainConfig; - this.web3 = options.web3; +class DeployTracker { + constructor(options) { + this.logger = options.logger; + this.env = options.env; + this.chainConfig = options.chainConfig; + this.web3 = options.web3; - if (this.chainConfig === false) { - this.currentChain = {contracts: []}; - return; + if (this.chainConfig === false) { + this.currentChain = {contracts: []}; + return; + } + + // TODO: need to make this async + let block = this.web3.eth.getBlock(0); + let chainId = block.hash; + + if (this.chainConfig[chainId] === undefined) { + this.chainConfig[chainId] = {contracts: {}}; + } + + this.currentChain = this.chainConfig[chainId]; + + this.currentChain.name = this.env; + // TODO: add other params + //this.currentChain.networkId = ""; + //this.currentChain.networkType = "custom" } - // TODO: need to make this async - let block = this.web3.eth.getBlock(0); - let chainId = block.hash; - - if (this.chainConfig[chainId] === undefined) { - this.chainConfig[chainId] = {contracts: {}}; + loadConfig(config) { + this.chainConfig = config; + return this; } - this.currentChain = this.chainConfig[chainId]; + trackContract(contractName, code, args, address) { + this.currentChain.contracts[this.web3.sha3(code + contractName + args.join(','))] = { + name: contractName, + address: address + }; + } - this.currentChain.name = this.env; - // TODO: add other params - //this.currentChain.networkId = ""; - //this.currentChain.networkType = "custom" -}; + getContract(contractName, code, args) { + let contract = this.currentChain.contracts[this.web3.sha3(code + contractName + args.join(','))]; + if (contract && contract.address === undefined) { + return false; + } + return contract; + } -DeployTracker.prototype.loadConfig = function(config) { - this.chainConfig = config; - return this; -}; - -DeployTracker.prototype.trackContract = function(contractName, code, args, address) { - this.currentChain.contracts[this.web3.sha3(code + contractName + args.join(','))] = { - name: contractName, - address: address - }; -}; - -DeployTracker.prototype.getContract = function(contractName, code, args) { - let contract = this.currentChain.contracts[this.web3.sha3(code + contractName + args.join(','))]; - if (contract && contract.address === undefined) { return false; } - return contract; -}; - -// TODO: abstract this -// chainConfig can be an abstract PersistentObject -DeployTracker.prototype.save = function() { - if (this.chainConfig === false) { return; } - fs.writeJSONSync("./chains.json", this.chainConfig); -}; + // TODO: abstract this + // chainConfig can be an abstract PersistentObject + save() { + if (this.chainConfig === false) { + return; + } + fs.writeJSONSync("./chains.json", this.chainConfig); + } +} module.exports = DeployTracker; diff --git a/lib/contracts/solcP.js b/lib/contracts/solcP.js index 47cbc98d0..4c903fc1f 100644 --- a/lib/contracts/solcP.js +++ b/lib/contracts/solcP.js @@ -1,6 +1,6 @@ let solc; -process.on('message', function(msg) { +process.on('message', function (msg) { if (msg.action === 'loadCompiler') { solc = require('solc'); process.send({result: "loadedCompiler"}); @@ -12,7 +12,7 @@ process.on('message', function(msg) { } }); -process.on('exit', function() { +process.on('exit', function () { process.exit(0); }); diff --git a/lib/contracts/solcW.js b/lib/contracts/solcW.js index e9d980cd1..f18407a98 100644 --- a/lib/contracts/solcW.js +++ b/lib/contracts/solcW.js @@ -2,35 +2,37 @@ let utils = require('../utils/utils.js'); let solcProcess; let compilerLoaded = false; -let SolcW = function() { -}; +class SolcW { -SolcW.prototype.load_compiler = function(done) { - if (compilerLoaded) { done(); } - solcProcess = require('child_process').fork(utils.joinPath(__dirname, '/solcP.js')); - solcProcess.once('message', function(msg) { - if (msg.result !== 'loadedCompiler') { - return; + load_compiler(done) { + if (compilerLoaded) { + done(); } - compilerLoaded = true; - done(); - }); - solcProcess.send({action: 'loadCompiler'}); -}; + solcProcess = require('child_process').fork(utils.joinPath(__dirname, '/solcP.js')); + solcProcess.once('message', function (msg) { + if (msg.result !== 'loadedCompiler') { + return; + } + compilerLoaded = true; + done(); + }); + solcProcess.send({action: 'loadCompiler'}); + } -SolcW.prototype.isCompilerLoaded = function() { - return (compilerLoaded === true); -}; + isCompilerLoaded() { + return (compilerLoaded === true); + } -SolcW.prototype.compile = function(obj, optimize, done) { - solcProcess.once('message', function(msg) { - if (msg.result !== 'compilation') { - return; - } - done(msg.output); - }); - solcProcess.send({action: 'compile', obj: obj, optimize: optimize}); -}; + compile(obj, optimize, done) { + solcProcess.once('message', function (msg) { + if (msg.result !== 'compilation') { + return; + } + done(msg.output); + }); + solcProcess.send({action: 'compile', obj: obj, optimize: optimize}); + } +} module.exports = SolcW; diff --git a/lib/core/config.js b/lib/core/config.js index fd36a63c1..9cae005fd 100644 --- a/lib/core/config.js +++ b/lib/core/config.js @@ -4,23 +4,25 @@ let utils = require('../utils/utils.js'); // TODO: add wrapper for fs so it can also work in the browser // can work with both read and save -let Config = function(options) { - this.env = options.env; - this.blockchainConfig = {}; - this.contractsConfig = {}; - this.pipelineConfig = {}; - this.webServerConfig = {}; - this.chainTracker = {}; - this.assetFiles = {}; - this.contractsFiles = []; - this.configDir = options.configDir || 'config/'; - this.chainsFile = options.chainsFile || './chains.json'; - this.plugins = options.plugins; - this.logger = options.logger; - this.events = options.events; -}; +class Config { + constructor(options) { + this.env = options.env; + this.blockchainConfig = {}; + this.contractsConfig = {}; + this.pipelineConfig = {}; + this.webServerConfig = {}; + this.chainTracker = {}; + this.assetFiles = {}; + this.contractsFiles = []; + this.configDir = options.configDir || 'config/'; + this.chainsFile = options.chainsFile || './chains.json'; + this.plugins = options.plugins; + this.logger = options.logger; + this.events = options.events; + } +} -Config.prototype.loadConfigFiles = function(options) { +Config.prototype.loadConfigFiles = function (options) { let interceptLogs = options.interceptLogs; if (options.interceptLogs === undefined) { interceptLogs = true; @@ -28,7 +30,7 @@ Config.prototype.loadConfigFiles = function(options) { //Check if the config file exists 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'); process.exit(1); } @@ -36,7 +38,13 @@ Config.prototype.loadConfigFiles = function(options) { this.embarkConfig = fs.readJSONSync(options.embarkConfig); this.embarkConfig.plugins = this.embarkConfig.plugins || {}; - 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.load(); @@ -45,7 +53,7 @@ Config.prototype.loadConfigFiles = function(options) { this.loadPluginContractFiles(); }; -Config.prototype.load = Config.prototype.reloadConfig = function() { +Config.prototype.load = Config.prototype.reloadConfig = function () { this.loadEmbarkConfigFile(); this.loadBlockchainConfigFile(); this.loadStorageConfigFile(); @@ -55,7 +63,7 @@ Config.prototype.load = Config.prototype.reloadConfig = function() { this.loadChainTrackerFile(); }; -Config.prototype.loadBlockchainConfigFile = function() { +Config.prototype.loadBlockchainConfigFile = function () { let defaultBlockchainConfig = fs.readJSONSync(this.configDir + "blockchain.json"); this.blockchainConfig = defaultBlockchainConfig[this.env] || {}; @@ -64,7 +72,7 @@ Config.prototype.loadBlockchainConfigFile = function() { } }; -Config.prototype.loadContractsConfigFile = function() { +Config.prototype.loadContractsConfigFile = function () { let configObject = {}; let configPlugins = []; @@ -72,8 +80,8 @@ Config.prototype.loadContractsConfigFile = function() { configPlugins = kinds; }); if (configPlugins.length > 0) { - configPlugins.forEach(function(plugin) { - plugin.contractsConfigs.forEach(function(pluginConfig) { + configPlugins.forEach(function (plugin) { + plugin.contractsConfigs.forEach(function (pluginConfig) { configObject = utils.recursiveMerge(configObject, pluginConfig); }); }); @@ -88,7 +96,7 @@ Config.prototype.loadContractsConfigFile = function() { }; -Config.prototype.loadStorageConfigFile = function() { +Config.prototype.loadStorageConfigFile = function () { let configObject = { "default": { "enabled": true, @@ -98,8 +106,7 @@ Config.prototype.loadStorageConfigFile = function() { "host": "localhost", "port": 5001 }, - "development": { - } + "development": {} }; //let configPlugins = this.plugins.getPluginsFor('storageConfig'); @@ -131,7 +138,7 @@ Config.prototype.loadStorageConfigFile = function() { } }; -Config.prototype.loadCommunicationConfigFile = function() { +Config.prototype.loadCommunicationConfigFile = function () { let configObject = { "default": { "enabled": true, @@ -171,7 +178,7 @@ Config.prototype.loadCommunicationConfigFile = function() { } }; -Config.prototype.loadWebServerConfigFile = function() { +Config.prototype.loadWebServerConfigFile = function () { let webServerConfigJSON; if (fs.existsSync(this.configDir + "webserver.json")) { webServerConfigJSON = fs.readJSONSync(this.configDir + "webserver.json"); @@ -186,28 +193,28 @@ Config.prototype.loadWebServerConfigFile = function() { this.webServerConfig = utils.recursiveMerge(defaultWebConfig, webServerConfigJSON); }; -Config.prototype.loadEmbarkConfigFile = function() { +Config.prototype.loadEmbarkConfigFile = function () { let contracts = this.embarkConfig.contracts; this.contractsFiles = this.loadFiles(contracts); - this.buildDir = this.embarkConfig.buildDir; + this.buildDir = this.embarkConfig.buildDir; this.configDir = this.embarkConfig.config; }; -Config.prototype.loadPipelineConfigFile = function() { +Config.prototype.loadPipelineConfigFile = function () { let assets = this.embarkConfig.app; - for(let targetFile in assets) { + for (let targetFile in assets) { this.assetFiles[targetFile] = this.loadFiles(assets[targetFile]); } }; -Config.prototype.loadChainTrackerFile = function() { +Config.prototype.loadChainTrackerFile = function () { //let self = this; let chainTracker; try { chainTracker = fs.readJSONSync(this.chainsFile); } - catch(err) { + catch (err) { //self.logger.info(this.chainsFile + ' file not found, creating it...'); chainTracker = {}; fs.writeJSONSync(this.chainsFile, {}); @@ -215,32 +222,52 @@ Config.prototype.loadChainTrackerFile = function() { this.chainTracker = chainTracker; }; -Config.prototype.loadFiles = function(files) { +Config.prototype.loadFiles = function (files) { let self = this; let originalFiles = utils.filesMatchingPattern(files); let readFiles = []; // get embark.js object first - originalFiles.filter(function(file) { + originalFiles.filter(function (file) { return file.indexOf('.') >= 0; - }).filter(function(file) { + }).filter(function (file) { if (file === 'embark.js') { if (self.blockchainConfig.enabled || self.communicationConfig.provider === 'whisper' || self.communicationConfig.available_providers.indexOf('whisper') >= 0) { - readFiles.push({filename: 'web3.js', content: fs.readFileSync(fs.embarkPath("js/web3.js")).toString(), path: fs.embarkPath("js/web3.js")}); + readFiles.push({ + filename: 'web3.js', + content: fs.readFileSync(fs.embarkPath("js/web3.js")).toString(), + path: fs.embarkPath("js/web3.js") + }); } if (self.storageConfig.enabled && (self.storageConfig.provider === 'ipfs' || self.storageConfig.available_providers.indexOf('ipfs') >= 0)) { - readFiles.push({filename: 'ipfs.js', content: fs.readFileSync(fs.embarkPath("js/ipfs.js")).toString(), path: fs.embarkPath("js/ipfs.js")}); + readFiles.push({ + filename: 'ipfs.js', + content: fs.readFileSync(fs.embarkPath("js/ipfs.js")).toString(), + path: fs.embarkPath("js/ipfs.js") + }); } if (self.communicationConfig.enabled && (self.communicationConfig.provider === 'orbit' || self.communicationConfig.available_providers.indexOf('orbit') >= 0)) { // TODO: remove duplicated files if functionality is the same for storage and orbit - readFiles.push({filename: 'ipfs-api.js', content: fs.readFileSync(fs.embarkPath("js/ipfs-api.min.js")).toString(), path: fs.embarkPath("js/ipfs-api.min.js")}); - readFiles.push({filename: 'orbit.js', content: fs.readFileSync(fs.embarkPath("js/orbit.min.js")).toString(), path: fs.embarkPath("js/orbit.min.js")}); + readFiles.push({ + filename: 'ipfs-api.js', + content: fs.readFileSync(fs.embarkPath("js/ipfs-api.min.js")).toString(), + path: fs.embarkPath("js/ipfs-api.min.js") + }); + readFiles.push({ + filename: 'orbit.js', + content: fs.readFileSync(fs.embarkPath("js/orbit.min.js")).toString(), + path: fs.embarkPath("js/orbit.min.js") + }); } - readFiles.push({filename: 'embark.js', content: fs.readFileSync(fs.embarkPath("js/build/embark.bundle.js")).toString(), path: fs.embarkPath("js/build/embark.bundle.js")}); + readFiles.push({ + filename: 'embark.js', + content: fs.readFileSync(fs.embarkPath("js/build/embark.bundle.js")).toString(), + path: fs.embarkPath("js/build/embark.bundle.js") + }); } }); @@ -250,30 +277,30 @@ Config.prototype.loadFiles = function(files) { let filePlugins = self.plugins.getPluginsFor('pipelineFiles'); if (filePlugins.length > 0) { - filePlugins.forEach(function(plugin) { + filePlugins.forEach(function (plugin) { try { let fileObjects = plugin.runFilePipeline(); - for (let i=0; i < fileObjects.length; i++) { + for (let i = 0; i < fileObjects.length; i++) { let fileObject = fileObjects[i]; filesFromPlugins.push(fileObject); } } - catch(err) { + catch (err) { self.logger.error(err.message); } }); } - filesFromPlugins.filter(function(file) { + filesFromPlugins.filter(function (file) { if (utils.fileMatchesPattern(files, file.intendedPath)) { readFiles.push(file); } }); // get user files - originalFiles.filter(function(file) { + originalFiles.filter(function (file) { return file.indexOf('.') >= 0; - }).filter(function(file) { + }).filter(function (file) { if (file === 'embark.js') { return; } else if (file === 'abi.js') { @@ -286,15 +313,19 @@ Config.prototype.loadFiles = function(files) { return readFiles; }; -Config.prototype.loadPluginContractFiles = function() { +Config.prototype.loadPluginContractFiles = function () { let self = this; let contractsPlugins = this.plugins.getPluginsFor('contractFiles'); if (contractsPlugins.length > 0) { - contractsPlugins.forEach(function(plugin) { - plugin.contractsFiles.forEach(function(file) { - let filename = file.replace('./',''); - self.contractsFiles.push({filename: filename, content: plugin.loadPluginFile(file), path: plugin.pathToFile(file)}); + contractsPlugins.forEach(function (plugin) { + plugin.contractsFiles.forEach(function (file) { + let filename = file.replace('./', ''); + self.contractsFiles.push({ + filename: filename, + content: plugin.loadPluginFile(file), + path: plugin.pathToFile(file) + }); }); }); } diff --git a/lib/core/core.js b/lib/core/core.js index 5632edd25..04a700d02 100644 --- a/lib/core/core.js +++ b/lib/core/core.js @@ -1,5 +1,5 @@ +class Core { -let Core = function() {}; - +} module.exports = Core; diff --git a/lib/core/engine.js b/lib/core/engine.js index e107fadcb..254e608f4 100644 --- a/lib/core/engine.js +++ b/lib/core/engine.js @@ -1,27 +1,27 @@ let http = require('http'); let Web3 = require('web3'); let utils = require('../utils/utils.js'); - let Events = require('./events.js'); let Logger = require('./logger.js'); let Config = require('./config.js'); - let DeployManager = require('../contracts/deploy_manager.js'); let ABIGenerator = require('../contracts/abi.js'); let ServicesMonitor = require('./services_monitor.js'); let Pipeline = require('../pipeline/pipeline.js'); -let Server = require('../pipeline/server.js'); +let Serve = require('../pipeline/server.js'); let Watch = require('../pipeline/watch.js'); -let version = require('../../package.json').version; +let version = require('../../package.json'); -let Engine = function(options) { - this.env = options.env; - this.embarkConfig = options.embarkConfig; - this.interceptLogs = options.interceptLogs; - this.version = version; -}; +class Engine { + constructor(options) { + this.env = options.env; + this.embarkConfig = options.embarkConfig; + this.interceptLogs = options.interceptLogs; + this.version = version; + } +} -Engine.prototype.init = function(_options) { +Engine.prototype.init = function (_options) { let self = this; let options = _options || {}; this.events = new Events(); @@ -31,17 +31,17 @@ Engine.prototype.init = function(_options) { this.plugins = this.config.plugins; this.servicesMonitor = new ServicesMonitor({events: this.events, logger: this.logger}); - this.servicesMonitor.addCheck('embarkVersion', function(cb) { + this.servicesMonitor.addCheck('embarkVersion', function (cb) { return cb({name: 'Embark ' + self.version, status: 'green'}); }, 0); }; -Engine.prototype.startMonitor = function() { +Engine.prototype.startMonitor = function () { let self = this; if (this.plugins) { let servicePlugins = this.plugins.getPluginsFor('serviceChecks'); - servicePlugins.forEach(function(plugin) { - plugin.serviceChecks.forEach(function(pluginCheck) { + servicePlugins.forEach(function (plugin) { + plugin.serviceChecks.forEach(function (pluginCheck) { self.servicesMonitor.addCheck(pluginCheck.checkName, pluginCheck.checkFn, pluginCheck.time); }); }); @@ -49,17 +49,17 @@ Engine.prototype.startMonitor = function() { this.servicesMonitor.startMonitor(); }; -Engine.prototype.startService = function(serviceName, _options) { +Engine.prototype.startService = function (serviceName, _options) { let options = _options || {}; let services = { - "pipeline": this.pipelineService, - "abi": this.abiService, - "deployment": this.deploymentService, + "pipeline": this.pipelineService, + "abi": this.abiService, + "deployment": this.deploymentService, "fileWatcher": this.fileWatchService, - "webServer": this.webServerService, - "ipfs": this.ipfsService, - "web3": this.web3Service + "webServer": this.webServerService, + "ipfs": this.ipfsService, + "web3": this.web3Service }; let service = services[serviceName]; @@ -73,7 +73,7 @@ Engine.prototype.startService = function(serviceName, _options) { return service.apply(this, [options]); }; -Engine.prototype.pipelineService = function(options) { +Engine.prototype.pipelineService = function (options) { let self = this; this.logger.setStatus("Building Assets"); let pipeline = new Pipeline({ @@ -83,7 +83,7 @@ Engine.prototype.pipelineService = function(options) { logger: this.logger, plugins: this.plugins }); - this.events.on('abi', function(abi) { + this.events.on('abi', function (abi) { self.currentAbi = abi; pipeline.build(abi); self.events.emit('outputDone'); @@ -99,9 +99,9 @@ Engine.prototype.pipelineService = function(options) { //}); }; -Engine.prototype.abiService = function(options) { +Engine.prototype.abiService = function (options) { let self = this; - let generateABICode = function(contractsManager) { + let generateABICode = function (contractsManager) { let abiGenerator = new ABIGenerator({ blockchainConfig: self.config.blockchainConfig, contractsManager: contractsManager, @@ -121,7 +121,7 @@ Engine.prototype.abiService = function(options) { this.events.on('blockchainDisabled', generateABICode); }; -Engine.prototype.deploymentService = function(options) { +Engine.prototype.deploymentService = function (options) { let self = this; this.deployManager = new DeployManager({ web3: options.web3 || self.web3, @@ -132,29 +132,32 @@ Engine.prototype.deploymentService = function(options) { events: this.events }); - this.events.on('file-event', function(fileType, path) { + this.events.on('file-event', function (fileType, path) { // TODO: for now need to deploy on asset chanes as well // because the contractsManager config is corrupted after a deploy //if (fileType === 'contract' || fileType === 'config') { - self.config.reloadConfig(); - self.deployManager.deployContracts(function() {}); + self.config.reloadConfig(); + self.deployManager.deployContracts(function () { + }); //} }); }; -Engine.prototype.fileWatchService = function(options) { +Engine.prototype.fileWatchService = function (options) { this.logger.setStatus("Watching for changes"); let watch = new Watch({logger: this.logger, events: this.events}); watch.start(); }; -Engine.prototype.webServerService = function(options) { +Engine.prototype.webServerService = function (options) { let self = this; let webServerConfig = this.config.webServerConfig; - if (!webServerConfig.enabled) { return; } + if (!webServerConfig.enabled) { + return; + } let host = options.host || webServerConfig.host; - let port = options.port || webServerConfig.port; + let port = options.port || webServerConfig.port; this.logger.setStatus("Starting Server"); let server = new Server({ @@ -163,43 +166,43 @@ Engine.prototype.webServerService = function(options) { port: port }); - self.servicesMonitor.addCheck('Webserver', function(cb) { + self.servicesMonitor.addCheck('Webserver', function (cb) { let devServer = 'Webserver (http://' + host + ':' + port + ')'; return cb({name: devServer, status: 'green'}); }); - server.start(function(){ + server.start(function () { }); }; -Engine.prototype.ipfsService = function(options) { +Engine.prototype.ipfsService = function (options) { let self = this; - self.servicesMonitor.addCheck('IPFS', function(cb) { - utils.checkIsAvailable('http://localhost:5001', function(available) { + self.servicesMonitor.addCheck('IPFS', function (cb) { + utils.checkIsAvailable('http://localhost:5001', function (available) { if (available) { //Ideally this method should be in an IPFS API JSONRPC wrapper //The URL should also be flexible to accept non-default IPFS url self.logger.trace("Checking IPFS version..."); - http.get('http://localhost:5001/api/v0/version', function(res) { + http.get('http://localhost:5001/api/v0/version', function (res) { let body = ''; - res.on('data', function(d) { + res.on('data', function (d) { body += d; }); - res.on('end', function() { - try{ + res.on('end', function () { + try { let parsed = JSON.parse(body); - if(parsed.Version){ + if (parsed.Version) { return cb({name: ("IPFS " + parsed.Version), status: 'green'}); } - else{ + else { return cb({name: "IPFS ", status: 'green'}); } } - catch (e){ + catch (e) { return cb({name: "IPFS ", status: 'red'}); } }); - res.on('error', function(err) { + res.on('error', function (err) { self.logger.trace("Check IPFS version error: " + err); return cb({name: "IPFS ", status: 'red'}); }); @@ -212,7 +215,7 @@ Engine.prototype.ipfsService = function(options) { }); }; -Engine.prototype.web3Service = function(options) { +Engine.prototype.web3Service = function (options) { let self = this; this.web3 = options.web3; if (this.web3 === undefined) { @@ -221,16 +224,19 @@ Engine.prototype.web3Service = function(options) { this.web3.setProvider(new this.web3.providers.HttpProvider(web3Endpoint)); } - self.servicesMonitor.addCheck('Ethereum', function(cb) { + self.servicesMonitor.addCheck('Ethereum', function (cb) { if (self.web3.isConnected()) { - return cb({name: (self.web3.version.node.split("/")[0] + " " + self.web3.version.node.split("/")[1].split("-")[0] + " (Ethereum)"), status: 'green'}); + return cb({ + name: (self.web3.version.node.split("/")[0] + " " + self.web3.version.node.split("/")[1].split("-")[0] + " (Ethereum)"), + status: 'green' + }); } else { return cb({name: "No Blockchain node found", status: 'red'}); } }); - self.servicesMonitor.addCheck('Whisper', function(cb) { - self.web3.version.getWhisper(function(err, res) { + self.servicesMonitor.addCheck('Whisper', function (cb) { + self.web3.version.getWhisper(function (err, res) { if (err) { return cb({name: 'Whisper', status: 'red'}); } else { diff --git a/lib/core/events.js b/lib/core/events.js index b3fbe8864..ebb3992ee 100644 --- a/lib/core/events.js +++ b/lib/core/events.js @@ -1,4 +1,12 @@ //TODO: This is deprecated because Embark extends EventEmitter now -let EventEmitter = require('events'); +let events = require('events'); + +class EventEmitter { + constructor(options) { + this.options = options; + } +} + +EventEmitter.prototype = Object.create(events.EventEmitter.prototype); module.exports = EventEmitter; diff --git a/lib/core/fs.js b/lib/core/fs.js index 56d8aefaa..8b3be66a6 100644 --- a/lib/core/fs.js +++ b/lib/core/fs.js @@ -25,7 +25,7 @@ function writeJSONSync() { return fs.writeJSONSync.apply(fs.writeJSONSync, arguments); } -function existsSync(){ +function existsSync() { return fs.existsSync.apply(fs.existsSync, arguments); } diff --git a/lib/core/logger.js b/lib/core/logger.js index f8fa4ebad..729d6a172 100644 --- a/lib/core/logger.js +++ b/lib/core/logger.js @@ -1,39 +1,52 @@ let colors = require('colors'); -let Logger = function(options) { - this.logLevels = ['error', 'warn', 'info', 'debug', 'trace']; - this.logLevel = options.logLevel || 'info'; - this.logFunction = options.logFunction || console.log; - this.contractsState = options.contractsState || function() {}; - this.setStatus = options.setStatus || console.log; -}; +class Logger { + constructor(options) { + this.logLevels = ['error', 'warn', 'info', 'debug', 'trace']; + this.logLevel = options.logLevel || 'info'; + this.logFunction = options.logFunction || console.log; + this.contractsState = options.contractsState || function () { + }; + this.setStatus = options.setStatus || console.log; + } +} -Logger.prototype.error = function(txt) { - if (!(this.shouldLog('error'))) { return; } +Logger.prototype.error = function (txt) { + if (!(this.shouldLog('error'))) { + return; + } this.logFunction(txt.red); }; -Logger.prototype.warn = function(txt) { - if (!(this.shouldLog('warn'))) { return; } +Logger.prototype.warn = function (txt) { + if (!(this.shouldLog('warn'))) { + return; + } this.logFunction(txt.yellow); }; -Logger.prototype.info = function(txt) { - if (!(this.shouldLog('info'))) { return; } +Logger.prototype.info = function (txt) { + if (!(this.shouldLog('info'))) { + return; + } this.logFunction(txt.green); }; -Logger.prototype.debug = function(txt) { - if (!(this.shouldLog('debug'))) { return; } +Logger.prototype.debug = function (txt) { + if (!(this.shouldLog('debug'))) { + return; + } this.logFunction(txt); }; -Logger.prototype.trace = function(txt) { - if (!(this.shouldLog('trace'))) { return; } +Logger.prototype.trace = function (txt) { + if (!(this.shouldLog('trace'))) { + return; + } this.logFunction(txt); }; -Logger.prototype.shouldLog = function(level) { +Logger.prototype.shouldLog = function (level) { return (this.logLevels.indexOf(level) <= this.logLevels.indexOf(this.logLevel)); }; diff --git a/lib/core/plugin.js b/lib/core/plugin.js index 86af207a5..adef6da96 100644 --- a/lib/core/plugin.js +++ b/lib/core/plugin.js @@ -3,38 +3,40 @@ let fs = require('./fs.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]; +class Plugin { + constructor(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]); + } + } + + this.clientWeb3Providers = []; + this.contractsGenerators = []; + this.pipeline = []; + this.pipelineFiles = []; + this.console = []; + this.contractsConfigs = []; + this.contractsFiles = []; + this.compilers = []; + this.serviceChecks = []; + this.pluginTypes = []; + + if (!(this instanceof Plugin)) { + return new Plugin(); } } - 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]); - } - } - - this.clientWeb3Providers = []; - this.contractsGenerators = []; - this.pipeline = []; - this.pipelineFiles = []; - this.console = []; - this.contractsConfigs = []; - this.contractsFiles = []; - this.compilers = []; - this.serviceChecks = []; - this.pluginTypes = []; - - if (!(this instanceof Plugin)) { - return new Plugin(); - } -}; - -Plugin.prototype.runPlugin = Plugin.prototype.run = function() { +Plugin.prototype.runPlugin = Plugin.prototype.run = function () { if (this.shouldInterceptLogs) { this.interceptLogs(this.pluginModule); } @@ -42,15 +44,15 @@ Plugin.prototype.runPlugin = Plugin.prototype.run = function() { this.call(this.loadPluginFile(fullyQualifiedPath), this); }; -Plugin.prototype.loadPluginFile = function(filename) { +Plugin.prototype.loadPluginFile = function (filename) { return fs.readFileSync(this.pathToFile(filename)).toString(); }; -Plugin.prototype.pathToFile = function(filename) { +Plugin.prototype.pathToFile = function (filename) { return utils.joinPath(this.pluginPath, filename); }; -Plugin.prototype.interceptLogs = function(context) { +Plugin.prototype.interceptLogs = function (context) { let self = this; // TODO: this is a bit nasty, figure out a better way context.console = context.console || console; @@ -60,20 +62,20 @@ Plugin.prototype.interceptLogs = function(context) { // //self.logger.error.apply(self.logger, arguments); // self.logger.error(self.name + " > " + txt); //}; - context.console.log = function(txt) { + context.console.log = function (txt) { self.logger.info(self.name + " > " + txt); }; - context.console.warn = function(txt) { + context.console.warn = function (txt) { self.logger.warn(self.name + " > " + txt); }; - context.console.info = function(txt) { + context.console.info = function (txt) { self.logger.info(self.name + " > " + txt); }; - context.console.debug = function(txt) { + context.console.debug = function (txt) { // TODO: ue JSON.stringify self.logger.debug(self.name + " > " + txt); }; - context.console.trace = function(txt) { + context.console.trace = function (txt) { self.logger.trace(self.name + " > " + txt); }; }; @@ -92,90 +94,90 @@ Plugin.prototype.register = function (classname, cb) { }); // TODO: add deploy provider -Plugin.prototype.registerClientWeb3Provider = function(cb) { +Plugin.prototype.registerClientWeb3Provider = function (cb) { this.clientWeb3Providers.push(cb); this.pluginTypes.push('clientWeb3Provider'); }; -Plugin.prototype.registerContractsGeneration = function(cb) { +Plugin.prototype.registerContractsGeneration = function (cb) { this.contractsGenerators.push(cb); this.pluginTypes.push('contractGeneration'); }; -Plugin.prototype.registerPipeline = function(matcthingFiles, cb) { +Plugin.prototype.registerPipeline = function (matcthingFiles, cb) { // TODO: generate error for more than one pipeline per plugin this.pipeline.push({matcthingFiles: matcthingFiles, cb: cb}); this.pluginTypes.push('pipeline'); }; -Plugin.prototype.addFileToPipeline = function(file, intendedPath, options) { +Plugin.prototype.addFileToPipeline = function (file, intendedPath, options) { this.pipelineFiles.push({file: file, intendedPath: intendedPath, options: options}); this.pluginTypes.push('pipelineFiles'); }; -Plugin.prototype.addContractFile = function(file) { +Plugin.prototype.addContractFile = function (file) { this.contractsFiles.push(file); this.pluginTypes.push('contractFiles'); }; -Plugin.prototype.registerConsoleCommand = function(cb) { +Plugin.prototype.registerConsoleCommand = function (cb) { this.console.push(cb); this.pluginTypes.push('console'); }; -Plugin.prototype.registerServiceCheck = function(checkName, checkFn, time) { +Plugin.prototype.registerServiceCheck = function (checkName, checkFn, time) { this.serviceChecks.push({checkName: checkName, checkFn: checkFn, time: time}); this.pluginTypes.push('serviceChecks'); }; -Plugin.prototype.has = function(pluginType) { +Plugin.prototype.has = function (pluginType) { return this.pluginTypes.indexOf(pluginType) >= 0; }; -Plugin.prototype.generateProvider = function(args) { - return this.clientWeb3Providers.map(function(cb) { +Plugin.prototype.generateProvider = function (args) { + return this.clientWeb3Providers.map(function (cb) { return cb.call(this, args); }).join("\n"); }; -Plugin.prototype.generateContracts = function(args) { - return this.contractsGenerators.map(function(cb) { +Plugin.prototype.generateContracts = function (args) { + return this.contractsGenerators.map(function (cb) { return cb.call(this, args); }).join("\n"); }; -Plugin.prototype.registerContractConfiguration = function(config) { +Plugin.prototype.registerContractConfiguration = function (config) { this.contractsConfigs.push(config); this.pluginTypes.push('contractsConfig'); }; -Plugin.prototype.registerCompiler = function(extension, cb) { +Plugin.prototype.registerCompiler = function (extension, cb) { this.compilers.push({extension: extension, cb: cb}); this.pluginTypes.push('compilers'); }; -Plugin.prototype.runCommands = function(cmd, options) { - return this.console.map(function(cb) { +Plugin.prototype.runCommands = function (cmd, options) { + return this.console.map(function (cb) { return cb.call(this, cmd, options); }).join("\n"); }; -Plugin.prototype.runFilePipeline = function() { +Plugin.prototype.runFilePipeline = function () { let self = this; - return this.pipelineFiles.map(function(file) { - let obj = {}; - obj.filename = file.file.replace('./',''); - obj.content = self.loadPluginFile(file.file).toString(); - obj.intendedPath = file.intendedPath; - obj.options = file.options; - obj.path = self.pathToFile(obj.filename); + return this.pipelineFiles.map(function (file) { + let obj = {}; + obj.filename = file.file.replace('./', ''); + obj.content = self.loadPluginFile(file.file).toString(); + obj.intendedPath = file.intendedPath; + obj.options = file.options; + obj.path = self.pathToFile(obj.filename); - return obj; + return obj; }); }; -Plugin.prototype.runPipeline = function(args) { +Plugin.prototype.runPipeline = function (args) { // TODO: should iterate the pipelines let pipeline = this.pipeline[0]; let shouldRunPipeline = utils.fileMatchesPattern(pipeline.matcthingFiles, args.targetFile); diff --git a/lib/core/plugins.js b/lib/core/plugins.js index bbfbd1f43..17aea472d 100644 --- a/lib/core/plugins.js +++ b/lib/core/plugins.js @@ -1,52 +1,53 @@ const _ = require('underscore'); 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); - }); - -}; - -Plugins.prototype.load = Plugins.prototype.loadPlugins = function () { - let pluginConfig; - for (let i = 0; this.config.plugins.length > i; i++) { - pluginConfig = this.config.plugins[i].config; - let Plugin = require('./plugin'); - let plugin = new Plugin(pluginConfig); - plugin.run(); - } -}; - -Plugins.prototype.listPlugins = function () { - return this.config.plugins.join(', '); -}; - -let getPluginsFor = function (pluginType, plugins) { +const getPluginsFor = function (pluginType, plugins) { return _.filter(plugins, pluginType); }; -Plugins.prototype.getPluginsFor = getPluginsFor; +class Plugins extends EventEmitter { + constructor(options) { + super(); + //TODO: put an observer on this.plugins and call loadPlugin when a new item is added + this.config = {}; -Plugins.prototype = Object.create(EventEmitter.prototype); + const loadPlugins = this.load; + 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); + }); + } + + load() { + let pluginConfig; + for (let i = 0; this.config.plugins.length > i; i++) { + pluginConfig = this.config.plugins[i].config; + let Plugin = require('./plugin'); + let plugin = new Plugin(pluginConfig); + plugin.run(); + } + } + + listPlugins() { + return this.config.plugins.join(', '); + } + +} module.exports = Plugins; \ No newline at end of file diff --git a/lib/core/runCode.js b/lib/core/runCode.js index 6c89be039..765bd2658 100644 --- a/lib/core/runCode.js +++ b/lib/core/runCode.js @@ -8,7 +8,7 @@ let web3; // ====================== function doEval(code, _web3) { if (_web3) { - web3 = _web3; + let web3 = _web3; } return eval(code); // jshint ignore:line } diff --git a/lib/core/services_monitor.js b/lib/core/services_monitor.js index d221f0876..1bc65e102 100644 --- a/lib/core/services_monitor.js +++ b/lib/core/services_monitor.js @@ -3,22 +3,27 @@ let async = require('../utils/async_extend.js'); // TODO: need to separate colors from states // i.e use status: /on|off|warn/ not /red|green/ // it's up to the logger or console to determine the color -let ServicesMonitor = function(options) { - this.events = options.events; - this.logger = options.logger; - this.checkList = {}; - this.checkTimers = {}; - this.checkState = {}; - this.working = false; -}; +class ServicesMonitor { + constructor(options) { + this.events = options.events; + this.logger = options.logger; + this.checkList = {}; + this.checkTimers = {}; + this.checkState = {}; + this.working = false; + } +} +; -ServicesMonitor.prototype.initCheck = function(checkName) { +ServicesMonitor.prototype.initCheck = function (checkName) { let self = this; let check = this.checkList[checkName]; - if (!check) { return false; } + if (!check) { + return false; + } - self.events.on('check:' + checkName, function(obj) { + self.events.on('check:' + checkName, function (obj) { // TODO: see todo above if (check && check.status === 'red' && obj.status === 'green') { self.events.emit('check:backOnline:' + checkName); @@ -32,19 +37,19 @@ ServicesMonitor.prototype.initCheck = function(checkName) { }); if (check.interval !== 0) { - self.checkTimers[checkName] = setInterval(function() { - check.fn.call(check.fn, function(obj) { + self.checkTimers[checkName] = setInterval(function () { + check.fn.call(check.fn, function (obj) { self.events.emit('check:' + checkName, obj); }); }, check.interval); } - check.fn.call(check.fn, function(obj) { + check.fn.call(check.fn, function (obj) { self.events.emit('check:' + checkName, obj); }); }; -ServicesMonitor.prototype.addCheck = function(checkName, checkFn, time) { +ServicesMonitor.prototype.addCheck = function (checkName, checkFn, time) { let self = this; this.logger.trace('add check: ' + checkName); this.checkList[checkName] = {fn: checkFn, interval: time || 5000}; @@ -54,22 +59,22 @@ ServicesMonitor.prototype.addCheck = function(checkName, checkFn, time) { } }; -ServicesMonitor.prototype.stopCheck = function(name) { +ServicesMonitor.prototype.stopCheck = function (name) { clearInterval(this.checkTimers[name]); delete this.checkTimers[name]; delete this.checkList[name]; delete this.checkState[name]; }; -ServicesMonitor.prototype.startMonitor = function() { +ServicesMonitor.prototype.startMonitor = function () { let self = this; this.working = true; this.logger.trace('startMonitor'); - async.eachObject(this.checkList, function(checkName, check, callback) { + async.eachObject(this.checkList, function (checkName, check, callback) { self.initCheck(checkName); callback(); - }, function(err) { + }, function (err) { if (err) { self.logger.error("error running service check"); self.logger.error(err.message); diff --git a/lib/core/test.js b/lib/core/test.js index 5117702d0..c52ff1a12 100644 --- a/lib/core/test.js +++ b/lib/core/test.js @@ -1,4 +1,4 @@ -let getSimulator = function() { +let getSimulator = function () { try { return require('ethereumjs-testrpc'); } catch (e) { @@ -17,15 +17,16 @@ let getSimulator = function() { } }; -let Test; -Test = (function (options) { - let async = require('async'); - let opts = options === undefined ? {} : options; - opts.logLevel = opts.hasOwnProperty('logLevel') ? opts.logLevel : 'debug'; - opts.simulatorOptions = opts.hasOwnProperty('simulatorOptions') ? opts.simulatorOptions : {}; - let sim = getSimulator(); - function newWebThree() { +class Test { + constructor(options) { + let opts = options === undefined ? {} : options; + opts.logLevel = opts.hasOwnProperty('logLevel') ? opts.logLevel : 'debug'; + opts.simulatorOptions = opts.hasOwnProperty('simulatorOptions') ? opts.simulatorOptions : {}; + let sim = getSimulator(); + } + + newWebThree() { try { let Web3 = require('web3'); let web3 = new Web3(); @@ -35,73 +36,6 @@ Test = (function (options) { throw new Error(e); } } - - function deployAll(contractsConfig, cb) { - let RunCode = require('./runCode.js'); - let self = this; - - function newEngine () { - let Engine = require('./engine.js'); - return new Engine({ - env: opts.env || 'test', - // TODO: confi will need to detect if this is a obj - embarkConfig: opts.embarkConfig || 'embark.json', - interceptLogs: false - }); - } - - self.web3 = newWebThree(); - self.engine = newEngine(); - self.engine.init(); - - async.waterfall([ - function getConfig(callback) { - self.engine.config.contractsConfig = {contracts: contractsConfig}; - callback(); - }, - function startServices(callback) { - //{abiType: 'contracts', embarkJS: false} - self.engine.startService("abi"); - self.engine.startService("deployment", { - web3: self.web3, - trackContracts: false - }); - callback(); - }, - function deploy(callback) { - self.engine.events.on('abi-contracts-vanila', function (vanillaABI) { - callback(null, vanillaABI); - }); - self.engine.deployManager.deployContracts(function (err, result) { - if (err) { - console.log(err); - callback(err); - } - }); - } - ], function (err, result) { - if (err) { - console.log("got error"); - process.exit(); - } - // this should be part of the waterfall and not just something done at the - // end - self.web3.eth.getAccounts(function (err, accounts) { - if (err) { - throw new Error(err); - } - self.web3.eth.defaultAccount = accounts[0]; - RunCode.doEval(result, self.web3); // jshint ignore:line - cb(); - }); - }); - } - - - return { - deployAll: deployAll, - sim: sim - }; -}()); +} module.exports = Test; diff --git a/lib/core/test_logger.js b/lib/core/test_logger.js index d1f8616d4..0d85baa01 100644 --- a/lib/core/test_logger.js +++ b/lib/core/test_logger.js @@ -2,51 +2,64 @@ let colors = require('colors'); // TODO: just logFunction changes, probably doesn't need a whole new module just // for this -let TestLogger = function(options) { - this.logLevels = ['error', 'warn', 'info', 'debug', 'trace']; - this.logs = []; - this.logLevel = options.logLevel || 'info'; -}; +class TestLogger { + constructor(options) { + this.logLevels = ['error', 'warn', 'info', 'debug', 'trace']; + this.logs = []; + this.logLevel = options.logLevel || 'info'; + } -TestLogger.prototype.logFunction = function() { - this.logs.push(arguments); -}; + logFunction() { + this.logs.push(arguments); + } -TestLogger.prototype.contractsState = function() { - this.logs.push(arguments); -}; + contractsState() { + this.logs.push(arguments); + } -TestLogger.prototype.availableServices = function() { - this.logs.push(arguments); -}; + availableServices() { + this.logs.push(arguments); + } -TestLogger.prototype.error = function(txt) { - if (!(this.shouldLog('error'))) { return; } - this.logFunction(txt.red); -}; + error(txt) { + if (!(this.shouldLog('error'))) { + return; + } + this.logFunction(txt.red); + } -TestLogger.prototype.warn = function(txt) { - if (!(this.shouldLog('warn'))) { return; } - this.logFunction(txt.yellow); -}; + warn(txt) { + if (!(this.shouldLog('warn'))) { + return; + } + this.logFunction(txt.yellow); + } -TestLogger.prototype.info = function(txt) { - if (!(this.shouldLog('info'))) { return; } - this.logFunction(txt.green); -}; + info(txt) { + if (!(this.shouldLog('info'))) { + return; + } + this.logFunction(txt.green); + } -TestLogger.prototype.debug = function(txt) { - if (!(this.shouldLog('debug'))) { return; } - this.logFunction(txt); -}; + debug(txt) { + if (!(this.shouldLog('debug'))) { + return; + } + this.logFunction(txt); + } -TestLogger.prototype.trace = function(txt) { - if (!(this.shouldLog('trace'))) { return; } - this.logFunction(txt); -}; + trace(txt) { + if (!(this.shouldLog('trace'))) { + return; + } + this.logFunction(txt); + } -TestLogger.prototype.shouldLog = function(level) { - return (this.logLevels.indexOf(level) <= this.logLevels.indexOf(this.logLevel)); -}; + shouldLog(level) { + return (this.logLevels.indexOf(level) <= this.logLevels.indexOf(this.logLevel)); + } + +} module.exports = TestLogger; diff --git a/lib/dashboard/command_history.js b/lib/dashboard/command_history.js index ba990ba8a..73c575611 100644 --- a/lib/dashboard/command_history.js +++ b/lib/dashboard/command_history.js @@ -1,28 +1,29 @@ - -let CommandHistory = function() { - this.history = []; - this.pointer = -1; -}; - -CommandHistory.prototype.addCommand = function(cmd) { - this.history.push(cmd); - this.pointer = this.history.length; -}; - -CommandHistory.prototype.getPreviousCommand = function(cmd) { - if (this.pointer >= 0) { - this.pointer--; +class CommandHistory { + constructor() { + this.history = []; + this.pointer = -1; } - return this.history[this.pointer]; -}; -CommandHistory.prototype.getNextCommand = function(cmd) { - if (this.pointer >= this.history.length) { - this.pointer = this.history.length - 1; - return ''; + addCommand(cmd) { + this.history.push(cmd); + this.pointer = this.history.length; } - this.pointer++; - return this.history[this.pointer]; -}; + + getPreviousCommand(cmd) { + if (this.pointer >= 0) { + this.pointer--; + } + return this.history[this.pointer]; + } + + getNextCommand(cmd) { + if (this.pointer >= this.history.length) { + this.pointer = this.history.length - 1; + return ''; + } + this.pointer++; + return this.history[this.pointer]; + } +} module.exports = CommandHistory; diff --git a/lib/dashboard/console.js b/lib/dashboard/console.js index 783d834b1..d4453dac1 100644 --- a/lib/dashboard/console.js +++ b/lib/dashboard/console.js @@ -1,63 +1,65 @@ let utils = require('../utils/utils.js'); let RunCode = require('../core/runCode.js'); -let Console = function(options) { - this.plugins = options.plugins; - this.version = options.version; -}; - -Console.prototype.runCode = function(code) { - RunCode.doEval(code); // jshint ignore:line -}; - -Console.prototype.processEmbarkCmd = function(cmd) { - if (cmd === 'help') { - let helpText = [ - 'Welcome to Embark ' + this.version, - '', - 'possible commands are:', - // TODO: only if the blockchain is actually active! - // will need to pass te current embark state here - 'web3 - instantiated web3.js object configured to the current environment', - 'quit - to immediatly exit', - '', - 'The web3 object and the interfaces for the deployed contracts and their methods are also available' - ]; - return helpText.join('\n'); - } else if (cmd === 'quit') { - utils.exit(); - } - return false; -}; - -Console.prototype.executeCmd = function(cmd, callback) { - let plugin, pluginOutput; - let plugins = []; - this.plugins.emit('get', 'console', (list) => { - plugins = list; - }); - for (let i = 0; i < plugins.length; i++) { - plugin = plugins[i]; - pluginOutput = plugin.runCommands(cmd, {}); - if (pluginOutput !== false && pluginOutput !== 'false') return callback(pluginOutput); +class Console { + constructor(options) { + this.plugins = options.plugins; + this.version = options.version; } - let output = this.processEmbarkCmd(cmd); - if (output) { - return callback(output); + runCode(code) { + RunCode.doEval(code); // jshint ignore:line } - try { - let result = RunCode.doEval(cmd); - return callback(result); + processEmbarkCmd (cmd) { + if (cmd === 'help') { + let helpText = [ + 'Welcome to Embark ' + this.version, + '', + 'possible commands are:', + // TODO: only if the blockchain is actually active! + // will need to pass te current embark state here + 'web3 - instantiated web3.js object configured to the current environment', + 'quit - to immediatly exit', + '', + 'The web3 object and the interfaces for the deployed contracts and their methods are also available' + ]; + return helpText.join('\n'); + } else if (cmd === 'quit') { + utils.exit(); + } + return false; } - catch(e) { - if (e.message.indexOf('not defined') > 0) { - return callback(("error: " + e.message).red + ("\nType " + "help".bold + " to see the list of available commands").cyan); - } else { - return callback(e.message); + + executeCmd(cmd, callback) { + let plugin, pluginOutput; + let plugins = []; + this.plugins.emit('get', 'console', (list) => { + plugins = list; + }); + for (let i = 0; i < plugins.length; i++) { + plugin = plugins[i]; + pluginOutput = plugin.runCommands(cmd, {}); + if (pluginOutput !== false && pluginOutput !== 'false') return callback(pluginOutput); + } + + let output = this.processEmbarkCmd(cmd); + if (output) { + return callback(output); + } + + try { + let result = RunCode.doEval(cmd); + return callback(result); + } + catch (e) { + if (e.message.indexOf('not defined') > 0) { + return callback(("error: " + e.message).red + ("\nType " + "help".bold + " to see the list of available commands").cyan); + } else { + return callback(e.message); + } } } -}; +} module.exports = Console; diff --git a/lib/dashboard/dashboard.js b/lib/dashboard/dashboard.js index c3222c247..9aa48b0cc 100644 --- a/lib/dashboard/dashboard.js +++ b/lib/dashboard/dashboard.js @@ -3,40 +3,43 @@ let async = require('async'); let Monitor = require('./monitor.js'); let Console = require('./console.js'); -let Dashboard = function(options) { - this.logger = options.logger; - this.plugins = options.plugins; - this.version = options.version; - this.env = options.env; -}; +class Dashboard { + constructor(options) { + this.logger = options.logger; + this.plugins = options.plugins; + this.version = options.version; + this.env = options.env; + } -Dashboard.prototype.start = function(done) { - let console, monitor; - let self = this; + start(done) { + let console, monitor; + let self = this; - async.waterfall([ - function startConsole(callback) { - console = new Console({plugins: self.plugins, version: self.version}); - callback(); - }, - function startMonitor(callback) { - monitor = new Monitor({env: self.env, console: console}); - self.logger.logFunction = monitor.logEntry; - self.logger.contractsState = monitor.setContracts; - self.logger.setStatus = monitor.setStatus.bind(monitor); + async.waterfall([ + function startConsole(callback) { + console = new Console({plugins: self.plugins, version: self.version}); + callback(); + }, + function startMonitor(callback) { + monitor = new Monitor({env: self.env, console: console}); + self.logger.logFunction = monitor.logEntry; + self.logger.contractsState = monitor.setContracts; + self.logger.setStatus = monitor.setStatus.bind(monitor); - self.logger.info('========================'.bold.green); - self.logger.info(('Welcome to Embark ' + self.version).yellow.bold); - self.logger.info('========================'.bold.green); + self.logger.info('========================'.bold.green); + self.logger.info(('Welcome to Embark ' + self.version).yellow.bold); + self.logger.info('========================'.bold.green); - // TODO: do this after monitor is rendered - callback(); - } - ], function() { - self.console = console; - self.monitor = monitor; - done(); - }); -}; + // TODO: do this after monitor is rendered + callback(); + } + ], function () { + self.console = console; + self.monitor = monitor; + done(); + }); + } + +} module.exports = Dashboard; diff --git a/lib/dashboard/monitor.js b/lib/dashboard/monitor.js index d70f6ce13..15fa56984 100644 --- a/lib/dashboard/monitor.js +++ b/lib/dashboard/monitor.js @@ -4,352 +4,354 @@ let blessed = require("blessed"); let CommandHistory = require('./command_history.js'); let version = require('../../package.json').version; -function Dashboard(options) { - let title = (options && options.title) || "Embark " + version; - this.env = options.env; - this.console = options.console; - this.history = new CommandHistory(); +class Dashboard { + constructor(options) { + let title = (options && options.title) || "Embark " + version; + this.env = options.env; + this.console = options.console; + this.history = new CommandHistory(); - this.color = (options && options.color) || "green"; - this.minimal = (options && options.minimal) || false; + this.color = (options && options.color) || "green"; + this.minimal = (options && options.minimal) || false; - this.screen = blessed.screen({ - smartCSR: true, - title: title, - dockBorders: false, - fullUnicode: true, - autoPadding: true - }); + this.screen = blessed.screen({ + smartCSR: true, + title: title, + dockBorders: false, + fullUnicode: true, + autoPadding: true + }); - this.layoutLog(); - this.layoutStatus(); - this.layoutModules(); - this.layoutCmd(); + this.layoutLog(); + this.layoutStatus(); + this.layoutModules(); + this.layoutCmd(); - this.screen.key(["C-c"], function() { - process.exit(0); - }); + this.screen.key(["C-c"], function () { + process.exit(0); + }); - this.logEntry = this.logEntry.bind(this); - this.setContracts = this.setContracts.bind(this); - this.availableServices = this.availableServices.bind(this); + this.logEntry = this.logEntry.bind(this); + this.setContracts = this.setContracts.bind(this); + this.availableServices = this.availableServices.bind(this); - this.status.setContent(this.env.green); + this.status.setContent(this.env.green); - this.screen.render(); - this.input.focus(); -} - -Dashboard.prototype.availableServices = function(_services) { - let services = []; - let checkName; - for (checkName in _services) { - services.push(_services[checkName]); + this.screen.render(); + this.input.focus(); } - this.progress.setContent(services.join('\n')); - this.screen.render(); -}; - -Dashboard.prototype.setStatus = function(status) { - this.operations.setContent(status); - this.screen.render(); -}; - -Dashboard.prototype.setContracts = function(contracts) { - let data = []; - - data.push(["Contract Name", "Address", "Status"]); - - contracts.forEach(function(row) { - data.push(row); - }); - - this.moduleTable.setData(data); - this.screen.render(); -}; - -Dashboard.prototype.logEntry = function(text) { - this.logText.log(text); - this.screen.render(); -}; - -Dashboard.prototype.layoutLog = function() { - this.log = blessed.box({ - label: "Logs", - padding: 1, - width: "100%", - height: "55%", - left: "0%", - top: "42%", - border: { - type: "line" - }, - style: { - fg: -1, - border: { - fg: this.color - } + availableServices(_services) { + let services = []; + let checkName; + for (checkName in _services) { + services.push(_services[checkName]); } - }); - this.logText = blessed.log({ - parent: this.log, - tags: true, - width: "100%-5", - //height: '90%', - scrollable: true, - input: false, - alwaysScroll: true, - scrollbar: { - ch: " ", - inverse: true - }, - keys: false, - vi: false, - mouse: true - }); + this.progress.setContent(services.join('\n')); + this.screen.render(); + } - this.screen.append(this.log); -}; + setStatus(status) { + this.operations.setContent(status); + this.screen.render(); + } -Dashboard.prototype.layoutModules = function() { - this.modules = blessed.box({ - label: "Contracts", - tags: true, - padding: 1, - width: "75%", - height: "42%", - left: "0%", - top: "0", - border: { - type: "line" - }, - style: { - fg: -1, + setContracts(contracts) { + let data = []; + + data.push(["Contract Name", "Address", "Status"]); + + contracts.forEach(function (row) { + data.push(row); + }); + + this.moduleTable.setData(data); + this.screen.render(); + } + + logEntry(text) { + this.logText.log(text); + this.screen.render(); + } + + layoutLog() { + this.log = blessed.box({ + label: "Logs", + padding: 1, + width: "100%", + height: "55%", + left: "0%", + top: "42%", border: { - fg: this.color + type: "line" + }, + style: { + fg: -1, + border: { + fg: this.color + } } - } - }); + }); - this.moduleTable = blessed.table({ - parent: this.modules, - height: "100%", - width: "100%-5", - align: "left", - pad: 1, - margin: "auto", - shrink: true, - scrollable: true, - alwaysScroll: true, - scrollbar: { - ch: " ", - inverse: true - }, - keys: false, - vi: false, - mouse: true, - data: [["ContractName", "Address", "Status"]] - }); + this.logText = blessed.log({ + parent: this.log, + tags: true, + width: "100%-5", + //height: '90%', + scrollable: true, + input: false, + alwaysScroll: true, + scrollbar: { + ch: " ", + inverse: true + }, + keys: false, + vi: false, + mouse: true + }); - this.screen.append(this.modules); -}; + this.screen.append(this.log); + } -Dashboard.prototype.layoutAssets = function() { - this.assets = blessed.box({ - label: "Asset Pipeline", - tags: true, - padding: 1, - width: "50%", - height: "55%", - left: "50%", - top: "42%", - border: { - type: "line" - }, - style: { - fg: -1, + layoutModules() { + this.modules = blessed.box({ + label: "Contracts", + tags: true, + padding: 1, + width: "75%", + height: "42%", + left: "0%", + top: "0", border: { - fg: this.color + type: "line" + }, + style: { + fg: -1, + border: { + fg: this.color + } } - } - }); + }); - this.assetTable = blessed.table({ - parent: this.assets, - height: "100%", - width: "100%-5", - align: "left", - pad: 1, - scrollable: true, - alwaysScroll: true, - scrollbar: { - ch: " ", - inverse: true - }, - keys: false, - vi: false, - mouse: true, - data: [["Name", "Size"]] - }); + this.moduleTable = blessed.table({ + parent: this.modules, + height: "100%", + width: "100%-5", + align: "left", + pad: 1, + margin: "auto", + shrink: true, + scrollable: true, + alwaysScroll: true, + scrollbar: { + ch: " ", + inverse: true + }, + keys: false, + vi: false, + mouse: true, + data: [["ContractName", "Address", "Status"]] + }); - this.screen.append(this.assets); -}; + this.screen.append(this.modules); + } -Dashboard.prototype.layoutStatus = function() { - - this.wrapper = blessed.layout({ - width: "25%", - height: "42%", - top: "0%", - left: "75%", - layout: "grid" - }); - - this.status = blessed.box({ - parent: this.wrapper, - label: "Environment", - tags: true, - padding: { - left: 1 - }, - width: "100%", - height: "20%", - valign: "middle", - border: { - type: "line" - }, - style: { - fg: -1, + layoutAssets() { + this.assets = blessed.box({ + label: "Asset Pipeline", + tags: true, + padding: 1, + width: "50%", + height: "55%", + left: "50%", + top: "42%", border: { - fg: this.color + type: "line" + }, + style: { + fg: -1, + border: { + fg: this.color + } } - } - }); + }); - this.operations = blessed.box({ - parent: this.wrapper, - label: "Status", - tags: true, - padding: { - left: 1 - }, - width: "100%", - height: "20%", - valign: "middle", - border: { - type: "line" - }, - style: { - fg: -1, + this.assetTable = blessed.table({ + parent: this.assets, + height: "100%", + width: "100%-5", + align: "left", + pad: 1, + scrollable: true, + alwaysScroll: true, + scrollbar: { + ch: " ", + inverse: true + }, + keys: false, + vi: false, + mouse: true, + data: [["Name", "Size"]] + }); + + this.screen.append(this.assets); + } + + layoutStatus() { + + this.wrapper = blessed.layout({ + width: "25%", + height: "42%", + top: "0%", + left: "75%", + layout: "grid" + }); + + this.status = blessed.box({ + parent: this.wrapper, + label: "Environment", + tags: true, + padding: { + left: 1 + }, + width: "100%", + height: "20%", + valign: "middle", border: { - fg: this.color + type: "line" + }, + style: { + fg: -1, + border: { + fg: this.color + } } - } - }); + }); - this.progress = blessed.box({ - parent: this.wrapper, - label: "Available Services", - tags: true, - padding: this.minimal ? { - left: 1 - } : 1, - width: "100%", - height: "60%", - valign: "top", - border: { - type: "line" - }, - style: { - fg: -1, + this.operations = blessed.box({ + parent: this.wrapper, + label: "Status", + tags: true, + padding: { + left: 1 + }, + width: "100%", + height: "20%", + valign: "middle", border: { - fg: this.color + type: "line" + }, + style: { + fg: -1, + border: { + fg: this.color + } } - } - }); + }); - this.screen.append(this.wrapper); -}; - - -Dashboard.prototype.layoutCmd = function() { - this.consoleBox = blessed.box({ - label: 'Console', - tags: true, - padding: 0, - width: '100%', - height: '6%', - left: '0%', - top: '95%', - border: { - type: 'line' - }, - style: { - fg: 'black', + this.progress = blessed.box({ + parent: this.wrapper, + label: "Available Services", + tags: true, + padding: this.minimal ? { + left: 1 + } : 1, + width: "100%", + height: "60%", + valign: "top", border: { - fg: this.color + type: "line" + }, + style: { + fg: -1, + border: { + fg: this.color + } } - } - }); + }); - this.input = blessed.textbox({ - parent: this.consoleBox, - name: 'input', - input: true, - keys: false, - top: 0, - left: 1, - height: '50%', - width: '100%-2', - inputOnFocus: true, - style: { - fg: 'green', - bg: 'black', - focus: { + this.screen.append(this.wrapper); + } + + layoutCmd() { + this.consoleBox = blessed.box({ + label: 'Console', + tags: true, + padding: 0, + width: '100%', + height: '6%', + left: '0%', + top: '95%', + border: { + type: 'line' + }, + style: { + fg: 'black', + border: { + fg: this.color + } + } + }); + + this.input = blessed.textbox({ + parent: this.consoleBox, + name: 'input', + input: true, + keys: false, + top: 0, + left: 1, + height: '50%', + width: '100%-2', + inputOnFocus: true, + style: { + fg: 'green', bg: 'black', - fg: 'green' + focus: { + bg: 'black', + fg: 'green' + } } - } - }); + }); - let self = this; + let self = this; - this.input.key(["C-c"], function() { - process.exit(0); - }); + this.input.key(["C-c"], function () { + process.exit(0); + }); - this.input.key(["C-w"], function() { - self.input.clearValue(); - self.input.focus(); - }); + this.input.key(["C-w"], function () { + self.input.clearValue(); + self.input.focus(); + }); - this.input.key(["up"], function() { - let cmd = self.history.getPreviousCommand(); - self.input.setValue(cmd); - self.input.focus(); - }); + this.input.key(["up"], function () { + let cmd = self.history.getPreviousCommand(); + self.input.setValue(cmd); + self.input.focus(); + }); - this.input.key(["down"], function() { - let cmd = self.history.getNextCommand(); - self.input.setValue(cmd); - self.input.focus(); - }); + this.input.key(["down"], function () { + let cmd = self.history.getNextCommand(); + self.input.setValue(cmd); + self.input.focus(); + }); - this.input.on('submit', function(data) { - if (data !== '') { - self.history.addCommand(data); - self.logText.log('console> '.bold.green + data); - self.console.executeCmd(data, function(result) { - self.logText.log(result); - }); - } - self.input.clearValue(); - self.input.focus(); - }); + this.input.on('submit', function (data) { + if (data !== '') { + self.history.addCommand(data); + self.logText.log('console> '.bold.green + data); + self.console.executeCmd(data, function (result) { + self.logText.log(result); + }); + } + self.input.clearValue(); + self.input.focus(); + }); - this.screen.append(this.consoleBox); -}; + this.screen.append(this.consoleBox); + } + +} module.exports = Dashboard; diff --git a/lib/index.js b/lib/index.js index 6f7f78490..d28c8a570 100644 --- a/lib/index.js +++ b/lib/index.js @@ -16,178 +16,188 @@ let Config = require('./core/config'); * @api public */ -let Embark = function (options) { - this.version = require('../package.json').version; +class Embark { + constructor(options) { + this.version = require('../package.json').version; - this.env = options.environment || options.env || "development"; + this.env = options.environment || options.env || "development"; - this.config = new Config({env: this.env, logger: this.logger, events: this.events}); - this.config.loadConfigFiles(options); - this.plugins = this.config.plugins; + this.config = new Config({env: this.env, logger: this.logger, events: this.events}); + this.config.loadConfigFiles(options); + this.plugins = this.config.plugins; - this.blockchain = function (env, client) { - return require('./cmds/blockchain/blockchain.js')(Embark.prototype.config.blockchainConfig, client, env).run(); - }; + this.blockchain = function (env, client) { + return require('./cmds/blockchain/blockchain.js')(Embark.prototype.config.blockchainConfig, client, env).run(); + }; - this.simulator = function (options) { - let Simulator = require('./cmds/simulator.js'); - let simulator = new Simulator({blockchainConfig: Embark.prototype.config.blockchainConfig}); - simulator.run(options); - }; + this.simulator = function (options) { + let Simulator = require('./cmds/simulator.js'); + let simulator = new Simulator({blockchainConfig: Embark.prototype.config.blockchainConfig}); + simulator.run(options); + }; - this.generateTemplate = function (templateName, destinationFolder, name) { - let TemplateGenerator = require('./cmds/template_generator.js'); - let templateGenerator = new TemplateGenerator(templateName); - templateGenerator.generate(destinationFolder, name); - }; + this.generateTemplate = function (templateName, destinationFolder, name) { + let TemplateGenerator = require('./cmds/template_generator.js'); + let templateGenerator = new TemplateGenerator(templateName); + templateGenerator.generate(destinationFolder, name); + }; - this.run = function (options) { - let Dashboard = require('./dashboard/dashboard.js'); - let Engine = require('./core/engine'); - let engine = new Engine({ - env: options.env, - embarkConfig: 'embark.json' - }); + this.run = function (options) { + let Dashboard = require('./dashboard/dashboard.js'); + let Engine = require('./core/engine'); + let engine = new Engine({ + env: options.env, + embarkConfig: 'embark.json' + }); - engine.init(); + engine.init(); - if (!options.useDashboard) { - console.log('========================'.bold.green); - console.log(('Welcome to Embark ' + Embark.version).yellow.bold); - console.log('========================'.bold.green); - } + if (!options.useDashboard) { + console.log('========================'.bold.green); + console.log(('Welcome to Embark ' + Embark.version).yellow.bold); + console.log('========================'.bold.green); + } - async.parallel([ - function startDashboard(callback) { - if (!options.useDashboard) { - return callback(); - } - - let dashboard = new Dashboard({ - logger: engine.logger, - plugins: engine.plugins, - version: engine.version, - env: engine.env - }); - dashboard.start(function () { - Embark.on('abi-vanila', function (abi) { - dashboard.console.runCode(abi); - }); - - engine.logger.info('dashboard start'); - Embark.on('servicesState', function (servicesState) { - dashboard.monitor.availableServices(servicesState); - }); - - callback(); - }); - }, - function (callback) { - let pluginList = engine.plugins.listPlugins(); - if (pluginList.length > 0) { - engine.logger.info("loaded plugins: " + pluginList.join(", ")); - } - - engine.startMonitor(); - engine.startService("web3"); - engine.startService("pipeline"); - engine.startService("abi"); - engine.startService("deployment"); - engine.startService("ipfs"); - - Embark.on('check:backOnline:Ethereum', function () { - engine.logger.info('Ethereum node detected..'); - engine.config.reloadConfig(); - engine.deployManager.deployContracts(function () { - engine.logger.info('Deployment Done'); - }); - }); - - engine.deployManager.deployContracts(function () { - engine.startService("fileWatcher"); - if (options.runWebserver) { - engine.startService("webServer", { - host: options.serverHost, - port: options.serverPort - }); + async.parallel([ + function startDashboard(callback) { + if (!options.useDashboard) { + return callback(); } - callback(); - }); - } - ], function (err) { - if (err) { - engine.logger.error(err.message); - } else { - 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("Ready".underline); - Embark.emit('firstDeploymentDone'); - } - }); - }; - this.build = function (options) { - let Engine = require('./core/engine'); + let dashboard = new Dashboard({ + logger: engine.logger, + plugins: engine.plugins, + version: engine.version, + env: engine.env + }); + dashboard.start(function () { + Embark.on('abi-vanila', function (abi) { + dashboard.console.runCode(abi); + }); - let engine = new Engine({ - env: options.env, - embarkConfig: 'embark.json', - interceptLogs: false - }); - engine.init(); + engine.logger.info('dashboard start'); + Embark.on('servicesState', function (servicesState) { + dashboard.monitor.availableServices(servicesState); + }); - async.waterfall([ - function startServices(callback) { - let pluginList = engine.plugins.listPlugins(); - if (pluginList.length > 0) { - engine.logger.info("loaded plugins: " + pluginList.join(", ")); + callback(); + }); + }, + function (callback) { + let pluginList = engine.plugins.listPlugins(); + if (pluginList.length > 0) { + engine.logger.info("loaded plugins: " + pluginList.join(", ")); + } + + engine.startMonitor(); + engine.startService("web3"); + engine.startService("pipeline"); + engine.startService("abi"); + engine.startService("deployment"); + engine.startService("ipfs"); + + Embark.on('check:backOnline:Ethereum', function () { + engine.logger.info('Ethereum node detected..'); + engine.config.reloadConfig(); + engine.deployManager.deployContracts(function () { + engine.logger.info('Deployment Done'); + }); + }); + + engine.deployManager.deployContracts(function () { + engine.startService("fileWatcher"); + if (options.runWebserver) { + engine.startService("webServer", { + host: options.serverHost, + port: options.serverPort + }); + } + callback(); + }); } + ], function (err) { + if (err) { + engine.logger.error(err.message); + } else { + 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("Ready".underline); + Embark.emit('firstDeploymentDone'); + } + }); + }; - engine.startService("pipeline"); - engine.startService("abi"); - engine.startService("deployment"); - callback(); - }, - function deploy(callback) { - engine.deployManager.deployContracts(function () { + this.build = function (options) { + let Engine = require('./core/engine'); + + let engine = new Engine({ + env: options.env, + embarkConfig: 'embark.json', + interceptLogs: false + }); + engine.init(); + + async.waterfall([ + function startServices(callback) { + let pluginList = engine.plugins.listPlugins(); + if (pluginList.length > 0) { + engine.logger.info("loaded plugins: " + pluginList.join(", ")); + } + + engine.startService("pipeline"); + engine.startService("abi"); + engine.startService("deployment"); callback(); - }); - } - ], function (err) { - if (err) { - engine.logger.error(err.message); - } else { - engine.logger.info("finished building".underline); - } - // needed due to child processes - process.exit(); - }); - }; + }, + function deploy(callback) { + engine.deployManager.deployContracts(function () { + callback(); + }); + } + ], function (err) { + if (err) { + engine.logger.error(err.message); + } else { + engine.logger.info("finished building".underline); + } + // needed due to child processes + process.exit(); + }); + }; - this.initTests = function (options) { - let Test = require('./core/test.js'); - return new Test(options); - }; + this.initTests = function (options) { + let Test = require('./core/test.js'); + return new Test(options); + }; // TODO: should deploy if it hasn't already - this.upload = function (platform) { - if (platform === 'ipfs') { - let ipfs = new IPFS({buildDir: 'dist/', plugins: Embark.prototype.plugins, storageConfig: Embark.prototype.config.storageConfig}); - ipfs.deploy(); - } else if (platform === 'swarm') { - let swarm = new Swarm({buildDir: 'dist/', plugins: Embark.prototype.plugins, storageConfig: Embark.prototype.config.storageConfig}); - swarm.deploy(); - } else { - console.log(("unknown platform: " + platform).red); - console.log('try "embark upload ipfs" or "embark upload swarm"'.green); - } - }; + this.upload = function (platform) { + if (platform === 'ipfs') { + let ipfs = new IPFS({ + buildDir: 'dist/', + plugins: Embark.prototype.plugins, + storageConfig: Embark.prototype.config.storageConfig + }); + ipfs.deploy(); + } else if (platform === 'swarm') { + let swarm = new Swarm({ + buildDir: 'dist/', + plugins: Embark.prototype.plugins, + storageConfig: Embark.prototype.config.storageConfig + }); + swarm.deploy(); + } else { + console.log(("unknown platform: " + platform).red); + console.log('try "embark upload ipfs" or "embark upload swarm"'.green); + } + }; - if (!(this instanceof Embark)) { - return new Embark(); + if (!(this instanceof Embark)) { + return new Embark(); + } + return this; } - return this; -}; +} Embark.prototype = Object.create(EventEmitter.prototype); diff --git a/lib/pipeline/pipeline.js b/lib/pipeline/pipeline.js index 190f22224..2a91e2102 100644 --- a/lib/pipeline/pipeline.js +++ b/lib/pipeline/pipeline.js @@ -1,80 +1,83 @@ /*jshint esversion: 6, loopfunc: true */ let fs = require('../core/fs.js'); -let Pipeline = function(options) { - this.buildDir = options.buildDir; - this.contractsFiles = options.contractsFiles; - this.assetFiles = options.assetFiles; - this.logger = options.logger; - this.plugins = options.plugins; -}; +class Pipeline { -Pipeline.prototype.build = function(abi, path) { - let self = this; - for(let targetFile in this.assetFiles) { + constructor(options) { + this.buildDir = options.buildDir; + this.contractsFiles = options.contractsFiles; + this.assetFiles = options.assetFiles; + this.logger = options.logger; + this.plugins = options.plugins; + } - let contentFiles = this.assetFiles[targetFile].map(file => { - self.logger.trace("reading " + file.filename); + build(abi, path) { + let self = this; + for (let targetFile in this.assetFiles) { - let pipelinePlugins = this.plugins.getPluginsFor('pipeline'); + let contentFiles = this.assetFiles[targetFile].map(file => { + self.logger.trace("reading " + file.filename); - if (file.filename === 'embark.js') { - return {content: file.content + "\n" + abi, filename: file.filename, path: file.path, modified: true}; - } else if (file.filename === 'abi.js') { - return {content: abi, filename: file.filename, path: file.path, modified: true}; - } else if (['web3.js', 'ipfs.js', 'ipfs-api.js', 'orbit.js'].indexOf(file.filename) >= 0) { - file.modified = true; - return file; - } else { + let pipelinePlugins = this.plugins.getPluginsFor('pipeline'); - if (pipelinePlugins.length > 0) { - pipelinePlugins.forEach(function(plugin) { - try { - if (file.options && file.options.skipPipeline) { - return; + if (file.filename === 'embark.js') { + return {content: file.content + "\n" + abi, filename: file.filename, path: file.path, modified: true}; + } else if (file.filename === 'abi.js') { + return {content: abi, filename: file.filename, path: file.path, modified: true}; + } else if (['web3.js', 'ipfs.js', 'ipfs-api.js', 'orbit.js'].indexOf(file.filename) >= 0) { + file.modified = true; + return file; + } else { + + if (pipelinePlugins.length > 0) { + pipelinePlugins.forEach(function (plugin) { + try { + if (file.options && file.options.skipPipeline) { + return; + } + file.content = plugin.runPipeline({targetFile: file.filename, source: file.content}); + file.modified = true; } - file.content = plugin.runPipeline({targetFile: file.filename, source: file.content}); - file.modified = true; - } - catch(err) { - self.logger.error(err.message); - } - }); + catch (err) { + self.logger.error(err.message); + } + }); + } + + return file; + } + }); + + let dir = targetFile.split('/').slice(0, -1).join('/'); + self.logger.trace("creating dir " + this.buildDir + dir); + fs.mkdirpSync(this.buildDir + dir); + + // if it's a directory + if (targetFile.slice(-1) === '/' || targetFile.indexOf('.') === -1) { + let targetDir = targetFile; + + if (targetDir.slice(-1) !== '/') { + targetDir = targetDir + '/'; } - return file; + contentFiles.map(function (file) { + let filename = file.filename.replace('app/', ''); + filename = filename.replace(targetDir, ''); + self.logger.info("writing file " + (self.buildDir + targetDir + filename).bold.dim); + + fs.copySync(self.buildDir + targetDir + filename, file.path, {overwrite: true}); + }); + } else { + let content = contentFiles.map(function (file) { + return file.content; + }).join("\n"); + + self.logger.info("writing file " + (this.buildDir + targetFile).bold.dim); + fs.writeFileSync(this.buildDir + targetFile, content); } - }); - - let dir = targetFile.split('/').slice(0, -1).join('/'); - self.logger.trace("creating dir " + this.buildDir + dir); - fs.mkdirpSync(this.buildDir + dir); - - // if it's a directory - if (targetFile.slice(-1) === '/' || targetFile.indexOf('.') === -1) { - let targetDir = targetFile; - - if (targetDir.slice(-1) !== '/') { - targetDir = targetDir + '/'; - } - - contentFiles.map(function(file) { - let filename = file.filename.replace('app/', ''); - filename = filename.replace(targetDir, ''); - self.logger.info("writing file " + (self.buildDir + targetDir + filename).bold.dim); - - fs.copySync(self.buildDir + targetDir + filename, file.path, {overwrite: true}); - }); - } else { - let content = contentFiles.map(function(file) { - return file.content; - }).join("\n"); - - self.logger.info("writing file " + (this.buildDir + targetFile).bold.dim); - fs.writeFileSync(this.buildDir + targetFile, content); } } -}; +} module.exports = Pipeline; diff --git a/lib/pipeline/server.js b/lib/pipeline/server.js index c3b781886..43d25e573 100644 --- a/lib/pipeline/server.js +++ b/lib/pipeline/server.js @@ -2,23 +2,26 @@ let finalhandler = require('finalhandler'); let http = require('http'); let serveStatic = require('serve-static'); -let Server = function(options) { - this.dist = options.dist || 'dist/'; - this.port = options.port || 8000; - this.hostname = options.host || 'localhost'; - this.logger = options.logger; -}; +class Server { + constructor(options) { + this.dist = options.dist || 'dist/'; + this.port = options.port || 8000; + this.hostname = options.host || 'localhost'; + this.logger = options.logger; + } -Server.prototype.start = function(callback) { - let serve = serveStatic(this.dist, {'index': ['index.html', 'index.htm']}); + start(callback) { + let serve = serveStatic(this.dist, {'index': ['index.html', 'index.htm']}); - let server = http.createServer(function onRequest (req, res) { - serve(req, res, finalhandler(req, res)); - }); + let server = http.createServer(function onRequest(req, res) { + serve(req, res, finalhandler(req, res)); + }); - this.logger.info("webserver available at " + ("http://" + this.hostname + ":" + this.port).bold.underline.green); - server.listen(this.port, this.hostname) ; - callback(); -}; + this.logger.info("webserver available at " + ("http://" + this.hostname + ":" + this.port).bold.underline.green); + server.listen(this.port, this.hostname); + callback(); + } + +} module.exports = Server; diff --git a/lib/pipeline/watch.js b/lib/pipeline/watch.js index 07a59401a..1131bfd29 100644 --- a/lib/pipeline/watch.js +++ b/lib/pipeline/watch.js @@ -5,97 +5,100 @@ let fs = require('../core/fs.js'); // TODO: this should be receiving the config object not re-reading the // embark.json file -let Watch = function(options) { - this.logger = options.logger; - this.events = options.events; -}; - -Watch.prototype.start = function() { - let self = this; - // TODO: should come from the config object instead of reading the file - // directly - let embarkConfig = fs.readJSONSync("embark.json"); - - this.watchAssets(embarkConfig, function() { - self.logger.trace('ready to watch asset changes'); - }); - - this.watchContracts(embarkConfig, function() { - self.logger.trace('ready to watch contract changes'); - }); - - this.watchConfigs(function() { - self.logger.trace('ready to watch config changes'); - }); - - this.logger.info("ready to watch file changes"); -}; - -Watch.prototype.watchAssets = function(embarkConfig, callback) { - let self = this; - let appConfig = embarkConfig.app; - let filesToWatch = []; - - for(let targetFile in appConfig) { - filesToWatch.push(appConfig[targetFile]); +class Watch { + constructor(options) { + this.logger = options.logger; + this.events = options.events; } - this.watchFiles( - filesToWatch, - function(eventName, path) { - self.logger.info(`${eventName}: ${path}`); - self.events.emit('file-' + eventName, 'asset', path); - self.events.emit('file-event', 'asset', path); - }, - function() { - callback(); + start() { + let self = this; + // TODO: should come from the config object instead of reading the file + // directly + let embarkConfig = fs.readJSONSync("embark.json"); + + this.watchAssets(embarkConfig, function () { + self.logger.trace('ready to watch asset changes'); + }); + + this.watchContracts(embarkConfig, function () { + self.logger.trace('ready to watch contract changes'); + }); + + this.watchConfigs(function () { + self.logger.trace('ready to watch config changes'); + }); + + this.logger.info("ready to watch file changes"); + } + + watchAssets(embarkConfig, callback) { + let self = this; + let appConfig = embarkConfig.app; + let filesToWatch = []; + + for (let targetFile in appConfig) { + filesToWatch.push(appConfig[targetFile]); } - ); -}; -Watch.prototype.watchContracts = function(embarkConfig, callback) { - let self = this; - this.watchFiles( - [embarkConfig.contracts], - function(eventName, path) { - self.logger.info(`${eventName}: ${path}`); - self.events.emit('file-' + eventName, 'contract', path); - self.events.emit('file-event', 'contract', path); - }, - function() { - callback(); - } - ); -}; + this.watchFiles( + filesToWatch, + function (eventName, path) { + self.logger.info(`${eventName}: ${path}`); + self.events.emit('file-' + eventName, 'asset', path); + self.events.emit('file-event', 'asset', path); + }, + function () { + callback(); + } + ); + } -Watch.prototype.watchConfigs = function(callback) { - let self = this; - this.watchFiles( - "config/**/contracts.json", - function(eventName, path) { - self.logger.info(`${eventName}: ${path}`); - self.events.emit('file-' + eventName, 'config', path); - self.events.emit('file-event', 'config', path); - }, - function() { - callback(); - } - ); -}; + watchContracts(embarkConfig, callback) { + let self = this; + this.watchFiles( + [embarkConfig.contracts], + function (eventName, path) { + self.logger.info(`${eventName}: ${path}`); + self.events.emit('file-' + eventName, 'contract', path); + self.events.emit('file-event', 'contract', path); + }, + function () { + callback(); + } + ); + } -Watch.prototype.watchFiles = function(files, changeCallback, doneCallback) { - this.logger.trace('watchFiles'); - this.logger.trace(files); + watchConfigs(callback) { + let self = this; + this.watchFiles( + "config/**/contracts.json", + function (eventName, path) { + self.logger.info(`${eventName}: ${path}`); + self.events.emit('file-' + eventName, 'config', path); + self.events.emit('file-event', 'config', path); + }, + function () { + callback(); + } + ); + } - let configWatcher = chokidar.watch(files, { - ignored: /[\/\\]\./, persistent: true, ignoreInitial: true, followSymlinks: true - }); + watchFiles(files, changeCallback, doneCallback) { + this.logger.trace('watchFiles'); + this.logger.trace(files); - configWatcher - .on('add', path => changeCallback('add', path)) - .on('change', path => changeCallback('change', path)) - .on('unlink', path => changeCallback('remove', path)) - .on('ready', doneCallback); -}; + let configWatcher = chokidar.watch(files, { + ignored: /[\/\\]\./, persistent: true, ignoreInitial: true, followSymlinks: true + }); + + configWatcher + .on('add', path => changeCallback('add', path)) + .on('change', path => changeCallback('change', path)) + .on('unlink', path => changeCallback('remove', path)) + .on('ready', doneCallback); + } + +} module.exports = Watch; diff --git a/lib/upload/ipfs.js b/lib/upload/ipfs.js index b21fb7f3c..026949560 100644 --- a/lib/upload/ipfs.js +++ b/lib/upload/ipfs.js @@ -2,55 +2,59 @@ let colors = require('colors'); let async = require('async'); let shelljs = require('shelljs'); -let IPFS = function(options) { - this.options = options; - this.buildDir = options.buildDir || 'dist/'; - this.plugins = options.plugins; - this.storageConfig = options.storageConfig; - this.configIpfsBin = this.storageConfig.ipfs_bin || "ipfs"; -}; +class IPFS { -IPFS.prototype.deploy = function() { - let self = this; - async.waterfall([ - function findBinary(callback) { - let ipfs_bin = shelljs.exec('which ' + self.configIpfsBin).output.split("\n")[0]; + constructor(options) { + this.options = options; + this.buildDir = options.buildDir || 'dist/'; + this.plugins = options.plugins; + this.storageConfig = options.storageConfig; + this.configIpfsBin = this.storageConfig.ipfs_bin || "ipfs"; + } - if (ipfs_bin === 'ipfs not found' || ipfs_bin === ''){ - console.log(('=== WARNING: ' + self.configIpfsBin + ' not found or not in the path. Guessing ~/go/bin/ipfs for path').yellow); - ipfs_bin = "~/go/bin/ipfs"; + deploy() { + let self = this; + async.waterfall([ + function findBinary(callback) { + let ipfs_bin = shelljs.exec('which ' + self.configIpfsBin).output.split("\n")[0]; + + if (ipfs_bin === 'ipfs not found' || ipfs_bin === '') { + console.log(('=== WARNING: ' + self.configIpfsBin + ' not found or not in the path. Guessing ~/go/bin/ipfs for path').yellow); + ipfs_bin = "~/go/bin/ipfs"; + } + + return callback(null, ipfs_bin); + }, + function runCommand(ipfs_bin, callback) { + let cmd = ipfs_bin + " add -r " + self.buildDir; + console.log(("=== adding " + self.buildDir + " to ipfs").green); + console.log(cmd.green); + let result = shelljs.exec(cmd); + + return callback(null, result); + }, + function getHashFromOutput(result, callback) { + let rows = result.output.split("\n"); + let dir_row = rows[rows.length - 2]; + let dir_hash = dir_row.split(" ")[1]; + + return callback(null, dir_hash); + }, + function printUrls(dir_hash, callback) { + console.log(("=== DApp available at http://localhost:8080/ipfs/" + dir_hash + "/").green); + console.log(("=== DApp available at http://gateway.ipfs.io/ipfs/" + dir_hash + "/").green); + + return callback(); } - - return callback(null, ipfs_bin); - }, - function runCommand(ipfs_bin, callback) { - let cmd = ipfs_bin + " add -r " + self.buildDir; - console.log(("=== adding " + self.buildDir + " to ipfs").green); - console.log(cmd.green); - let result = shelljs.exec(cmd); - - return callback(null, result); - }, - function getHashFromOutput(result, callback) { - let rows = result.output.split("\n"); - let dir_row = rows[rows.length - 2]; - let dir_hash = dir_row.split(" ")[1]; - - return callback(null, dir_hash); - }, - function printUrls(dir_hash, callback) { - console.log(("=== DApp available at http://localhost:8080/ipfs/" + dir_hash + "/").green); - console.log(("=== DApp available at http://gateway.ipfs.io/ipfs/" + dir_hash + "/").green); - - return callback(); - } - ], function(err, result) { + ], function (err, result) { if (err) { console.log("error uploading to ipfs".red); console.log(err); } - }); -}; + }); + } + +} module.exports = IPFS; diff --git a/lib/upload/swarm.js b/lib/upload/swarm.js index 894c09da3..80fa67c56 100644 --- a/lib/upload/swarm.js +++ b/lib/upload/swarm.js @@ -2,54 +2,56 @@ let colors = require('colors'); let async = require('async'); let shelljs = require('shelljs'); -let Swarm = function(options) { - this.options = options; - this.buildDir = options.buildDir || 'dist/'; -}; +class Swarm { + constructor(options) { + this.options = options; + this.buildDir = options.buildDir || 'dist/'; + } -Swarm.prototype.deploy = function() { - let self = this; - async.waterfall([ - function findBinary(callback) { - let swarm_bin = shelljs.exec('which swarm').output.split("\n")[0]; + deploy() { + let self = this; + async.waterfall([ + function findBinary(callback) { + let swarm_bin = shelljs.exec('which swarm').output.split("\n")[0]; - if (swarm_bin==='swarm not found' || swarm_bin === ''){ - console.log('=== WARNING: Swarm not in an executable path. Guessing ~/go/bin/swarm for path'.yellow); - swarm_bin = "~/go/bin/swarm"; + if (swarm_bin === 'swarm not found' || swarm_bin === '') { + console.log('=== WARNING: Swarm not in an executable path. Guessing ~/go/bin/swarm for path'.yellow); + swarm_bin = "~/go/bin/swarm"; + } + + return callback(null, swarm_bin); + }, + function runCommand(swarm_bin, callback) { + let cmd = swarm_bin + " --defaultpath " + self.buildDir + "index.html --recursive up " + self.buildDir; + console.log(("=== adding " + self.buildDir + " to swarm").green); + console.log(cmd.green); + let result = shelljs.exec(cmd); + + return callback(null, result); + }, + function getHashFromOutput(result, callback) { + if (result.code !== 0) { + return callback("couldn't upload, is the swarm daemon running?"); + } + + let rows = result.output.split("\n"); + let dir_hash = rows.reverse()[1]; + + return callback(null, dir_hash); + }, + function printUrls(dir_hash, callback) { + console.log(("=== DApp available at http://localhost:8500/bzz:/" + dir_hash + "/").green); + + return callback(); } - - return callback(null, swarm_bin); - }, - function runCommand(swarm_bin, callback) { - let cmd = swarm_bin + " --defaultpath " + self.buildDir + "index.html --recursive up " + self.buildDir; - console.log(("=== adding " + self.buildDir + " to swarm").green); - console.log(cmd.green); - let result = shelljs.exec(cmd); - - return callback(null, result); - }, - function getHashFromOutput(result, callback) { - if (result.code !== 0) { - return callback("couldn't upload, is the swarm daemon running?"); - } - - let rows = result.output.split("\n"); - let dir_hash = rows.reverse()[1]; - - return callback(null, dir_hash); - }, - function printUrls(dir_hash, callback) { - console.log(("=== DApp available at http://localhost:8500/bzz:/" + dir_hash + "/").green); - - return callback(); - } - ], function(err, result) { + ], function (err, result) { if (err) { console.log("error uploading to swarm".red); console.log(err); } - }); -}; + }); + } +} module.exports = Swarm; diff --git a/lib/utils/async_extend.js b/lib/utils/async_extend.js index 5c024c60a..616dc5199 100644 --- a/lib/utils/async_extend.js +++ b/lib/utils/async_extend.js @@ -3,12 +3,13 @@ let async = require('async'); function asyncEachObject(object, iterator, callback) { async.each( Object.keys(object || {}), - function(key, next){ + function (key, next) { iterator(key, object[key], next); }, callback ); } + async.eachObject = asyncEachObject; module.exports = async; diff --git a/lib/utils/debug_util.js b/lib/utils/debug_util.js index 3bebe506f..3bc2d35d4 100644 --- a/lib/utils/debug_util.js +++ b/lib/utils/debug_util.js @@ -5,9 +5,9 @@ function extend(filename, async) { return; } async._waterfall = async.waterfall; - async.waterfall = function(_tasks, callback) { - let tasks = _tasks.map(function(t) { - let fn = function() { + async.waterfall = function (_tasks, callback) { + let tasks = _tasks.map(function (t) { + let fn = function () { console.log("async " + filename + ": " + t.name); t.apply(t, arguments); }; diff --git a/lib/utils/utils.js b/lib/utils/utils.js index 712741505..8828cd31d 100644 --- a/lib/utils/utils.js +++ b/lib/utils/utils.js @@ -22,9 +22,9 @@ function recursiveMerge(target, source) { } function checkIsAvailable(url, callback) { - http.get(url, function(res) { + http.get(url, function (res) { callback(true); - }).on('error', function(res) { + }).on('error', function (res) { callback(false); }); } diff --git a/test/blockchain.js b/test/blockchain.js index a707d2c27..befdd3100 100644 --- a/test/blockchain.js +++ b/test/blockchain.js @@ -1,6 +1,7 @@ /*globals describe, it*/ -let Blockchain = require('../lib/cmds/blockchain/blockchain.js'); -let assert = require('assert'); +const Blockchain = require('../lib/cmds/blockchain/blockchain'); +// let BlockchainClient = require('../lib/cmds/blockchain/blockchain_client'); +const assert = require('assert'); describe('embark.Blockchain', function() { //let Client = function() {}; @@ -12,26 +13,28 @@ describe('embark.Blockchain', function() { describe('with empty config', function() { it('should have a default config', function() { let config = { - networkType: 'custom', - genesisBlock: false, - geth_bin: 'geth', - datadir: false, - mineWhenNeeded: false, - rpcHost: 'localhost', - rpcPort: 8545, - rpcApi: ['eth', 'web3', 'net'], - rpcCorsDomain: false, - networkId: 12301, - port: 30303, - nodiscover: false, - maxpeers: 25, - mine: false, - vmdebug: false, - whisper: true, - account: {}, - bootnodes: "" - }; - let blockchain = Blockchain(config, 'geth'); + blockchainConfig: { + networkType: 'custom', + genesisBlock: false, + geth_bin: 'geth', + datadir: false, + mineWhenNeeded: false, + rpcHost: 'localhost', + rpcPort: 8545, + rpcApi: ['eth', 'web3', 'net'], + rpcCorsDomain: false, + networkId: 12301, + port: 30303, + nodiscover: false, + maxpeers: 25, + mine: false, + vmdebug: false, + whisper: true, + account: {}, + bootnodes: "", + } + } + let blockchain = new Blockchain(config, 'geth'); assert.deepEqual(blockchain.config, config); }); @@ -59,7 +62,7 @@ describe('embark.Blockchain', function() { account: {}, bootnodes: "" }; - let blockchain = Blockchain(config, 'geth'); + let blockchain = new Blockchain(config, 'geth'); assert.deepEqual(blockchain.config, config); }); diff --git a/test/contracts.js b/test/contracts.js index 7e366a19e..211eabe51 100644 --- a/test/contracts.js +++ b/test/contracts.js @@ -9,7 +9,7 @@ let readFile = function(file) { }; describe('embark.Contratcs', function() { - + this.timeout(0); describe('simple', function() { let contractsManager = new ContractsManager({ contractFiles: [