2018-08-08 22:07:10 +00:00
let async = require ( 'async' ) ;
const constants = require ( '../lib/constants' ) ;
require ( 'colors' ) ;
let version = require ( '../package.json' ) . version ;
class EmbarkController {
constructor ( options ) {
this . version = version ;
this . options = options || { } ;
}
initConfig ( env , options ) {
2018-08-09 17:11:54 +00:00
let Events = require ( '../lib/core/events.js' ) ;
let Logger = require ( '../lib/core/logger.js' ) ;
let Config = require ( '../lib/core/config.js' ) ;
2018-08-08 22:07:10 +00:00
this . events = new Events ( ) ;
this . logger = new Logger ( { logLevel : 'debug' , events : this . events } ) ;
this . config = new Config ( { env : env , logger : this . logger , events : this . events , context : this . context } ) ;
this . config . loadConfigFiles ( options ) ;
this . plugins = this . config . plugins ;
}
blockchain ( env , client ) {
this . context = [ constants . contexts . blockchain ] ;
return require ( '../lib/modules/blockchain_process/blockchain.js' ) ( this . config . blockchainConfig , client , env ) . run ( ) ;
}
simulator ( options ) {
this . context = options . context || [ constants . contexts . simulator , constants . contexts . blockchain ] ;
let Simulator = require ( '../lib/modules/blockchain_process/simulator.js' ) ;
let simulator = new Simulator ( {
blockchainConfig : this . config . blockchainConfig ,
logger : this . logger
} ) ;
simulator . run ( options ) ;
}
generateTemplate ( templateName , destinationFolder , name , url ) {
this . context = [ constants . contexts . templateGeneration ] ;
let TemplateGenerator = require ( '../lib/utils/template_generator.js' ) ;
let templateGenerator = new TemplateGenerator ( templateName ) ;
if ( url ) {
return templateGenerator . downloadAndGenerate ( url , destinationFolder , name ) ;
}
templateGenerator . generate ( destinationFolder , name ) ;
}
run ( options ) {
let self = this ;
self . context = options . context || [ constants . contexts . run , constants . contexts . build ] ;
2018-08-08 22:15:25 +00:00
let Dashboard = require ( './dashboard/dashboard.js' ) ;
2018-08-08 22:07:10 +00:00
2018-09-17 22:50:13 +00:00
const webServerConfig = { } ;
2018-08-08 22:07:10 +00:00
2018-10-18 12:36:34 +00:00
if ( options . runWebserver !== null ) {
2018-09-17 22:50:13 +00:00
webServerConfig . enabled = options . runWebserver ;
}
2018-10-18 12:36:34 +00:00
if ( options . serverHost !== null ) {
2018-08-08 22:07:10 +00:00
webServerConfig . host = options . serverHost ;
}
2018-09-17 22:50:13 +00:00
2018-10-18 12:36:34 +00:00
if ( options . serverPort !== null ) {
2018-08-08 22:07:10 +00:00
webServerConfig . port = options . serverPort ;
}
2018-10-18 12:36:34 +00:00
if ( options . openBrowser !== null ) {
2018-09-17 22:50:13 +00:00
webServerConfig . openBrowser = options . openBrowser ;
}
2018-08-08 22:07:10 +00:00
const Engine = require ( '../lib/core/engine.js' ) ;
const engine = new Engine ( {
env : options . env ,
client : options . client ,
locale : options . locale ,
version : this . version ,
embarkConfig : options . embarkConfig || 'embark.json' ,
logFile : options . logFile ,
logLevel : options . logLevel ,
context : self . context ,
useDashboard : options . useDashboard ,
2018-08-16 20:51:34 +00:00
webServerConfig : webServerConfig ,
2018-09-12 09:16:27 +00:00
webpackConfigName : options . webpackConfigName ,
ipcRole : 'server'
2018-08-08 22:07:10 +00:00
} ) ;
2018-09-05 09:39:09 +00:00
async . waterfall ( [
function initEngine ( callback ) {
engine . init ( { } , ( ) => {
if ( ! options . useDashboard ) {
engine . logger . info ( '========================' . bold . green ) ;
engine . logger . info ( ( _ _ ( 'Welcome to Embark' ) + ' ' + engine . version ) . yellow . bold ) ;
engine . logger . info ( '========================' . bold . green ) ;
}
callback ( ) ;
} ) ;
} ,
2018-08-08 22:07:10 +00:00
function startDashboard ( callback ) {
if ( ! options . useDashboard ) {
return callback ( ) ;
}
let dashboard = new Dashboard ( {
events : engine . events ,
logger : engine . logger ,
plugins : engine . plugins ,
version : self . version ,
2018-08-31 08:24:45 +00:00
env : engine . env
2018-08-08 22:07:10 +00:00
} ) ;
dashboard . start ( function ( ) {
engine . logger . info ( _ _ ( 'dashboard start' ) ) ;
callback ( ) ;
} ) ;
} ,
function ( callback ) {
let pluginList = engine . plugins . listPlugins ( ) ;
if ( pluginList . length > 0 ) {
engine . logger . info ( _ _ ( "loaded plugins" ) + ": " + pluginList . join ( ", " ) ) ;
}
engine . startService ( "processManager" ) ;
engine . startService ( "serviceMonitor" ) ;
engine . startService ( "libraryManager" ) ;
engine . startService ( "codeRunner" ) ;
engine . startService ( "web3" ) ;
engine . startService ( "pipeline" ) ;
engine . startService ( "deployment" ) ;
engine . startService ( "storage" ) ;
engine . startService ( "codeGenerator" ) ;
2018-08-31 08:24:45 +00:00
engine . startService ( "console" ) ;
2018-09-10 17:08:17 +00:00
engine . startService ( "pluginCommand" ) ;
2018-08-08 22:07:10 +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' ) ) ;
} ) ;
} ) ;
engine . events . on ( 'outputDone' , function ( ) {
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-09-17 22:51:46 +00:00
if ( webServerConfig . enabled !== false ) {
engine . startService ( "webServer" ) ;
2018-08-08 22:07:10 +00:00
}
engine . startService ( "fileWatcher" ) ;
callback ( ) ;
}
] , function ( err , _result ) {
if ( err ) {
engine . logger . error ( err . message ) ;
engine . logger . info ( err . stack ) ;
} else {
engine . events . emit ( 'firstDeploymentDone' ) ;
}
} ) ;
}
build ( options ) {
this . context = options . context || [ constants . contexts . build ] ;
const Engine = require ( '../lib/core/engine.js' ) ;
const engine = new Engine ( {
env : options . env ,
client : options . client ,
locale : options . locale ,
version : this . version ,
embarkConfig : 'embark.json' ,
interceptLogs : false ,
logFile : options . logFile ,
logLevel : options . logLevel ,
events : options . events ,
logger : options . logger ,
config : options . config ,
plugins : options . plugins ,
2018-08-16 20:51:34 +00:00
context : this . context ,
webpackConfigName : options . webpackConfigName
2018-08-08 22:07:10 +00:00
} ) ;
2018-09-05 09:39:09 +00:00
2018-08-08 22:07:10 +00:00
async . waterfall ( [
2018-09-05 09:39:09 +00:00
function initEngine ( callback ) {
engine . init ( { } , callback ) ;
} ,
2018-08-08 22:07:10 +00:00
function startServices ( callback ) {
let pluginList = engine . plugins . listPlugins ( ) ;
if ( pluginList . length > 0 ) {
engine . logger . info ( _ _ ( "loaded plugins" ) + ": " + pluginList . join ( ", " ) ) ;
}
engine . startService ( "processManager" ) ;
engine . startService ( "libraryManager" ) ;
engine . startService ( "codeRunner" ) ;
if ( ! options . onlyCompile ) {
2018-10-09 13:12:33 +00:00
engine . startService ( "web3" ) ;
engine . startService ( "deployment" , { onlyCompile : options . onlyCompile } ) ;
2018-08-08 22:07:10 +00:00
engine . startService ( "pipeline" ) ;
2018-09-12 15:10:39 +00:00
engine . startService ( "storage" ) ;
engine . startService ( "codeGenerator" ) ;
2018-10-09 13:12:33 +00:00
} else {
engine . startService ( 'compiler' ) ;
2018-09-12 15:10:39 +00:00
}
2018-08-08 22:07:10 +00:00
callback ( ) ;
} ,
2018-10-09 13:12:33 +00:00
function buildOrBuildAndDeploy ( callback ) {
if ( options . onlyCompile ) {
engine . events . request ( 'contracts:build' , { } , err => callback ( err ) ) ;
} else {
// deploy:contracts will trigger a build as well
engine . events . request ( 'deploy:contracts' , err => callback ( err ) ) ;
}
2018-08-08 22:07:10 +00:00
} ,
function waitForWriteFinish ( callback ) {
if ( options . onlyCompile ) {
engine . logger . info ( "Finished compiling" . underline ) ;
return callback ( null , true ) ;
}
engine . logger . info ( "Finished deploying" . underline ) ;
engine . events . on ( 'outputDone' , ( err ) => {
2018-10-09 13:12:33 +00:00
engine . logger . info ( _ _ ( "Finished building" ) . underline ) ;
2018-08-08 22:07:10 +00:00
callback ( err , true ) ;
} ) ;
}
2018-09-27 13:08:39 +00:00
] , function ( _err , canExit ) {
2018-08-08 22:07:10 +00:00
// TODO: this should be moved out and determined somewhere else
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' ) ) ;
} ) ;
}
console ( options ) {
this . context = options . context || [ constants . contexts . run , constants . contexts . console ] ;
2018-08-08 12:42:45 +00:00
const REPL = require ( './dashboard/repl.js' ) ;
2018-08-08 22:07:10 +00:00
const Engine = require ( '../lib/core/engine.js' ) ;
const engine = new Engine ( {
env : options . env ,
client : options . client ,
locale : options . locale ,
version : this . version ,
embarkConfig : options . embarkConfig || 'embark.json' ,
logFile : options . logFile ,
logLevel : options . logLevel ,
2018-08-08 12:42:45 +00:00
context : this . context ,
2018-08-19 01:04:16 +00:00
webpackConfigName : options . webpackConfigName
2018-08-08 22:07:10 +00:00
} ) ;
2018-09-05 09:39:09 +00:00
2018-08-08 22:07:10 +00:00
async . waterfall ( [
2018-09-05 09:39:09 +00:00
function initEngine ( callback ) {
engine . init ( { } , callback ) ;
} ,
2018-08-08 22:07:10 +00:00
function startServices ( callback ) {
let pluginList = engine . plugins . listPlugins ( ) ;
if ( pluginList . length > 0 ) {
engine . logger . info ( _ _ ( "loaded plugins" ) + ": " + pluginList . join ( ", " ) ) ;
}
2018-09-12 09:16:27 +00:00
if ( engine . ipc . connected ) {
2018-08-08 12:42:45 +00:00
engine . startService ( "codeRunner" ) ;
2018-08-31 08:24:45 +00:00
engine . startService ( "console" ) ;
2018-09-12 09:16:27 +00:00
return callback ( ) ;
}
engine . startService ( "processManager" ) ;
engine . startService ( "serviceMonitor" ) ;
engine . startService ( "libraryManager" ) ;
engine . startService ( "codeRunner" ) ;
engine . startService ( "web3" ) ;
engine . startService ( "pipeline" ) ;
engine . startService ( "deployment" ) ;
engine . startService ( "storage" ) ;
engine . startService ( "codeGenerator" ) ;
engine . startService ( "console" ) ;
engine . startService ( "pluginCommand" ) ;
2018-10-08 23:41:38 +00:00
engine . events . once ( 'check:backOnline:Ethereum' , ( ) => callback ( ) ) ;
2018-08-08 12:42:45 +00:00
} ,
2018-09-28 10:09:23 +00:00
function ipcConnect ( callback ) {
2018-08-10 13:22:45 +00:00
// Do specific work in case we are connected to a socket:
// - Setup Web3
// - Apply history
2018-08-08 12:42:45 +00:00
if ( ! engine . ipc . connected || engine . ipc . isServer ( ) ) {
return callback ( ) ;
}
2018-09-13 10:13:52 +00:00
const Provider = require ( '../lib/modules/blockchain_connector/provider' ) ;
2018-08-08 12:42:45 +00:00
const Web3 = require ( 'web3' ) ;
let web3 = new Web3 ( ) ;
engine . ipc . request ( "runcode:getCommands" , null , ( _ , { web3Config , commands } ) => {
2018-09-13 10:13:52 +00:00
const providerOptions = {
web3 : web3 ,
accountsConfig : engine . config . contractsConfig . deployment . accounts ,
blockchainConfig : engine . config . blockchainConfig ,
logger : engine . logger ,
isDev : engine . isDev ,
type : engine . config . contractsConfig . deployment . type ,
web3Endpoint : web3Config . providerUrl
} ;
const provider = new Provider ( providerOptions ) ;
2018-09-20 10:49:05 +00:00
web3 . eth . defaultAccount = web3Config . defaultAccount ;
2018-09-13 10:13:52 +00:00
provider . startWeb3Provider ( ( ) => {
engine . events . emit ( "runcode:register" , "web3" , web3 ) ;
async . each ( commands , ( { varName , code } , next ) => {
if ( varName ) {
engine . events . emit ( "runcode:register" , varName , code ) ;
} else {
engine . events . request ( "runcode:eval" , code ) ;
}
next ( ) ;
} , callback ) ;
} ) ;
2018-08-08 12:42:45 +00:00
} ) ;
2018-08-08 22:07:10 +00:00
} ,
function deploy ( callback ) {
2018-08-10 13:22:45 +00:00
// Skip if we are connected to a websocket, the server will do it
2018-08-08 12:42:45 +00:00
if ( engine . ipc . connected && engine . ipc . isClient ( ) ) {
return callback ( ) ;
}
2018-08-28 10:47:40 +00:00
engine . config . reloadConfig ( ) ;
2018-08-08 22:07:10 +00:00
engine . events . request ( 'deploy:contracts' , function ( err ) {
callback ( err ) ;
} ) ;
} ,
function waitForWriteFinish ( callback ) {
2018-08-10 13:22:45 +00:00
// Skip if we are connected to a websocket, the server will do it
2018-08-08 12:42:45 +00:00
if ( engine . ipc . connected && engine . ipc . isClient ( ) ) {
return callback ( ) ;
}
2018-08-08 22:07:10 +00:00
engine . logger . info ( "Finished deploying" . underline ) ;
engine . events . once ( 'outputDone' , ( err ) => {
engine . logger . info ( _ _ ( "finished building" ) . underline ) ;
callback ( err ) ;
} ) ;
} ,
function startREPL ( callback ) {
2018-08-31 08:24:45 +00:00
new REPL ( { events : engine . events , env : engine . env } ) . start ( callback ) ;
2018-08-08 22:07:10 +00:00
}
] , function ( err , _result ) {
if ( err ) {
engine . logger . error ( err . message ) ;
engine . logger . info ( err . stack ) ;
} else {
engine . events . emit ( 'firstDeploymentDone' ) ;
}
} ) ;
}
graph ( options ) {
this . context = options . context || [ constants . contexts . graph ] ;
options . onlyCompile = true ;
const Engine = require ( '../lib/core/engine.js' ) ;
const engine = new Engine ( {
env : options . env ,
version : this . version ,
embarkConfig : options . embarkConfig || 'embark.json' ,
logFile : options . logFile ,
context : this . context
} ) ;
2018-09-05 09:39:09 +00:00
2018-08-08 22:07:10 +00:00
async . waterfall ( [
2018-09-05 09:39:09 +00:00
function ( callback ) {
engine . init ( { } , callback ) ;
} ,
2018-08-08 22:07:10 +00:00
function ( callback ) {
let pluginList = engine . plugins . listPlugins ( ) ;
if ( pluginList . length > 0 ) {
engine . logger . info ( _ _ ( "loaded plugins" ) + ": " + pluginList . join ( ", " ) ) ;
}
engine . startService ( "processManager" ) ;
engine . startService ( "serviceMonitor" ) ;
engine . startService ( "libraryManager" ) ;
2018-10-09 13:33:54 +00:00
engine . startService ( "compiler" ) ;
2018-08-08 22:07:10 +00:00
engine . startService ( "codeGenerator" ) ;
engine . startService ( "graph" ) ;
2018-10-09 13:33:54 +00:00
engine . events . request ( 'contracts:build' , { } , callback ) ;
2018-08-08 22:07:10 +00:00
}
] , ( err ) => {
if ( err ) {
engine . logger . error ( err . message ) ;
engine . logger . info ( err . stack ) ;
} else {
engine . events . request ( "graph:create" , options , ( ) => {
2018-10-01 18:39:45 +00:00
engine . logger . info ( _ _ ( "Done. %s generated" , options . output ) . underline ) ;
2018-08-08 22:07:10 +00:00
} ) ;
}
process . exit ( ) ;
} ) ;
}
reset ( ) {
var fs = require ( '../lib/core/fs.js' ) ;
fs . removeSync ( './chains.json' ) ;
fs . removeSync ( '.embark/' ) ;
2018-08-16 20:52:09 +00:00
fs . removeSync ( 'node_modules/.cache' ) ;
2018-08-08 22:07:10 +00:00
fs . removeSync ( 'dist/' ) ;
2018-09-18 19:22:47 +00:00
fs . removeSync ( 'coverage/' ) ;
2018-08-08 22:07:10 +00:00
console . log ( _ _ ( "reset done!" ) . green ) ;
}
2018-08-16 23:02:54 +00:00
ejectWebpack ( ) {
var fs = require ( '../lib/core/fs.js' ) ;
2018-10-03 14:02:29 +00:00
var embarkConfig = fs . embarkPath ( 'lib/modules/pipeline/webpack.config.js' ) ;
2018-08-16 23:02:54 +00:00
var dappConfig = fs . dappPath ( 'webpack.config.js' ) ;
2018-10-03 18:51:51 +00:00
fs . copyPreserve ( embarkConfig , dappConfig ) ;
console . log ( _ _ ( 'webpack config ejected to:' ) . dim . yellow ) ;
2018-08-20 16:02:38 +00:00
console . log ( ` ${ dappConfig } ` . green ) ;
2018-10-03 14:02:29 +00:00
var embarkOverrides = fs . embarkPath ( 'lib/modules/pipeline/babel-loader-overrides.js' ) ;
2018-10-03 19:53:40 +00:00
var dappOverrides = fs . dappPath ( 'babel-loader-overrides.js' ) ;
2018-10-03 18:51:51 +00:00
fs . copyPreserve ( embarkOverrides , dappOverrides ) ;
console . log ( _ _ ( 'webpack overrides ejected to:' ) . dim . yellow ) ;
2018-10-01 23:35:15 +00:00
console . log ( ` ${ dappOverrides } ` . green ) ;
2018-08-16 23:02:54 +00:00
}
2018-08-08 22:07:10 +00:00
upload ( options ) {
this . context = options . context || [ constants . contexts . upload , constants . contexts . build ] ;
const Engine = require ( '../lib/core/engine.js' ) ;
const engine = new Engine ( {
env : options . env ,
client : options . client ,
locale : options . locale ,
version : this . version ,
embarkConfig : 'embark.json' ,
interceptLogs : false ,
logFile : options . logFile ,
logLevel : options . logLevel ,
events : options . events ,
logger : options . logger ,
config : options . config ,
plugins : options . plugins ,
2018-08-28 20:44:13 +00:00
context : this . context ,
webpackConfigName : options . webpackConfigName
2018-08-08 22:07:10 +00:00
} ) ;
2018-09-05 09:39:09 +00:00
let platform ;
2018-08-08 22:07:10 +00:00
2018-09-05 09:39:09 +00:00
async . waterfall ( [
function initEngine ( callback ) {
engine . init ( { } , ( ) => {
2018-09-05 15:38:09 +00:00
if ( engine . config . embarkConfig . config . storage === false || engine . config . storageConfig . enabled === false ) {
engine . logger . error ( _ _ ( 'Storage configuration is disabled in embark.json. Please provide a storage file before uploading' ) ) ;
engine . logger . info ( _ _ ( 'You can find an example here: %s' , 'https://github.com/embark-framework/embark/blob/master/templates/demo/config/storage.js' . underline ) ) ;
2018-09-05 15:48:14 +00:00
process . exit ( 1 ) ;
2018-09-05 15:38:09 +00:00
}
2018-09-05 09:39:09 +00:00
platform = engine . config . storageConfig . upload . provider ;
callback ( ) ;
} ) ;
} ,
2018-08-08 22:07:10 +00:00
function startServices ( callback ) {
engine . startService ( "processManager" ) ;
engine . startService ( "serviceMonitor" ) ;
engine . startService ( "libraryManager" ) ;
engine . startService ( "codeRunner" ) ;
engine . startService ( "web3" ) ;
engine . startService ( "pipeline" ) ;
engine . startService ( "deployment" ) ;
engine . startService ( "storage" ) ;
engine . startService ( "codeGenerator" ) ;
callback ( ) ;
} ,
function listLoadedPlugin ( callback ) {
let pluginList = engine . plugins . listPlugins ( ) ;
if ( pluginList . length > 0 ) {
engine . logger . info ( _ _ ( "loaded plugins" ) + ": " + pluginList . join ( ", " ) ) ;
}
callback ( ) ;
} ,
function deploy ( callback ) {
engine . events . on ( 'outputDone' , function ( ) {
engine . events . request ( "storage:upload" , callback ) ;
} ) ;
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' ) ) ;
} ) ;
} ) ;
} ,
function associateToENS ( hash , callback ) {
if ( ! options . ensDomain ) {
return callback ( null , hash ) ;
}
engine . events . request ( "storage:ens:associate" ,
{ name : options . ensDomain , storageHash : hash } , ( err ) => {
if ( err ) {
return callback ( err ) ;
}
engine . logger . info ( _ _ ( 'ENS association completed for {{hash}} at {{domain}}' , { hash , domain : options . ensDomain } ) ) ;
callback ( ) ;
} ) ;
}
] , function ( err ) {
if ( err ) {
if ( err . message ) {
engine . logger . error ( err . message ) ;
return engine . logger . debug ( err . stack ) ;
}
2018-09-05 13:29:26 +00:00
engine . logger . error ( err ) ;
2018-08-08 22:07:10 +00:00
} else {
engine . logger . info ( ( _ _ ( "finished building DApp and deploying to" ) + " " + platform ) . underline ) ;
}
// needed due to child processes
process . exit ( ) ;
} ) ;
}
runTests ( options ) {
this . context = [ constants . contexts . test ] ;
2018-10-18 12:36:34 +00:00
const Engine = require ( '../lib/core/engine.js' ) ;
const engine = new Engine ( {
env : options . env ,
client : options . client ,
locale : options . locale ,
version : this . version ,
embarkConfig : 'embark.json' ,
interceptLogs : false ,
logFile : options . logFile ,
logLevel : options . logLevel ,
events : options . events ,
logger : options . logger ,
config : options . config ,
plugins : options . plugins ,
context : this . context ,
webpackConfigName : options . webpackConfigName
} ) ;
async . waterfall ( [
function initEngine ( callback ) {
engine . init ( { } , callback ) ;
} ,
function startServices ( callback ) {
engine . startService ( "testRunner" ) ;
callback ( ) ;
} ,
function runTests ( callback ) {
engine . events . request ( 'tests:run' , options , callback ) ;
}
] , function ( err ) {
if ( err ) {
engine . logger . error ( err . message || err ) ;
}
process . exit ( ) ;
} ) ;
2018-08-08 22:07:10 +00:00
}
}
module . exports = EmbarkController ;