2017-03-29 15:37:30 +00:00
let async = require ( 'async' ) ;
2018-04-25 14:34:17 +00:00
const constants = require ( './constants' ) ;
2017-03-01 04:29:16 +00:00
2017-12-05 23:14:46 +00:00
require ( 'colors' ) ;
2016-08-14 12:04:34 +00:00
2018-08-15 15:42:28 +00:00
// Set PWD to CWD since Windows doesn't have a value for PWD
if ( ! process . env . PWD ) {
process . env . PWD = process . cwd ( ) ;
}
2018-04-09 20:14:07 +00:00
2017-03-30 13:16:46 +00:00
let version = require ( '../package.json' ) . version ;
2017-03-31 11:34:43 +00:00
class Embark {
2017-03-30 13:16:46 +00:00
2018-06-19 14:03:46 +00:00
constructor ( options ) {
2017-03-30 13:16:46 +00:00
this . version = version ;
this . options = options || { } ;
}
2017-03-30 11:12:39 +00:00
2017-03-30 13:16:46 +00:00
initConfig ( env , options ) {
let Events = require ( './core/events.js' ) ;
let Logger = require ( './core/logger.js' ) ;
let Config = require ( './core/config.js' ) ;
2017-03-30 11:12:39 +00:00
2017-03-30 13:16:46 +00:00
this . events = new Events ( ) ;
2018-03-15 21:18:20 +00:00
this . logger = new Logger ( { logLevel : 'debug' , events : this . events } ) ;
2017-03-30 13:16:46 +00:00
2018-04-25 14:34:17 +00:00
this . config = new Config ( { env : env , logger : this . logger , events : this . events , context : this . context } ) ;
2017-03-30 11:12:39 +00:00
this . config . loadConfigFiles ( options ) ;
this . plugins = this . config . plugins ;
2017-03-30 13:16:46 +00:00
}
2017-03-30 11:12:39 +00:00
2018-06-27 18:29:31 +00:00
isDev ( ) {
return this . config && this . config . blockchainConfig && this . config . blockchainConfig . isDev ;
2018-05-14 18:32:19 +00:00
}
2017-03-30 13:16:46 +00:00
blockchain ( env , client ) {
2018-04-25 14:34:17 +00:00
this . context = [ constants . contexts . blockchain ] ;
2018-07-13 12:56:59 +00:00
return require ( './cmds/blockchain/blockchain.js' ) ( this . config . blockchainConfig , client , env , this . isDev ( env ) , ( ) => { } ) . run ( ) ;
2017-03-30 13:16:46 +00:00
}
2017-02-25 03:49:34 +00:00
2017-03-30 13:16:46 +00:00
simulator ( options ) {
2018-04-25 14:34:17 +00:00
this . context = options . context || [ constants . contexts . simulator , constants . contexts . blockchain ] ;
2017-03-30 13:16:46 +00:00
let Simulator = require ( './cmds/simulator.js' ) ;
2018-06-07 16:50:22 +00:00
let simulator = new Simulator ( {
2018-06-19 14:03:46 +00:00
blockchainConfig : this . config . blockchainConfig ,
2018-06-07 19:13:35 +00:00
logger : this . logger
2018-06-07 16:50:22 +00:00
} ) ;
2017-03-30 13:16:46 +00:00
simulator . run ( options ) ;
}
2017-01-15 23:46:40 +00:00
2018-07-06 08:38:09 +00:00
generateTemplate ( templateName , destinationFolder , name , url ) {
2018-04-25 14:34:17 +00:00
this . context = [ constants . contexts . templateGeneration ] ;
2017-03-30 13:16:46 +00:00
let TemplateGenerator = require ( './cmds/template_generator.js' ) ;
let templateGenerator = new TemplateGenerator ( templateName ) ;
2018-07-06 08:38:09 +00:00
if ( url ) {
return templateGenerator . downloadAndGenerate ( url , destinationFolder , name ) ;
}
2017-03-30 13:16:46 +00:00
templateGenerator . generate ( destinationFolder , name ) ;
}
2017-02-25 03:49:34 +00:00
2017-03-30 13:16:46 +00:00
run ( options ) {
2017-03-31 11:34:43 +00:00
let self = this ;
2018-04-25 14:34:17 +00:00
self . context = options . context || [ constants . contexts . run , constants . contexts . build ] ;
2017-03-30 13:16:46 +00:00
let Dashboard = require ( './dashboard/dashboard.js' ) ;
2017-03-11 03:00:30 +00:00
2018-06-02 14:06:58 +00:00
const Engine = require ( './core/engine.js' ) ;
const engine = new Engine ( {
2017-03-30 13:16:46 +00:00
env : options . env ,
2018-05-18 19:48:28 +00:00
client : options . client ,
locale : options . locale ,
2018-06-27 18:29:31 +00:00
isDev : this . isDev ( ) ,
2017-03-31 11:34:43 +00:00
version : this . version ,
2018-03-10 18:45:56 +00:00
embarkConfig : options . embarkConfig || 'embark.json' ,
2018-04-19 04:25:43 +00:00
logFile : options . logFile ,
2018-04-25 14:34:17 +00:00
logLevel : options . logLevel ,
2018-06-14 23:37:52 +00:00
context : self . context ,
useDashboard : options . useDashboard
2017-03-30 13:16:46 +00:00
} ) ;
engine . init ( ) ;
if ( ! options . useDashboard ) {
2018-04-24 18:42:56 +00:00
engine . logger . info ( '========================' . bold . green ) ;
2018-05-08 21:49:46 +00:00
engine . logger . info ( ( _ _ ( 'Welcome to Embark' ) + ' ' + this . version ) . yellow . bold ) ;
2018-04-24 18:42:56 +00:00
engine . logger . info ( '========================' . bold . green ) ;
2017-03-30 13:16:46 +00:00
}
async . parallel ( [
function startDashboard ( callback ) {
if ( ! options . useDashboard ) {
return callback ( ) ;
}
let dashboard = new Dashboard ( {
2017-12-17 23:34:41 +00:00
events : engine . events ,
2017-03-30 13:16:46 +00:00
logger : engine . logger ,
plugins : engine . plugins ,
2017-03-31 11:34:43 +00:00
version : self . version ,
2018-07-07 13:34:56 +00:00
env : engine . env
2017-03-30 13:16:46 +00:00
} ) ;
dashboard . start ( function ( ) {
2018-05-08 21:49:46 +00:00
engine . logger . info ( _ _ ( 'dashboard start' ) ) ;
2017-02-25 20:47:35 +00:00
callback ( ) ;
2017-03-30 13:16:46 +00:00
} ) ;
} ,
function ( callback ) {
let pluginList = engine . plugins . listPlugins ( ) ;
if ( pluginList . length > 0 ) {
2018-05-08 21:49:46 +00:00
engine . logger . info ( _ _ ( "loaded plugins" ) + ": " + pluginList . join ( ", " ) ) ;
2017-03-30 11:12:39 +00:00
}
2017-03-30 13:16:46 +00:00
2018-06-01 16:27:12 +00:00
engine . startService ( "serviceMonitor" ) ;
2017-12-30 20:52:51 +00:00
engine . startService ( "libraryManager" ) ;
2018-05-23 15:16:56 +00:00
engine . startService ( "codeRunner" ) ;
2017-03-30 13:16:46 +00:00
engine . startService ( "web3" ) ;
engine . startService ( "pipeline" ) ;
engine . startService ( "deployment" ) ;
2018-05-31 10:18:25 +00:00
engine . startService ( "storage" ) ;
2018-05-23 15:16:13 +00:00
engine . startService ( "codeGenerator" ) ;
2018-05-25 17:25:02 +00:00
engine . startService ( "namingSystem" ) ;
2018-06-08 11:07:27 +00:00
2017-03-30 13:16:46 +00:00
engine . events . on ( 'check:backOnline:Ethereum' , function ( ) {
2018-05-08 21:49:46 +00:00
engine . logger . info ( _ _ ( 'Ethereum node detected' ) + '..' ) ;
2017-03-30 13:16:46 +00:00
engine . config . reloadConfig ( ) ;
2018-06-19 14:03:46 +00:00
engine . events . request ( 'deploy:contracts' , function ( err ) {
2018-06-08 11:07:27 +00:00
if ( err ) {
return ;
}
2018-05-08 21:49:46 +00:00
engine . logger . info ( _ _ ( 'Deployment Done' ) ) ;
2017-03-30 13:16:46 +00:00
} ) ;
2016-11-28 20:14:39 +00:00
} ) ;
2017-03-30 13:16:46 +00:00
2018-04-17 04:11:22 +00:00
engine . events . on ( 'outputDone' , function ( ) {
2018-06-27 14:09:21 +00:00
engine . logger . warn ( _ _ ( "Note: The console uses " ) . green + ( _ _ ( "web3.js 1.0" ) . underline + " " ) . cyan + " the reference docs for web3.js can be found at http://web3js.readthedocs.io/en/1.0/" . green ) ;
2018-05-08 21:49:46 +00:00
engine . logger . info ( ( _ _ ( "Looking for documentation? You can find it at" ) + " " ) . cyan + "http://embark.status.im/docs/" . green . underline + "." . cyan ) ;
engine . logger . info ( _ _ ( "Ready" ) . underline ) ;
engine . events . emit ( "status" , _ _ ( "Ready" ) . green ) ;
2018-04-17 04:11:22 +00:00
} ) ;
2018-05-29 21:23:29 +00:00
2018-05-30 16:00:44 +00:00
if ( options . runWebserver ) {
engine . startService ( "webServer" , {
host : options . serverHost ,
port : options . serverPort
} ) ;
}
engine . startService ( "fileWatcher" ) ;
callback ( ) ;
2017-03-30 13:16:46 +00:00
}
2017-12-05 23:14:46 +00:00
] , function ( err , _result ) {
2017-03-30 13:16:46 +00:00
if ( err ) {
engine . logger . error ( err . message ) ;
engine . logger . info ( err . stack ) ;
2016-10-31 02:04:25 +00:00
} else {
2017-12-19 20:14:09 +00:00
engine . events . emit ( 'firstDeploymentDone' ) ;
2016-10-31 02:04:25 +00:00
}
2017-03-30 13:16:46 +00:00
} ) ;
}
2018-04-20 07:39:45 +00:00
build ( options ) {
2018-04-25 14:34:17 +00:00
this . context = options . context || [ constants . contexts . build ] ;
2018-04-26 09:05:56 +00:00
2018-06-02 14:06:58 +00:00
const Engine = require ( './core/engine.js' ) ;
const engine = new Engine ( {
2018-04-19 04:25:43 +00:00
env : options . env ,
2018-05-22 19:46:02 +00:00
client : options . client ,
locale : options . locale ,
2018-06-27 18:29:31 +00:00
isDev : this . isDev ( ) ,
2018-04-19 04:25:43 +00:00
version : this . version ,
embarkConfig : 'embark.json' ,
interceptLogs : false ,
logFile : options . logFile ,
logLevel : options . logLevel ,
events : options . events ,
logger : options . logger ,
config : options . config ,
2018-04-25 14:34:17 +00:00
plugins : options . plugins ,
context : this . context
2018-04-19 04:25:43 +00:00
} ) ;
engine . init ( ) ;
2016-10-02 21:26:57 +00:00
2017-03-30 13:16:46 +00:00
async . waterfall ( [
function startServices ( callback ) {
let pluginList = engine . plugins . listPlugins ( ) ;
if ( pluginList . length > 0 ) {
2018-05-08 21:49:46 +00:00
engine . logger . info ( _ _ ( "loaded plugins" ) + ": " + pluginList . join ( ", " ) ) ;
2017-03-30 13:16:46 +00:00
}
2017-12-30 20:52:51 +00:00
engine . startService ( "libraryManager" ) ;
2018-05-23 15:16:56 +00:00
engine . startService ( "codeRunner" ) ;
2017-03-30 13:16:46 +00:00
engine . startService ( "web3" ) ;
2018-06-22 15:12:34 +00:00
if ( ! options . onlyCompile ) {
2018-06-22 05:26:43 +00:00
engine . startService ( "pipeline" ) ;
}
2018-05-17 20:37:57 +00:00
engine . startService ( "deployment" , { onlyCompile : options . onlyCompile } ) ;
2018-05-25 07:13:57 +00:00
engine . startService ( "storage" ) ;
2018-05-23 15:16:13 +00:00
engine . startService ( "codeGenerator" ) ;
2017-03-30 13:16:46 +00:00
callback ( ) ;
} ,
function deploy ( callback ) {
2018-06-19 14:03:46 +00:00
engine . events . request ( 'deploy:contracts' , function ( err ) {
2018-05-23 14:06:12 +00:00
callback ( err ) ;
2017-03-30 13:16:46 +00:00
} ) ;
2018-06-14 14:30:34 +00:00
} ,
function waitForWriteFinish ( callback ) {
2018-06-22 15:12:34 +00:00
if ( options . onlyCompile ) {
engine . logger . info ( "Finished compiling" . underline ) ;
return callback ( null , true ) ;
}
2018-06-14 14:30:34 +00:00
engine . logger . info ( "Finished deploying" . underline ) ;
2018-06-22 15:12:34 +00:00
engine . events . on ( 'outputDone' , ( err ) => {
engine . logger . info ( _ _ ( "finished building" ) . underline ) ;
callback ( err , true ) ;
} ) ;
2017-03-30 13:16:46 +00:00
}
2018-06-22 15:12:34 +00:00
] , function ( err , canExit ) {
2017-03-30 13:16:46 +00:00
if ( err ) {
engine . logger . error ( err . message ) ;
engine . logger . debug ( err . stack ) ;
}
2018-06-22 15:12:34 +00:00
2018-07-07 13:59:00 +00:00
// TODO: this should be moved out and determined somewhere else
2018-06-22 15:12:34 +00:00
if ( canExit || ! engine . config . contractsConfig . afterDeploy || ! engine . config . contractsConfig . afterDeploy . length ) {
process . exit ( ) ;
}
engine . logger . info ( _ _ ( 'Waiting for after deploy to finish...' ) ) ;
engine . logger . info ( _ _ ( 'You can exit with CTRL+C when after deploy completes' ) ) ;
2017-03-30 13:16:46 +00:00
} ) ;
}
2018-03-22 19:09:01 +00:00
graph ( options ) {
2018-04-25 14:34:17 +00:00
this . context = options . context || [ constants . contexts . graph ] ;
2018-03-22 19:09:01 +00:00
options . onlyCompile = true ;
2018-06-19 14:03:46 +00:00
2018-06-02 14:06:58 +00:00
const Engine = require ( './core/engine.js' ) ;
const engine = new Engine ( {
2018-03-22 19:09:01 +00:00
env : options . env ,
2018-06-27 18:29:31 +00:00
isDev : this . isDev ( ) ,
2018-03-22 19:09:01 +00:00
version : this . version ,
embarkConfig : options . embarkConfig || 'embark.json' ,
2018-04-25 14:34:17 +00:00
logFile : options . logFile ,
context : this . context
2018-03-22 19:09:01 +00:00
} ) ;
engine . init ( ) ;
2018-06-19 14:03:46 +00:00
async . waterfall ( [
2018-03-22 19:09:01 +00:00
function ( callback ) {
let pluginList = engine . plugins . listPlugins ( ) ;
if ( pluginList . length > 0 ) {
2018-05-08 21:49:46 +00:00
engine . logger . info ( _ _ ( "loaded plugins" ) + ": " + pluginList . join ( ", " ) ) ;
2018-03-22 19:09:01 +00:00
}
2018-06-01 16:27:12 +00:00
engine . startService ( "serviceMonitor" ) ;
2018-03-22 19:09:01 +00:00
engine . startService ( "libraryManager" ) ;
engine . startService ( "pipeline" ) ;
engine . startService ( "deployment" , { onlyCompile : true } ) ;
2018-06-19 14:03:46 +00:00
engine . startService ( "web3" ) ;
2018-05-23 15:16:13 +00:00
engine . startService ( "codeGenerator" ) ;
2018-03-22 19:09:01 +00:00
2018-06-19 14:03:46 +00:00
engine . events . request ( 'deploy:contracts' , callback ) ;
2018-03-22 19:09:01 +00:00
}
2018-06-19 14:03:46 +00:00
] , ( err ) => {
2018-03-22 19:09:01 +00:00
if ( err ) {
engine . logger . error ( err . message ) ;
engine . logger . info ( err . stack ) ;
} else {
const GraphGenerator = require ( './cmds/graph.js' ) ;
2018-03-22 20:18:13 +00:00
let graphGen = new GraphGenerator ( engine ) ;
2018-05-04 20:17:12 +00:00
graphGen . generate ( options ) ;
2018-03-22 19:09:01 +00:00
2018-05-08 21:49:46 +00:00
engine . logger . info ( _ _ ( "Done. %s generated" , "./diagram.svg" ) . underline ) ;
2018-03-22 19:09:01 +00:00
}
2018-05-23 15:13:51 +00:00
process . exit ( ) ;
2018-03-22 19:09:01 +00:00
} ) ;
2018-03-22 14:43:29 +00:00
}
2018-01-11 14:22:58 +00:00
reset ( ) {
2018-04-25 14:34:17 +00:00
this . context = [ constants . contexts . reset ] ;
2018-01-11 14:22:58 +00:00
let resetCmd = require ( './cmds/reset.js' ) ;
resetCmd ( ) ;
}
2018-05-17 07:38:17 +00:00
upload ( options ) {
2018-04-26 09:05:56 +00:00
this . context = options . context || [ constants . contexts . upload , constants . contexts . build ] ;
2018-04-19 04:25:43 +00:00
2018-06-02 14:06:58 +00:00
const Engine = require ( './core/engine.js' ) ;
const engine = new Engine ( {
2018-04-20 07:39:45 +00:00
env : options . env ,
2018-05-22 19:46:58 +00:00
client : options . client ,
locale : options . locale ,
2018-06-27 18:29:31 +00:00
isDev : this . isDev ( ) ,
2018-04-20 07:39:45 +00:00
version : this . version ,
embarkConfig : 'embark.json' ,
interceptLogs : false ,
logFile : options . logFile ,
logLevel : options . logLevel ,
events : options . events ,
logger : options . logger ,
config : options . config ,
2018-06-01 03:12:17 +00:00
plugins : options . plugins ,
context : this . context
2018-04-20 07:39:45 +00:00
} ) ;
engine . init ( ) ;
2018-05-25 07:13:57 +00:00
let platform = engine . config . storageConfig . upload . provider ;
2018-05-17 07:38:17 +00:00
2017-12-27 00:55:42 +00:00
let cmdPlugin ;
2018-04-15 08:41:50 +00:00
async . waterfall ( [
2018-05-08 21:49:46 +00:00
2018-04-24 00:27:11 +00:00
function startServices ( callback ) {
2018-05-08 21:49:46 +00:00
2018-06-01 16:27:12 +00:00
engine . startService ( "serviceMonitor" ) ;
2018-04-24 00:27:11 +00:00
engine . startService ( "libraryManager" ) ;
2018-05-23 15:16:56 +00:00
engine . startService ( "codeRunner" ) ;
2018-04-24 00:27:11 +00:00
engine . startService ( "web3" ) ;
engine . startService ( "pipeline" ) ;
engine . startService ( "deployment" ) ;
2018-05-31 10:18:25 +00:00
engine . startService ( "storage" ) ;
2018-05-23 15:16:13 +00:00
engine . startService ( "codeGenerator" ) ;
2018-04-24 00:27:11 +00:00
callback ( ) ;
} ,
2018-06-19 14:03:46 +00:00
function setupStoragePlugin ( callback ) {
2018-04-24 00:27:11 +00:00
let pluginList = engine . plugins . listPlugins ( ) ;
if ( pluginList . length > 0 ) {
2018-05-08 21:49:46 +00:00
engine . logger . info ( _ _ ( "loaded plugins" ) + ": " + pluginList . join ( ", " ) ) ;
2018-04-24 00:27:11 +00:00
}
2018-05-08 21:49:46 +00:00
2018-04-15 08:41:50 +00:00
// check use has input existing storage plugin
2018-04-24 00:27:11 +00:00
let cmdPlugins = engine . plugins . getPluginsFor ( 'uploadCmds' ) ;
2018-05-08 21:49:46 +00:00
2018-04-15 08:41:50 +00:00
if ( cmdPlugins . length > 0 ) {
cmdPlugin = cmdPlugins . find ( ( pluginCmd ) => {
2018-04-26 18:00:41 +00:00
return pluginCmd . uploadCmds . some ( uploadCmd => {
return uploadCmd . cmd === platform ;
} ) ;
2018-04-12 10:46:04 +00:00
} ) ;
}
2018-04-15 08:41:50 +00:00
if ( ! cmdPlugin ) {
2018-05-25 07:13:57 +00:00
return callback ( { message : _ _ ( 'platform "{{platform}}" is specified as the upload provider, however no plugins have registered an upload command for "{{platform}}".' , { platform : platform } ) } ) ;
2018-04-12 10:46:04 +00:00
}
2018-05-01 13:38:13 +00:00
callback ( ) ;
2018-04-15 08:41:50 +00:00
} ,
2018-04-20 07:39:45 +00:00
function deploy ( callback ) {
2018-04-24 00:27:11 +00:00
engine . events . on ( 'outputDone' , function ( ) {
cmdPlugin . uploadCmds [ 0 ] . cb ( )
2018-06-19 14:03:46 +00:00
. then ( ( success ) => {
callback ( null , success ) ;
} )
. catch ( callback ) ;
2018-04-15 08:41:50 +00:00
} ) ;
2018-06-22 05:17:51 +00:00
engine . events . on ( 'check:backOnline:Ethereum' , function ( ) {
engine . logger . info ( _ _ ( 'Ethereum node detected' ) + '..' ) ;
engine . config . reloadConfig ( ) ;
engine . events . request ( 'deploy:contracts' , function ( err ) {
if ( err ) {
return ;
}
engine . logger . info ( _ _ ( 'Deployment Done' ) ) ;
} ) ;
2018-04-20 07:39:45 +00:00
} ) ;
2018-04-15 08:41:50 +00:00
}
] , function ( err , _result ) {
if ( err ) {
2018-04-24 00:27:11 +00:00
engine . logger . error ( err . message ) ;
engine . logger . debug ( err . stack ) ;
2018-04-15 08:41:50 +00:00
} else {
2018-05-08 21:49:46 +00:00
engine . logger . info ( ( _ _ ( "finished building DApp and deploying to" ) + " " + platform ) . underline ) ;
2018-04-15 08:41:50 +00:00
}
2018-04-12 10:46:04 +00:00
2018-04-15 08:41:50 +00:00
// needed due to child processes
process . exit ( ) ;
} ) ;
2017-03-29 15:37:30 +00:00
}
2018-06-13 13:44:19 +00:00
runTests ( options ) {
2018-04-25 14:34:17 +00:00
this . context = [ constants . contexts . test ] ;
2018-01-20 02:13:20 +00:00
let RunTests = require ( './tests/run_tests.js' ) ;
2018-06-13 13:44:19 +00:00
RunTests . run ( options ) ;
2017-07-02 03:11:42 +00:00
}
2017-03-30 13:16:46 +00:00
}
2017-03-12 02:49:12 +00:00
2016-08-18 00:29:41 +00:00
module . exports = Embark ;