mirror of
https://github.com/embarklabs/embark.git
synced 2025-02-10 20:56:38 +00:00
refactor
remove code not beloging to code runner & other core modules; disable code generator and move contract code to its own module cleanup pipeline; start preparing for plugin based pipeline file generation initial work to write pipeline files through an api add action events to pipeline; generate contracts json and js files move old pipeline to its own module; generate basic artifacts re-add missing plugins function add basic embarkjs provider registration refactor embark-whisper; move whisper api; execute whisper code in console add api to register help cmds in console; start moving hardcoded help cmds out cleanup embark-graph add todos
This commit is contained in:
parent
783b555dd2
commit
50c3525374
@ -20,7 +20,7 @@
|
|||||||
"ipfs-api": "17.2.7"
|
"ipfs-api": "17.2.7"
|
||||||
},
|
},
|
||||||
"plugins": {
|
"plugins": {
|
||||||
"embark-dapp-test-service": {}
|
"embarkjs-connector-web3": {}
|
||||||
},
|
},
|
||||||
"options": {
|
"options": {
|
||||||
"solc": {
|
"solc": {
|
||||||
|
@ -4,16 +4,12 @@ import VM from "./vm";
|
|||||||
export { fs, VM };
|
export { fs, VM };
|
||||||
|
|
||||||
import { Callback, Embark, Events, Logger } /* supplied by @types/embark in packages/embark-typings */ from "embark";
|
import { Callback, Embark, Events, Logger } /* supplied by @types/embark in packages/embark-typings */ from "embark";
|
||||||
import Web3 from "web3";
|
|
||||||
|
|
||||||
|
// TODO: ideally shouldn't be needed or should be done through an API
|
||||||
|
import Web3 from "web3";
|
||||||
const EmbarkJS = require("embarkjs");
|
const EmbarkJS = require("embarkjs");
|
||||||
|
|
||||||
export enum ProviderEventType {
|
class CodeRunner {
|
||||||
ProviderRegistered = "providerRegistered",
|
|
||||||
ProviderSet = "providerSet",
|
|
||||||
}
|
|
||||||
|
|
||||||
export default class CodeRunner {
|
|
||||||
private ready: boolean = false;
|
private ready: boolean = false;
|
||||||
private blockchainConnected: boolean = false;
|
private blockchainConnected: boolean = false;
|
||||||
private logger: Logger;
|
private logger: Logger;
|
||||||
@ -31,6 +27,7 @@ export default class CodeRunner {
|
|||||||
fs,
|
fs,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
// TODO: ideally shouldn't be needed or should be done through an API
|
||||||
sandbox: {
|
sandbox: {
|
||||||
EmbarkJS,
|
EmbarkJS,
|
||||||
Web3,
|
Web3,
|
||||||
@ -39,17 +36,7 @@ export default class CodeRunner {
|
|||||||
|
|
||||||
this.registerEvents();
|
this.registerEvents();
|
||||||
this.registerCommands();
|
this.registerCommands();
|
||||||
}
|
this.ready = true;
|
||||||
|
|
||||||
private generateListener(provider: string, eventType: ProviderEventType) {
|
|
||||||
const providerStateName = `${provider}:${eventType}`;
|
|
||||||
const eventName = `runcode:${providerStateName}`;
|
|
||||||
this.events.setCommandHandler(eventName, (cb) => {
|
|
||||||
if (this.providerStates[providerStateName] === true) {
|
|
||||||
return cb();
|
|
||||||
}
|
|
||||||
this.events.once(eventName, cb);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private registerEvents() {
|
private registerEvents() {
|
||||||
@ -61,44 +48,6 @@ export default class CodeRunner {
|
|||||||
cb(this.vm.options.sandbox);
|
cb(this.vm.options.sandbox);
|
||||||
});
|
});
|
||||||
this.events.setCommandHandler("runcode:eval", this.evalCode.bind(this));
|
this.events.setCommandHandler("runcode:eval", this.evalCode.bind(this));
|
||||||
this.events.setCommandHandler("runcode:embarkjs:reset", (cb) => {
|
|
||||||
this.resetEmbarkJS(cb);
|
|
||||||
});
|
|
||||||
this.events.on("contractsDeployed", () => {
|
|
||||||
this.events.on("code-generator-ready", (_modifiedAssets: any) => {
|
|
||||||
this.resetEmbarkJS();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// register listeners for when EmbarkJS runs registerProvider through the console.
|
|
||||||
// For example, when `EmbarkJS.Storage.registerProvider(...)` is run through the console,
|
|
||||||
// emit the `runcode:storage:providerRegistered` event, and fire any requests attached to it
|
|
||||||
Object.keys(EmbarkJS)
|
|
||||||
.filter((propName) => EmbarkJS[propName].hasOwnProperty("registerProvider"))
|
|
||||||
.forEach((providerName) => {
|
|
||||||
this.generateListener(providerName.toLowerCase(), ProviderEventType.ProviderRegistered);
|
|
||||||
});
|
|
||||||
|
|
||||||
// register listeners for when EmbarkJS runs setProvider through the console.
|
|
||||||
// For example, when `EmbarkJS.Storage.setProvider(...)` is run through the console,
|
|
||||||
// emit the `runcode:storage:providerSet` event, and fire any requests attached to it
|
|
||||||
Object.keys(EmbarkJS)
|
|
||||||
.filter((propName) => EmbarkJS[propName].hasOwnProperty("setProvider"))
|
|
||||||
.forEach((providerName) => {
|
|
||||||
this.generateListener(providerName.toLowerCase(), ProviderEventType.ProviderSet);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private resetEmbarkJS(cb?: Callback<null>) {
|
|
||||||
this.events.request("code-generator:embarkjs:init-provider-code", (code: string) => {
|
|
||||||
this.evalCode(code, (err) => {
|
|
||||||
if (err) {
|
|
||||||
console.dir(err);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (cb) { cb(); }
|
|
||||||
}, false);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private registerVar(varName: string, code: any, cb = () => { }) {
|
private registerVar(varName: string, code: any, cb = () => { }) {
|
||||||
@ -121,3 +70,5 @@ export default class CodeRunner {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default CodeRunner;
|
||||||
|
@ -38,6 +38,7 @@ class VM {
|
|||||||
"@babel/runtime-corejs2/core-js/promise",
|
"@babel/runtime-corejs2/core-js/promise",
|
||||||
"@babel/runtime-corejs2/helpers/interopRequireDefault",
|
"@babel/runtime-corejs2/helpers/interopRequireDefault",
|
||||||
"embark-utils",
|
"embark-utils",
|
||||||
|
// TODO: ideally this shouldnt' be needed/here or should be configurable by the modules themselves somehow
|
||||||
"embarkjs-ens",
|
"embarkjs-ens",
|
||||||
"embarkjs-ipfs",
|
"embarkjs-ipfs",
|
||||||
"embarkjs-swarm",
|
"embarkjs-swarm",
|
||||||
|
@ -28,6 +28,8 @@ class Console {
|
|||||||
private history: string[];
|
private history: string[];
|
||||||
private cmdHistoryFile: string;
|
private cmdHistoryFile: string;
|
||||||
private suggestions?: Suggestions;
|
private suggestions?: Suggestions;
|
||||||
|
private providerReady: boolean;
|
||||||
|
private helpCmds: any;
|
||||||
|
|
||||||
constructor(embark: Embark, options: any) {
|
constructor(embark: Embark, options: any) {
|
||||||
this.embark = embark;
|
this.embark = embark;
|
||||||
@ -41,6 +43,7 @@ class Console {
|
|||||||
this.history = [];
|
this.history = [];
|
||||||
this.cmdHistoryFile = options.cmdHistoryFile || dappPath(".embark", "cmd_history");
|
this.cmdHistoryFile = options.cmdHistoryFile || dappPath(".embark", "cmd_history");
|
||||||
this.loadHistory();
|
this.loadHistory();
|
||||||
|
this.helpCmds = {};
|
||||||
|
|
||||||
if (this.ipc.isServer()) {
|
if (this.ipc.isServer()) {
|
||||||
this.ipc.on("console:executeCmd", (cmd: string, cb: any) => {
|
this.ipc.on("console:executeCmd", (cmd: string, cb: any) => {
|
||||||
@ -57,6 +60,15 @@ class Console {
|
|||||||
this.saveHistory(cmd, true);
|
this.saveHistory(cmd, true);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
this.events.setCommandHandler("console:register:helpCmd", (options: any, cb: any) => {
|
||||||
|
const {cmdName, cmdHelp} = options;
|
||||||
|
this.helpCmds[cmdName] = cmdHelp;
|
||||||
|
if (cb) { cb(); }
|
||||||
|
});
|
||||||
|
this.events.setCommandHandler("console:unregister:helpCmd", (cmdName: string, cb: any) => {
|
||||||
|
delete this.helpCmds[cmdName];
|
||||||
|
if (cb) { cb(); }
|
||||||
|
});
|
||||||
this.events.setCommandHandler("console:executeCmd", this.executeCmd.bind(this));
|
this.events.setCommandHandler("console:executeCmd", this.executeCmd.bind(this));
|
||||||
this.events.setCommandHandler("console:history", (cb: any) => this.getHistory(this.cmdHistorySize(), cb));
|
this.events.setCommandHandler("console:history", (cb: any) => this.getHistory(this.cmdHistorySize(), cb));
|
||||||
this.registerConsoleCommands();
|
this.registerConsoleCommands();
|
||||||
@ -106,14 +118,20 @@ class Console {
|
|||||||
__("Welcome to Embark") + " " + this.version,
|
__("Welcome to Embark") + " " + this.version,
|
||||||
"",
|
"",
|
||||||
__("possible commands are:"),
|
__("possible commands are:"),
|
||||||
// TODO: only if the blockchain is actually active!
|
// TODO: this help commands should be passed through an API
|
||||||
// will need to pass te current embark state here
|
|
||||||
chalk.cyan("ipfs") + " - " + __("instantiated js-ipfs object configured to the current environment (available if ipfs is enabled)"),
|
chalk.cyan("ipfs") + " - " + __("instantiated js-ipfs object configured to the current environment (available if ipfs is enabled)"),
|
||||||
chalk.cyan("swarm") + " - " + __("instantiated swarm-api object configured to the current environment (available if swarm is enabled)"),
|
chalk.cyan("swarm") + " - " + __("instantiated swarm-api object configured to the current environment (available if swarm is enabled)"),
|
||||||
chalk.cyan("web3") + " - " + __("instantiated web3.js object configured to the current environment"),
|
|
||||||
chalk.cyan("EmbarkJS") + " - " + __("EmbarkJS static functions for Storage, Messages, Names, etc."),
|
chalk.cyan("EmbarkJS") + " - " + __("EmbarkJS static functions for Storage, Messages, Names, etc."),
|
||||||
chalk.cyan("log [process] on/off") + " - " + __("Activate or deactivate the logs of a sub-process. Options: blockchain, ipfs, webserver"),
|
chalk.cyan("log [process] on/off") + " - " + __("Activate or deactivate the logs of a sub-process. Options: blockchain, ipfs, webserver"),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
for (let cmdName in this.helpCmds) {
|
||||||
|
let helpCmd = this.helpCmds[cmdName];
|
||||||
|
helpText.push(chalk.cyan(cmdName) + " - " + helpCmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: remove old helpDescriptions
|
||||||
helpDescriptions.forEach((helpDescription) => {
|
helpDescriptions.forEach((helpDescription) => {
|
||||||
let matches = [] as string[];
|
let matches = [] as string[];
|
||||||
if (Array.isArray(helpDescription.matches)) {
|
if (Array.isArray(helpDescription.matches)) {
|
||||||
|
@ -14,6 +14,13 @@ interface Suggestion {
|
|||||||
|
|
||||||
type SuggestionsList = Suggestion[];
|
type SuggestionsList = Suggestion[];
|
||||||
|
|
||||||
|
// =============================================
|
||||||
|
// =============================================
|
||||||
|
// TODO: this should be moved to its own module
|
||||||
|
// it's a plugin not a core module
|
||||||
|
// =============================================
|
||||||
|
// =============================================
|
||||||
|
|
||||||
export default class Suggestions {
|
export default class Suggestions {
|
||||||
private embark: Embark;
|
private embark: Embark;
|
||||||
private events: Events;
|
private events: Events;
|
||||||
|
@ -62,7 +62,7 @@ export class ProcessLauncher {
|
|||||||
return self.exitCallback(code);
|
return self.exitCallback(code);
|
||||||
}
|
}
|
||||||
if (code) {
|
if (code) {
|
||||||
this.logger.info(`Child Process ${this.name} exited with code ${code}`);
|
self.logger.info(`Child Process ${this.name} exited with code ${code}`);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,8 @@ export class ProcessManager {
|
|||||||
|
|
||||||
this._registerApiCalls();
|
this._registerApiCalls();
|
||||||
this._registerEvents();
|
this._registerEvents();
|
||||||
this.events.once("deploy:beforeAll", this._registerCommands.bind(this));
|
// TODO: removed because Process Manager shouldn't care or have knoweldge about deployment
|
||||||
|
// this.events.once("deploy:beforeAll", this._registerCommands.bind(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
_registerApiCalls() {
|
_registerApiCalls() {
|
||||||
|
@ -34,7 +34,8 @@ class DeployTracker {
|
|||||||
if (this.chainFile === false) return;
|
if (this.chainFile === false) return;
|
||||||
const self = this;
|
const self = this;
|
||||||
|
|
||||||
this.embark.registerActionForEvent("deploy:beforeAll", this.setCurrentChain.bind(this));
|
// TODO: re-add
|
||||||
|
// this.embark.registerActionForEvent("deploy:beforeAll", this.setCurrentChain.bind(this));
|
||||||
|
|
||||||
this.events.on("deploy:contract:deployed", (contract) => {
|
this.events.on("deploy:contract:deployed", (contract) => {
|
||||||
self.trackContract(contract.className, contract.realRuntimeBytecode, contract.realArgs, contract.deployedAddress);
|
self.trackContract(contract.className, contract.realRuntimeBytecode, contract.realArgs, contract.deployedAddress);
|
||||||
|
@ -85,6 +85,7 @@ class ContractDeployer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
checkAndDeployContract(contract, params, callback, returnObject) {
|
checkAndDeployContract(contract, params, callback, returnObject) {
|
||||||
|
console.dir("= checkAndDeployContract: " + contract.className);
|
||||||
let self = this;
|
let self = this;
|
||||||
contract.error = false;
|
contract.error = false;
|
||||||
let accounts = [];
|
let accounts = [];
|
||||||
@ -176,6 +177,7 @@ class ContractDeployer {
|
|||||||
return self.deployContract(contract, next, returnObject);
|
return self.deployContract(contract, next, returnObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.dir("== emitAndRunActionsForEvent / should Deploy");
|
||||||
self.plugins.emitAndRunActionsForEvent('deploy:contract:shouldDeploy', {contract: contract, shouldDeploy: true}, function(_err, params) {
|
self.plugins.emitAndRunActionsForEvent('deploy:contract:shouldDeploy', {contract: contract, shouldDeploy: true}, function(_err, params) {
|
||||||
let trackedContract = params.contract;
|
let trackedContract = params.contract;
|
||||||
if (!params.shouldDeploy) {
|
if (!params.shouldDeploy) {
|
||||||
@ -202,7 +204,9 @@ class ContractDeployer {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
], callback);
|
], (err,results) => {
|
||||||
|
callback(err, results);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
willNotDeployContract(contract, trackedContract, callback) {
|
willNotDeployContract(contract, trackedContract, callback) {
|
||||||
@ -212,26 +216,13 @@ class ContractDeployer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
contractAlreadyDeployed(contract, trackedContract, callback) {
|
contractAlreadyDeployed(contract, trackedContract, callback) {
|
||||||
|
console.dir("--> contractAlreadyDeployed")
|
||||||
this.logFunction(contract)(contract.className.bold.cyan + __(" already deployed at ").green + trackedContract.address.bold.cyan);
|
this.logFunction(contract)(contract.className.bold.cyan + __(" already deployed at ").green + trackedContract.address.bold.cyan);
|
||||||
contract.deployedAddress = trackedContract.address;
|
contract.deployedAddress = trackedContract.address;
|
||||||
this.events.emit("deploy:contract:deployed", contract);
|
this.events.emit("deploy:contract:deployed", contract);
|
||||||
|
|
||||||
this.registerContract(contract, callback);
|
this.plugins.runActionsForEvent('deploy:contract:deployed', {contract: contract}, (err) => {
|
||||||
}
|
callback(err);
|
||||||
|
|
||||||
registerContract(contract, callback) {
|
|
||||||
this.events.request('code-generator:contract:custom', contract, (contractCode) => {
|
|
||||||
this.events.request('runcode:eval', contractCode, (err) => {
|
|
||||||
if (err) {
|
|
||||||
return callback(err);
|
|
||||||
}
|
|
||||||
this.events.request('runcode:eval', contract.className, (err, result) => {
|
|
||||||
if (err) {
|
|
||||||
return callback(err);
|
|
||||||
}
|
|
||||||
this.events.emit("runcode:register", contract.className, result, callback);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -240,11 +231,13 @@ class ContractDeployer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
deployContract(contract, callback, returnObject) {
|
deployContract(contract, callback, returnObject) {
|
||||||
|
console.dir("deployContract")
|
||||||
let self = this;
|
let self = this;
|
||||||
let deployObject;
|
let deployObject;
|
||||||
|
|
||||||
async.waterfall([
|
async.waterfall([
|
||||||
function doLinking(next) {
|
function doLinking(next) {
|
||||||
|
console.dir("= doLinking")
|
||||||
|
|
||||||
if (!contract.linkReferences || !Object.keys(contract.linkReferences).length) {
|
if (!contract.linkReferences || !Object.keys(contract.linkReferences).length) {
|
||||||
return next();
|
return next();
|
||||||
@ -288,11 +281,13 @@ class ContractDeployer {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
function applyBeforeDeploy(next) {
|
function applyBeforeDeploy(next) {
|
||||||
|
console.dir("= applyBeforeDeploy")
|
||||||
self.plugins.emitAndRunActionsForEvent('deploy:contract:beforeDeploy', {contract: contract}, (_params) => {
|
self.plugins.emitAndRunActionsForEvent('deploy:contract:beforeDeploy', {contract: contract}, (_params) => {
|
||||||
next();
|
next();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
function getGasPriceForNetwork(next) {
|
function getGasPriceForNetwork(next) {
|
||||||
|
console.dir("= getGasPriceForNetwork")
|
||||||
self.events.request("blockchain:gasPrice", (err, gasPrice) => {
|
self.events.request("blockchain:gasPrice", (err, gasPrice) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
return next(new Error(__("could not get the gas price")));
|
return next(new Error(__("could not get the gas price")));
|
||||||
@ -302,6 +297,7 @@ class ContractDeployer {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
function createDeployObject(next) {
|
function createDeployObject(next) {
|
||||||
|
console.dir("= createDeployObject")
|
||||||
let contractCode = contract.code;
|
let contractCode = contract.code;
|
||||||
let contractObject = self.blockchain.ContractObject({abi: contract.abiDefinition});
|
let contractObject = self.blockchain.ContractObject({abi: contract.abiDefinition});
|
||||||
let contractParams = (contract.realArgs || contract.args).slice();
|
let contractParams = (contract.realArgs || contract.args).slice();
|
||||||
@ -343,6 +339,7 @@ class ContractDeployer {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
function deployTheContract(next) {
|
function deployTheContract(next) {
|
||||||
|
console.dir("= deployTheContract " + contract.className)
|
||||||
let estimatedCost = contract.gas * contract.gasPrice;
|
let estimatedCost = contract.gas * contract.gasPrice;
|
||||||
|
|
||||||
self.blockchain.deployContractFromObject(deployObject, {
|
self.blockchain.deployContractFromObject(deployObject, {
|
||||||
@ -350,6 +347,9 @@ class ContractDeployer {
|
|||||||
gas: contract.gas,
|
gas: contract.gas,
|
||||||
gasPrice: contract.gasPrice
|
gasPrice: contract.gasPrice
|
||||||
}, function(error, receipt) {
|
}, function(error, receipt) {
|
||||||
|
console.dir("--> contract deployed")
|
||||||
|
console.dir(error)
|
||||||
|
console.dir(receipt)
|
||||||
if (error) {
|
if (error) {
|
||||||
contract.error = error.message;
|
contract.error = error.message;
|
||||||
self.events.emit("deploy:contract:error", contract);
|
self.events.emit("deploy:contract:error", contract);
|
||||||
@ -366,19 +366,25 @@ class ContractDeployer {
|
|||||||
if(receipt) self.events.emit("deploy:contract:receipt", receipt);
|
if(receipt) self.events.emit("deploy:contract:receipt", receipt);
|
||||||
self.events.emit("deploy:contract:deployed", contract);
|
self.events.emit("deploy:contract:deployed", contract);
|
||||||
|
|
||||||
self.registerContract(contract, () => {
|
// console.dir("__registerContract")
|
||||||
|
// self.registerContract(contract, () => {
|
||||||
|
console.dir("__runActionsForEvent deploy:contract:deployed")
|
||||||
self.plugins.runActionsForEvent('deploy:contract:deployed', {contract: contract}, (err) => {
|
self.plugins.runActionsForEvent('deploy:contract:deployed', {contract: contract}, (err) => {
|
||||||
|
console.dir("result __runActionsForEvent deploy:contract:deployed")
|
||||||
if (err) {
|
if (err) {
|
||||||
|
console.dir(err)
|
||||||
return next(err);
|
return next(err);
|
||||||
}
|
}
|
||||||
next(null, receipt);
|
next(null, receipt);
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}, hash => {
|
}, hash => {
|
||||||
self.logFunction(contract)(__("deploying") + " " + contract.className.bold.cyan + " " + __("with").green + " " + contract.gas + " " + __("gas at the price of").green + " " + contract.gasPrice + " " + __("Wei, estimated cost:").green + " " + estimatedCost + " Wei".green + " (txHash: " + hash.bold.cyan + ")");
|
self.logFunction(contract)(__("deploying") + " " + contract.className.bold.cyan + " " + __("with").green + " " + contract.gas + " " + __("gas at the price of").green + " " + contract.gasPrice + " " + __("Wei, estimated cost:").green + " " + estimatedCost + " Wei".green + " (txHash: " + hash.bold.cyan + ")");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
], callback);
|
], (__err, __results) => {
|
||||||
|
console.dir("--- deployed Contract")
|
||||||
|
callback(__err, __results)
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -54,9 +54,12 @@ class DeployManager {
|
|||||||
function (next) {
|
function (next) {
|
||||||
self.logger.info(__('Executing pre-deploy actions...'));
|
self.logger.info(__('Executing pre-deploy actions...'));
|
||||||
self.plugins.emitAndRunActionsForEvent("deploy:beforeAll", (err) => {
|
self.plugins.emitAndRunActionsForEvent("deploy:beforeAll", (err) => {
|
||||||
if (err) {
|
// console.dir("== err")
|
||||||
return next(err);
|
// console.dir(err)
|
||||||
}
|
// TODO: err is a function for some reason
|
||||||
|
// if (err) {
|
||||||
|
// return next(err);
|
||||||
|
// }
|
||||||
self.logger.info(__('Pre-deploy actions done. Deploying contracts'));
|
self.logger.info(__('Pre-deploy actions done. Deploying contracts'));
|
||||||
next();
|
next();
|
||||||
});
|
});
|
||||||
@ -64,6 +67,8 @@ class DeployManager {
|
|||||||
function (next) {
|
function (next) {
|
||||||
const contractDeploys = {};
|
const contractDeploys = {};
|
||||||
const errors = [];
|
const errors = [];
|
||||||
|
console.dir("=== contracts")
|
||||||
|
console.dir(contracts.map((x) => x.className))
|
||||||
contracts.forEach(contract => {
|
contracts.forEach(contract => {
|
||||||
function deploy(result, callback) {
|
function deploy(result, callback) {
|
||||||
if (typeof result === 'function') {
|
if (typeof result === 'function') {
|
||||||
@ -71,7 +76,10 @@ class DeployManager {
|
|||||||
}
|
}
|
||||||
contract._gasLimit = self.gasLimit;
|
contract._gasLimit = self.gasLimit;
|
||||||
self.events.request('deploy:contract', contract, (err) => {
|
self.events.request('deploy:contract', contract, (err) => {
|
||||||
|
console.dir("contract deployed " + contract.className)
|
||||||
if (err) {
|
if (err) {
|
||||||
|
console.dir("== err deploying contract");
|
||||||
|
console.dir(err);
|
||||||
contract.error = err.message || err;
|
contract.error = err.message || err;
|
||||||
if (contract.error === constants.blockchain.gasAllowanceError) {
|
if (contract.error === constants.blockchain.gasAllowanceError) {
|
||||||
self.logger.error(`[${contract.className}]: ${constants.blockchain.gasAllowanceErrorMessage}`);
|
self.logger.error(`[${contract.className}]: ${constants.blockchain.gasAllowanceErrorMessage}`);
|
||||||
@ -93,7 +101,14 @@ class DeployManager {
|
|||||||
contractDeploys[className].push(deploy);
|
contractDeploys[className].push(deploy);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
console.dir("== async.auto");
|
||||||
|
console.dir(Object.keys(contractDeploys));
|
||||||
|
console.dir(contractDeploys);
|
||||||
async.auto(contractDeploys, function(_err, _results) {
|
async.auto(contractDeploys, function(_err, _results) {
|
||||||
|
if (_err) {
|
||||||
|
console.dir("error deploying contracts")
|
||||||
|
console.dir(_err)
|
||||||
|
}
|
||||||
if (errors.length) {
|
if (errors.length) {
|
||||||
_err = __("Error deploying contracts. Please fix errors to continue.");
|
_err = __("Error deploying contracts. Please fix errors to continue.");
|
||||||
self.logger.error(_err);
|
self.logger.error(_err);
|
||||||
@ -109,6 +124,7 @@ class DeployManager {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
], (err) => {
|
], (err) => {
|
||||||
|
console.dir("==== finished deploying")
|
||||||
if (err) {
|
if (err) {
|
||||||
self.logger.error(err);
|
self.logger.error(err);
|
||||||
}
|
}
|
||||||
|
@ -150,6 +150,12 @@ class ENS {
|
|||||||
|
|
||||||
registerEvents() {
|
registerEvents() {
|
||||||
this.embark.registerActionForEvent("deploy:beforeAll", this.configureContractsAndRegister.bind(this));
|
this.embark.registerActionForEvent("deploy:beforeAll", this.configureContractsAndRegister.bind(this));
|
||||||
|
if (this.eventsRegistered) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.eventsRegistered = true;
|
||||||
|
// TODO: re-add
|
||||||
|
// this.embark.registerActionForEvent("deploy:beforeAll", this.configureContractsAndRegister.bind(this));
|
||||||
this.events.on('blockchain:reseted', this.reset.bind(this));
|
this.events.on('blockchain:reseted', this.reset.bind(this));
|
||||||
this.events.setCommandHandler("storage:ens:associate", this.associateStorageToEns.bind(this));
|
this.events.setCommandHandler("storage:ens:associate", this.associateStorageToEns.bind(this));
|
||||||
this.events.setCommandHandler("ens:config", this.getEnsConfig.bind(this));
|
this.events.setCommandHandler("ens:config", this.getEnsConfig.bind(this));
|
||||||
|
@ -1,21 +1,16 @@
|
|||||||
const async = require('async');
|
const async = require('async');
|
||||||
const Viz = require('viz.js');
|
const Viz = require('viz.js');
|
||||||
const fs = require('fs');
|
|
||||||
|
|
||||||
class GraphGenerator {
|
class GraphGenerator {
|
||||||
constructor(embark, _options) {
|
constructor(embark, _options) {
|
||||||
const self = this;
|
this.embark = embark;
|
||||||
this.events = embark.events;
|
this.events = embark.events;
|
||||||
this.contracts = [];
|
|
||||||
|
|
||||||
this.events.setCommandHandler("graph:create", function(options, cb) {
|
this.events.setCommandHandler("graph:create", this.generate.bind(this));
|
||||||
self.generate(options);
|
|
||||||
cb();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*eslint complexity: ["error", 21]*/
|
/*eslint complexity: ["error", 21]*/
|
||||||
generate(options) {
|
generate(options, cb) {
|
||||||
const self = this;
|
const self = this;
|
||||||
let id = 0;
|
let id = 0;
|
||||||
let contractString = "";
|
let contractString = "";
|
||||||
@ -23,6 +18,7 @@ class GraphGenerator {
|
|||||||
let idMapping = {};
|
let idMapping = {};
|
||||||
let contractInheritance = {};
|
let contractInheritance = {};
|
||||||
let contractsDependencies = {};
|
let contractsDependencies = {};
|
||||||
|
this.contracts = [];
|
||||||
|
|
||||||
async.waterfall([
|
async.waterfall([
|
||||||
function getContractList(next) {
|
function getContractList(next) {
|
||||||
@ -134,12 +130,13 @@ class GraphGenerator {
|
|||||||
|
|
||||||
let svg = Viz(dot);
|
let svg = Viz(dot);
|
||||||
|
|
||||||
fs.writeFileSync(options.output, svg, (err) => {
|
self.embark.fs.writeFileSync(options.output, svg, (err) => {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
next();
|
next();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
], function(_err, _result) {
|
], function(_err, _result) {
|
||||||
|
cb();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,6 +2,8 @@ const ProcessLogsApi = require('embark-process-logs-api');
|
|||||||
|
|
||||||
const EMBARK_PROCESS_NAME = 'embark';
|
const EMBARK_PROCESS_NAME = 'embark';
|
||||||
|
|
||||||
|
// TODO: looks unnecessary, should be moved to a common module together with embark-process-logs-api
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* EmbarkListener has two functions:
|
* EmbarkListener has two functions:
|
||||||
* 1. Register API endpoints (HTTP GET and WS) to retrieve embark logs.
|
* 1. Register API endpoints (HTTP GET and WS) to retrieve embark logs.
|
||||||
|
@ -53,8 +53,7 @@
|
|||||||
"embark-i18n": "^4.1.0-beta.3",
|
"embark-i18n": "^4.1.0-beta.3",
|
||||||
"embark-utils": "^4.1.0-beta.5",
|
"embark-utils": "^4.1.0-beta.5",
|
||||||
"find-up": "2.1.0",
|
"find-up": "2.1.0",
|
||||||
"fs-extra": "7.0.1",
|
"fs-extra": "7.0.1"
|
||||||
"webpack": "4.29.3"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/cli": "7.2.3",
|
"@babel/cli": "7.2.3",
|
||||||
|
119
packages/embark-pipeline/src/api.js
Normal file
119
packages/embark-pipeline/src/api.js
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
const path = require('path');
|
||||||
|
import { dappPath, fileTreeSort } from 'embark-utils';
|
||||||
|
|
||||||
|
class API {
|
||||||
|
|
||||||
|
constructor(embark, _options) {
|
||||||
|
this.plugins = embark.config.plugins;
|
||||||
|
}
|
||||||
|
|
||||||
|
registerAPIs() {
|
||||||
|
let plugin = this.plugins.createPlugin('deployment', {});
|
||||||
|
plugin.registerAPICall(
|
||||||
|
'get',
|
||||||
|
'/embark-api/file',
|
||||||
|
(req, res) => {
|
||||||
|
try {
|
||||||
|
this.apiGuardBadFile(req.query.path);
|
||||||
|
} catch (error) {
|
||||||
|
return res.send({ error: error.message });
|
||||||
|
}
|
||||||
|
|
||||||
|
const name = path.basename(req.query.path);
|
||||||
|
const content = this.fs.readFileSync(req.query.path, 'utf8');
|
||||||
|
res.send({ name, content, path: req.query.path });
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
plugin.registerAPICall(
|
||||||
|
'post',
|
||||||
|
'/embark-api/folders',
|
||||||
|
(req, res) => {
|
||||||
|
try {
|
||||||
|
this.apiGuardBadFile(req.body.path);
|
||||||
|
} catch (error) {
|
||||||
|
return res.send({ error: error.message });
|
||||||
|
}
|
||||||
|
|
||||||
|
this.fs.mkdirpSync(req.body.path);
|
||||||
|
const name = path.basename(req.body.path);
|
||||||
|
res.send({ name, path: req.body.path });
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
plugin.registerAPICall(
|
||||||
|
'post',
|
||||||
|
'/embark-api/files',
|
||||||
|
(req, res) => {
|
||||||
|
try {
|
||||||
|
this.apiGuardBadFile(req.body.path);
|
||||||
|
} catch (error) {
|
||||||
|
return res.send({ error: error.message });
|
||||||
|
}
|
||||||
|
|
||||||
|
this.fs.writeFileSync(req.body.path, req.body.content, { encoding: 'utf8' });
|
||||||
|
const name = path.basename(req.body.path);
|
||||||
|
res.send({ name, path: req.body.path, content: req.body.content });
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
plugin.registerAPICall(
|
||||||
|
'delete',
|
||||||
|
'/embark-api/file',
|
||||||
|
(req, res) => {
|
||||||
|
try {
|
||||||
|
this.apiGuardBadFile(req.query.path, { ensureExists: true });
|
||||||
|
} catch (error) {
|
||||||
|
return res.send({ error: error.message });
|
||||||
|
}
|
||||||
|
this.fs.removeSync(req.query.path);
|
||||||
|
res.send();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
plugin.registerAPICall(
|
||||||
|
'get',
|
||||||
|
'/embark-api/files',
|
||||||
|
(req, res) => {
|
||||||
|
const rootPath = dappPath();
|
||||||
|
|
||||||
|
const walk = (dir, filelist = []) => this.fs.readdirSync(dir).map(name => {
|
||||||
|
let isRoot = rootPath === dir;
|
||||||
|
if (this.fs.statSync(path.join(dir, name)).isDirectory()) {
|
||||||
|
return {
|
||||||
|
isRoot,
|
||||||
|
name,
|
||||||
|
dirname: dir,
|
||||||
|
path: path.join(dir, name),
|
||||||
|
isHidden: (name.indexOf('.') === 0 || name === "node_modules"),
|
||||||
|
children: fileTreeSort(walk(path.join(dir, name), filelist))
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
name,
|
||||||
|
isRoot,
|
||||||
|
path: path.join(dir, name),
|
||||||
|
dirname: dir,
|
||||||
|
isHidden: (name.indexOf('.') === 0 || name === "node_modules")
|
||||||
|
};
|
||||||
|
});
|
||||||
|
const files = fileTreeSort(walk(dappPath()));
|
||||||
|
res.send(files);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
apiGuardBadFile(pathToCheck, options = {ensureExists: false}) {
|
||||||
|
const dir = path.dirname(pathToCheck);
|
||||||
|
const error = new Error('Path is invalid');
|
||||||
|
if (options.ensureExists && !this.fs.existsSync(pathToCheck)) {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
if (!dir.startsWith(dappPath())) {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = API;
|
@ -1,402 +1,88 @@
|
|||||||
const path = require('path');
|
|
||||||
const async = require('async');
|
const async = require('async');
|
||||||
import { __ } from 'embark-i18n';
|
import { dappPath } from 'embark-utils';
|
||||||
import { dappPath, joinPath, LongRunningProcessTimer, fileTreeSort } from 'embark-utils';
|
|
||||||
import { ProcessLauncher } from 'embark-core';
|
const PipelineAPI = require('./api.js');
|
||||||
const constants = require('embark-core/constants');
|
|
||||||
const WebpackConfigReader = require('./webpackConfigReader');
|
|
||||||
|
|
||||||
class Pipeline {
|
class Pipeline {
|
||||||
constructor(embark, options) {
|
constructor(embark, options) {
|
||||||
this.embark = embark;
|
|
||||||
this.env = embark.config.env;
|
|
||||||
this.buildDir = embark.config.buildDir;
|
|
||||||
this.contractsFiles = embark.config.contractsFiles;
|
|
||||||
this.assetFiles = embark.config.assetFiles;
|
|
||||||
this.embarkConfig = embark.config.embarkConfig;
|
|
||||||
this.events = embark.events;
|
this.events = embark.events;
|
||||||
this.logger = embark.config.logger;
|
|
||||||
this.plugins = embark.config.plugins;
|
this.plugins = embark.config.plugins;
|
||||||
this.fs = embark.fs;
|
this.fs = embark.fs;
|
||||||
this.webpackConfigName = options.webpackConfigName;
|
this.files = {}
|
||||||
this.pipelinePlugins = this.plugins.getPluginsFor('pipeline');
|
|
||||||
this.pipelineConfig = embark.config.pipelineConfig;
|
|
||||||
this.isFirstBuild = true;
|
|
||||||
this.useDashboard = options.useDashboard;
|
|
||||||
|
|
||||||
// track changes to the pipeline config in the filesystem
|
this.api = new PipelineAPI(embark, options);
|
||||||
this.events.on('config:load:pipeline', (pipelineConfig) => {
|
this.api.registerAPIs();
|
||||||
this.pipelineConfig = pipelineConfig;
|
|
||||||
|
this.events.setCommandHandler('pipeline:generateAll', this.generateAll.bind(this));
|
||||||
|
|
||||||
|
this.events.setCommandHandler('pipeline:register', (params, cb) => {
|
||||||
|
this.files[dappPath(...params.path, params.file)] = params;
|
||||||
|
if (cb) { cb(); }
|
||||||
});
|
});
|
||||||
|
|
||||||
this.events.setCommandHandler('pipeline:build', (options, callback) => {
|
|
||||||
if(!this.pipelineConfig.enabled) {
|
|
||||||
return this.buildContracts([], callback);
|
|
||||||
}
|
|
||||||
this.build(options, callback);
|
|
||||||
});
|
|
||||||
this.events.setCommandHandler('pipeline:build:contracts', callback => this.buildContracts([], callback));
|
|
||||||
this.fs.removeSync(this.buildDir);
|
|
||||||
|
|
||||||
let plugin = this.plugins.createPlugin('deployment', {});
|
|
||||||
plugin.registerAPICall(
|
|
||||||
'get',
|
|
||||||
'/embark-api/file',
|
|
||||||
(req, res) => {
|
|
||||||
try {
|
|
||||||
this.apiGuardBadFile(req.query.path);
|
|
||||||
} catch (error) {
|
|
||||||
return res.send({error: error.message});
|
|
||||||
}
|
|
||||||
|
|
||||||
const name = path.basename(req.query.path);
|
|
||||||
const content = this.fs.readFileSync(req.query.path, 'utf8');
|
|
||||||
res.send({name, content, path: req.query.path});
|
|
||||||
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
plugin.registerAPICall(
|
|
||||||
'post',
|
|
||||||
'/embark-api/folders',
|
|
||||||
(req, res) => {
|
|
||||||
try {
|
|
||||||
this.apiGuardBadFile(req.body.path);
|
|
||||||
} catch (error) {
|
|
||||||
return res.send({error: error.message});
|
|
||||||
}
|
|
||||||
|
|
||||||
this.fs.mkdirpSync(req.body.path);
|
|
||||||
const name = path.basename(req.body.path);
|
|
||||||
res.send({name, path: req.body.path});
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
plugin.registerAPICall(
|
|
||||||
'post',
|
|
||||||
'/embark-api/files',
|
|
||||||
(req, res) => {
|
|
||||||
try {
|
|
||||||
this.apiGuardBadFile(req.body.path);
|
|
||||||
} catch (error) {
|
|
||||||
return res.send({error: error.message});
|
|
||||||
}
|
|
||||||
|
|
||||||
this.fs.writeFileSync(req.body.path, req.body.content, {encoding: 'utf8'});
|
|
||||||
const name = path.basename(req.body.path);
|
|
||||||
res.send({name, path: req.body.path, content: req.body.content});
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
plugin.registerAPICall(
|
|
||||||
'delete',
|
|
||||||
'/embark-api/file',
|
|
||||||
(req, res) => {
|
|
||||||
try {
|
|
||||||
this.apiGuardBadFile(req.query.path, {ensureExists: true});
|
|
||||||
} catch (error) {
|
|
||||||
return res.send({error: error.message});
|
|
||||||
}
|
|
||||||
this.fs.removeSync(req.query.path);
|
|
||||||
res.send();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
plugin.registerAPICall(
|
|
||||||
'get',
|
|
||||||
'/embark-api/files',
|
|
||||||
(req, res) => {
|
|
||||||
const rootPath = dappPath();
|
|
||||||
|
|
||||||
const walk = (dir, filelist = []) => this.fs.readdirSync(dir).map(name => {
|
|
||||||
let isRoot = rootPath === dir;
|
|
||||||
if (this.fs.statSync(path.join(dir, name)).isDirectory()) {
|
|
||||||
return {
|
|
||||||
isRoot,
|
|
||||||
name,
|
|
||||||
dirname: dir,
|
|
||||||
path: path.join(dir, name),
|
|
||||||
isHidden: (name.indexOf('.') === 0 || name === "node_modules"),
|
|
||||||
children: fileTreeSort(walk(path.join(dir, name), filelist))
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
name,
|
|
||||||
isRoot,
|
|
||||||
path: path.join(dir, name),
|
|
||||||
dirname: dir,
|
|
||||||
isHidden: (name.indexOf('.') === 0 || name === "node_modules")
|
|
||||||
};
|
|
||||||
});
|
|
||||||
const files = fileTreeSort(walk(dappPath()));
|
|
||||||
res.send(files);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
apiGuardBadFile(pathToCheck, options = {ensureExists: false}) {
|
generateAll(cb) {
|
||||||
const dir = path.dirname(pathToCheck);
|
console.dir("generating all files");
|
||||||
const error = new Error('Path is invalid');
|
|
||||||
if (options.ensureExists && !this.fs.existsSync(pathToCheck)) {
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
if (!dir.startsWith(dappPath())) {
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
build({modifiedAssets}, callback) {
|
|
||||||
let self = this;
|
|
||||||
const importsList = {};
|
|
||||||
let placeholderPage;
|
|
||||||
const contractsDir = dappPath(self.embarkConfig.generationDir, constants.dappArtifacts.contractsJs);
|
|
||||||
|
|
||||||
if (!self.assetFiles || !Object.keys(self.assetFiles).length) {
|
|
||||||
return self.buildContracts([], callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
async.waterfall([
|
async.waterfall([
|
||||||
function createPlaceholderPage(next) {
|
(next) => {
|
||||||
if (self.isFirstBuild) {
|
this.plugins.runActionsForEvent("pipeline:generateAll:before", {}, (err) => {
|
||||||
self.isFirstBuild = false;
|
next(err);
|
||||||
return next();
|
|
||||||
}
|
|
||||||
self.events.request('placeholder:build', next);
|
|
||||||
},
|
|
||||||
(next) => self.buildContracts(importsList, next),
|
|
||||||
function createImportList(next) {
|
|
||||||
importsList["Embark/EmbarkJS"] = dappPath(self.embarkConfig.generationDir, constants.dappArtifacts.embarkjs);
|
|
||||||
importsList["Embark/contracts"] = contractsDir;
|
|
||||||
|
|
||||||
self.plugins.getPluginsProperty('imports', 'imports').forEach(importObject => {
|
|
||||||
let [importName, importLocation] = importObject;
|
|
||||||
importsList[importName] = importLocation;
|
|
||||||
});
|
});
|
||||||
|
},
|
||||||
|
(next) => {
|
||||||
|
// TODO: make this async
|
||||||
|
for (let fileParams of Object.values(this.files)) {
|
||||||
|
if (fileParams.format === 'json') {
|
||||||
|
this.writeJSONFile(fileParams)
|
||||||
|
} else {
|
||||||
|
this.writeFile(fileParams)
|
||||||
|
}
|
||||||
|
}
|
||||||
next();
|
next();
|
||||||
},
|
},
|
||||||
function shouldRunWebpack(next) {
|
(next) => {
|
||||||
// assuming we got here because an asset was changed, let's check our webpack config
|
this.plugins.runActionsForEvent("pipeline:generateAll:after", {}, (err) => {
|
||||||
// to see if the changed asset requires webpack to run
|
next(err);
|
||||||
if (!(modifiedAssets && modifiedAssets.length)) return next(null, false);
|
|
||||||
const configReader = new WebpackConfigReader({webpackConfigName: self.webpackConfigName});
|
|
||||||
return configReader.readConfig((err, config) => {
|
|
||||||
if (err) return next(err);
|
|
||||||
|
|
||||||
if (typeof config !== 'object' || config === null) {
|
|
||||||
return next(__('Pipeline: bad webpack config, the resolved config was null or not an object'));
|
|
||||||
}
|
|
||||||
|
|
||||||
const shouldRun = modifiedAssets.some(modifiedAsset => config.module.rules.some(rule => rule.test.test(modifiedAsset)));
|
|
||||||
return next(null, !shouldRun);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
function runWebpack(shouldNotRun, next) {
|
|
||||||
if (shouldNotRun) return next();
|
|
||||||
const assets = Object.keys(self.assetFiles).filter(key => key.match(/\.js$/));
|
|
||||||
if (!assets || !assets.length) {
|
|
||||||
return next();
|
|
||||||
}
|
|
||||||
let strAssets = '';
|
|
||||||
if (!self.useDashboard) {
|
|
||||||
assets.forEach(key => {
|
|
||||||
strAssets += ('\n ' + (joinPath(self.buildDir, key)).bold.dim);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
const timer = new LongRunningProcessTimer(
|
|
||||||
self.logger,
|
|
||||||
'webpack',
|
|
||||||
'0',
|
|
||||||
`${'Pipeline:'.cyan} Bundling dapp using '${self.webpackConfigName}' config...${strAssets}`,
|
|
||||||
`${'Pipeline:'.cyan} Still bundling dapp using '${self.webpackConfigName}' config... ({{duration}})${strAssets}`,
|
|
||||||
`${'Pipeline:'.cyan} Finished bundling dapp in {{duration}}${strAssets}`,
|
|
||||||
{
|
|
||||||
showSpinner: !self.useDashboard,
|
|
||||||
interval: self.useDashboard ? 5000 : 1000,
|
|
||||||
longRunningThreshold: 15000
|
|
||||||
}
|
|
||||||
);
|
|
||||||
timer.start();
|
|
||||||
let built = false;
|
|
||||||
const webpackProcess = new ProcessLauncher({
|
|
||||||
embark: self.embark,
|
|
||||||
plugins: self.plugins,
|
|
||||||
modulePath: joinPath(__dirname, 'webpackProcess.js'),
|
|
||||||
logger: self.logger,
|
|
||||||
events: self.events,
|
|
||||||
exitCallback: code => {
|
|
||||||
if (!built) {
|
|
||||||
return next(`Webpack build exited with code ${code} before the process finished`);
|
|
||||||
}
|
|
||||||
if (code) {
|
|
||||||
self.logger.error(__('Webpack build process exited with code ', code));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
webpackProcess.send({
|
|
||||||
action: constants.pipeline.init,
|
|
||||||
options: {
|
|
||||||
webpackConfigName: self.webpackConfigName,
|
|
||||||
pipelineConfig: self.pipelineConfig,
|
|
||||||
fs: self.embark.fs
|
|
||||||
}
|
|
||||||
});
|
|
||||||
webpackProcess.send({action: constants.pipeline.build, assets: self.assetFiles, importsList});
|
|
||||||
|
|
||||||
webpackProcess.once('result', constants.pipeline.built, (msg) => {
|
|
||||||
built = true;
|
|
||||||
webpackProcess.kill();
|
|
||||||
return next(msg.error);
|
|
||||||
});
|
|
||||||
webpackProcess.once('result', constants.pipeline.webpackDone, () => {
|
|
||||||
timer.end();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
function assetFileWrite(next) {
|
|
||||||
async.eachOf(
|
|
||||||
// assetFileWrite should not process .js files
|
|
||||||
Object.keys(self.assetFiles)
|
|
||||||
.filter(key => !key.match(/\.js$/))
|
|
||||||
.reduce((obj, key) => {
|
|
||||||
obj[key] = self.assetFiles[key];
|
|
||||||
return obj;
|
|
||||||
}, {}),
|
|
||||||
function (files, targetFile, cb) {
|
|
||||||
const isDir = targetFile.slice(-1) === '/' || targetFile.slice(-1) === '\\' || targetFile.indexOf('.') === -1;
|
|
||||||
// if it's not a directory
|
|
||||||
if (!isDir) {
|
|
||||||
self.logger.info('Pipeline: '.cyan + __("writing file") + " " + (joinPath(self.buildDir, targetFile)).bold.dim);
|
|
||||||
}
|
|
||||||
async.map(
|
|
||||||
files,
|
|
||||||
function (file, fileCb) {
|
|
||||||
self.logger.trace("reading " + file.path);
|
|
||||||
file.content.then((fileContent) => {
|
|
||||||
self.runPlugins(file, fileContent, fileCb);
|
|
||||||
}).catch(fileCb);
|
|
||||||
},
|
|
||||||
function (err, contentFiles) {
|
|
||||||
if (err) {
|
|
||||||
self.logger.error('Pipeline: '.cyan + __('errors found while generating') + ' ' + targetFile);
|
|
||||||
}
|
|
||||||
let dir = targetFile.split('/').slice(0, -1).join('/');
|
|
||||||
self.logger.trace(`${'Pipeline:'.cyan} creating dir ` + joinPath(self.buildDir, dir));
|
|
||||||
self.fs.mkdirpSync(joinPath(self.buildDir, dir));
|
|
||||||
|
|
||||||
// if it's a directory
|
|
||||||
if (isDir) {
|
|
||||||
let targetDir = targetFile;
|
|
||||||
|
|
||||||
if (targetDir.slice(-1) !== '/') {
|
|
||||||
targetDir = targetDir + '/';
|
|
||||||
}
|
|
||||||
|
|
||||||
async.each(contentFiles, function (file, eachCb) {
|
|
||||||
let filename = file.path.replace(file.basedir + '/', '');
|
|
||||||
self.logger.info(`${'Pipeline:'.cyan} writing file ` + (joinPath(self.buildDir, targetDir, filename)).bold.dim);
|
|
||||||
|
|
||||||
self.fs.copy(file.path, joinPath(self.buildDir, targetDir, filename), {overwrite: true}, eachCb);
|
|
||||||
}, cb);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let content = contentFiles.map(file => {
|
|
||||||
if (file === undefined) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
return file.content;
|
|
||||||
}).join("\n");
|
|
||||||
|
|
||||||
if (new RegExp(/^index.html?/i).test(targetFile)) {
|
|
||||||
targetFile = targetFile.replace('index', 'index-temp');
|
|
||||||
placeholderPage = targetFile;
|
|
||||||
}
|
|
||||||
self.fs.writeFile(joinPath(self.buildDir, targetFile), content, cb);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
},
|
|
||||||
next
|
|
||||||
);
|
|
||||||
},
|
|
||||||
function removePlaceholderPage(next) {
|
|
||||||
let placeholderFile = joinPath(self.buildDir, placeholderPage);
|
|
||||||
self.fs.access(joinPath(self.buildDir, placeholderPage), (err) => {
|
|
||||||
if (err) return next(); // index-temp doesn't exist, do nothing
|
|
||||||
|
|
||||||
// rename index-temp.htm/l to index.htm/l, effectively replacing our placeholder page
|
|
||||||
// with the contents of the built index.html page
|
|
||||||
self.fs.move(placeholderFile, placeholderFile.replace('index-temp', 'index'), {overwrite: true}, next);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
], callback);
|
], () => {
|
||||||
|
cb();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
buildContracts(importsList, cb) {
|
writeJSONFile(params) {
|
||||||
const self = this;
|
const self = this;
|
||||||
|
const dir = dappPath(...params.path);
|
||||||
|
const filename = dappPath(...params.path, params.file);
|
||||||
|
const content = params.content;
|
||||||
|
|
||||||
async.waterfall([
|
async.waterfall([
|
||||||
function makeDirectory(next) {
|
function makeDirectory(next) {
|
||||||
self.fs.mkdirp(dappPath(self.buildDir, 'contracts'), err => next(err));
|
self.fs.mkdirp(dir, err => next(err));
|
||||||
},
|
},
|
||||||
function getContracts(next) {
|
function writeContractsJSON(next) {
|
||||||
self.events.request('contracts:list', next);
|
self.fs.writeJson(filename, content, { spaces: 2 }, () => { next() });
|
||||||
},
|
|
||||||
function writeContractsJSON(contracts, next) {
|
|
||||||
async.each(contracts, (contract, eachCb) => {
|
|
||||||
self.fs.writeJson(dappPath(
|
|
||||||
self.buildDir,
|
|
||||||
'contracts', contract.className + '.json'
|
|
||||||
), contract, {spaces: 2}, eachCb);
|
|
||||||
}, () => next(null, contracts));
|
|
||||||
},
|
|
||||||
function writeContractJS(contracts, next) {
|
|
||||||
const contractsDir = dappPath(self.embarkConfig.generationDir, constants.dappArtifacts.contractsJs);
|
|
||||||
self.fs.mkdirp(contractsDir, err => {
|
|
||||||
if (err) return next(err);
|
|
||||||
|
|
||||||
// Create a file index.js that requires all contract files
|
|
||||||
// Used to enable alternate import syntax:
|
|
||||||
// e.g. import {Token} from 'Embark/contracts'
|
|
||||||
// e.g. import * as Contracts from 'Embark/contracts'
|
|
||||||
let importsHelperFile = self.fs.createWriteStream(joinPath(contractsDir, 'index.js'));
|
|
||||||
importsHelperFile.write('module.exports = {\n');
|
|
||||||
|
|
||||||
async.eachOf(contracts, (contract, idx, eachCb) => {
|
|
||||||
self.events.request('code-generator:contract', contract.className, (err, contractPath) => {
|
|
||||||
if (err) {
|
|
||||||
return eachCb(err);
|
|
||||||
}
|
|
||||||
importsList["Embark/contracts/" + contract.className] = dappPath(contractPath);
|
|
||||||
|
|
||||||
// add the contract to the exports list to support alternate import syntax
|
|
||||||
importsHelperFile.write(`"${contract.className}": require('./${contract.className}').default,\n`);
|
|
||||||
eachCb();
|
|
||||||
});
|
|
||||||
}, () => {
|
|
||||||
importsHelperFile.write('\n};'); // close the module.exports = {}
|
|
||||||
importsHelperFile.close(next); // close the write stream
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
], cb);
|
], () => {
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
runPlugins(file, fileContent, fileCb) {
|
// TODO: can be refactored by joining with method above
|
||||||
|
writeFile(params) {
|
||||||
const self = this;
|
const self = this;
|
||||||
if (self.pipelinePlugins.length <= 0) {
|
const dir = dappPath(...params.path);
|
||||||
return fileCb(null, {content: fileContent, path: file.path, basedir: file.basedir, modified: true});
|
const filename = dappPath(...params.path, params.file);
|
||||||
}
|
const content = params.content;
|
||||||
async.eachSeries(self.pipelinePlugins, (plugin, pluginCB) => {
|
|
||||||
if (file.options && file.options.skipPipeline) {
|
|
||||||
return pluginCB();
|
|
||||||
}
|
|
||||||
|
|
||||||
fileContent = plugin.runPipeline({targetFile: file.path, source: fileContent});
|
async.waterfall([
|
||||||
file.modified = true;
|
function makeDirectory(next) {
|
||||||
pluginCB();
|
self.fs.mkdirp(dir, err => next(err));
|
||||||
}, err => {
|
},
|
||||||
if (err) {
|
function writeFile(next) {
|
||||||
self.logger.error(err.message);
|
self.fs.writeFile(filename, content, (err) => { next(err, true) });
|
||||||
}
|
}
|
||||||
return fileCb(null, {content: fileContent, path: file.path, basedir: file.basedir, modified: true});
|
], () => {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
const {escapeHtml, LogHandler} = require('embark-utils');
|
const {escapeHtml, LogHandler} = require('embark-utils');
|
||||||
|
|
||||||
|
// TODO: looks unnecessary, should be moved to a common module together with embark-listener
|
||||||
|
|
||||||
class ProcessLogsApi {
|
class ProcessLogsApi {
|
||||||
constructor({embark, processName, silent}) {
|
constructor({embark, processName, silent}) {
|
||||||
this.embark = embark;
|
this.embark = embark;
|
||||||
|
@ -14,11 +14,11 @@ class SpecialConfigs {
|
|||||||
this.embark = embark;
|
this.embark = embark;
|
||||||
this.config = embark.config;
|
this.config = embark.config;
|
||||||
|
|
||||||
this.registerBeforeAllDeployAction();
|
// this.registerBeforeAllDeployAction();
|
||||||
this.registerAfterDeployAction();
|
// this.registerAfterDeployAction();
|
||||||
this.registerBeforeDeployAction();
|
// this.registerBeforeDeployAction();
|
||||||
this.registerOnDeployAction();
|
// this.registerOnDeployAction();
|
||||||
this.registerDeployIfAction();
|
// this.registerDeployIfAction();
|
||||||
}
|
}
|
||||||
|
|
||||||
replaceWithENSAddress(cmd, callback) {
|
replaceWithENSAddress(cmd, callback) {
|
||||||
|
@ -69,9 +69,10 @@ class SolcTest extends Test {
|
|||||||
async.series(fns, next);
|
async.series(fns, next);
|
||||||
},
|
},
|
||||||
function resetEmbarkJs(file, next) {
|
function resetEmbarkJs(file, next) {
|
||||||
self.events.request("runcode:embarkjs:reset", (err) => {
|
// self.events.request("runcode:embarkjs:reset", (err) => {
|
||||||
next(err, file);
|
// next(err, file);
|
||||||
});
|
// });
|
||||||
|
next(err, file);
|
||||||
}
|
}
|
||||||
], cb);
|
], cb);
|
||||||
}
|
}
|
||||||
|
@ -169,9 +169,8 @@ class Test {
|
|||||||
}
|
}
|
||||||
this.firstRunConfig = false;
|
this.firstRunConfig = false;
|
||||||
this.events.request("blockchain:ready", () => {
|
this.events.request("blockchain:ready", () => {
|
||||||
this.events.request("code-generator:embarkjs:build", () => {
|
// this.events.request("runcode:embarkjs:reset", callback);
|
||||||
this.events.request("runcode:embarkjs:reset", callback);
|
callback();
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,7 @@ class Watcher {
|
|||||||
this.events.setCommandHandler('watcher:restart', () => this.restart());
|
this.events.setCommandHandler('watcher:restart', () => this.restart());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: it needs to be more agnostic, the files to watch should be registered through the plugin api
|
||||||
start() {
|
start() {
|
||||||
let self = this;
|
let self = this;
|
||||||
// TODO: should come from the config object instead of reading the file
|
// TODO: should come from the config object instead of reading the file
|
||||||
|
@ -20,21 +20,28 @@ class EmbarkWeb3 {
|
|||||||
async addWeb3ToEmbarkJS() {
|
async addWeb3ToEmbarkJS() {
|
||||||
let blockchainConnectorReady = false;
|
let blockchainConnectorReady = false;
|
||||||
|
|
||||||
const web3LocationPromise = this.getWeb3Location();
|
code += "\nEmbarkJS.Blockchain.registerProvider('web3', embarkJSConnectorWeb3);";
|
||||||
|
// code += "\nEmbarkJS.Blockchain.setProvider('web3', {});";
|
||||||
|
|
||||||
this.events.setCommandHandler('blockchain:connector:ready', (cb) => {
|
code += "\nEmbarkJS.Blockchain.setProvider('web3', {web3});";
|
||||||
if (blockchainConnectorReady) {
|
|
||||||
return cb();
|
this.events.request('runcode:eval', code, (err) => {
|
||||||
|
if (err) {
|
||||||
|
return cb(err);
|
||||||
}
|
}
|
||||||
this.events.once("blockchain:connector:ready", () => {
|
|
||||||
cb();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
web3LocationPromise.then((_web3Location) => {
|
registerWeb3Help() {
|
||||||
blockchainConnectorReady = true;
|
this.events.request('console:register:helpCmd', {
|
||||||
this.events.emit('blockchain:connector:ready');
|
cmdName: "web3",
|
||||||
});
|
cmdHelp: __("instantiated web3.js object configured to the current environment")
|
||||||
|
}, () => { })
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===============
|
||||||
|
// ===============
|
||||||
|
// ===============
|
||||||
|
|
||||||
let web3Location = await web3LocationPromise;
|
let web3Location = await web3LocationPromise;
|
||||||
web3Location = normalizePath(web3Location, true);
|
web3Location = normalizePath(web3Location, true);
|
||||||
|
88
packages/embark-whisper/src/api.js
Normal file
88
packages/embark-whisper/src/api.js
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
const {parallel} = require('async');
|
||||||
|
const {fromEvent} = require('rxjs');
|
||||||
|
const {map, takeUntil} = require('rxjs/operators');
|
||||||
|
|
||||||
|
import whisper from 'embarkjs-whisper';
|
||||||
|
|
||||||
|
const sendMessage = whisper.real_sendMessage;
|
||||||
|
const listenTo = whisper.real_listenTo;
|
||||||
|
|
||||||
|
class API {
|
||||||
|
|
||||||
|
constructor(embark, web3) {
|
||||||
|
this.embark = embark;
|
||||||
|
this.logger = embark.logger;
|
||||||
|
this.web3 = web3;
|
||||||
|
this.registerAPICalls();
|
||||||
|
}
|
||||||
|
|
||||||
|
registerAPICalls() {
|
||||||
|
const self = this;
|
||||||
|
if (self.apiCallsRegistered) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
self.apiCallsRegistered = true;
|
||||||
|
let symKeyID, sig;
|
||||||
|
parallel([
|
||||||
|
function(paraCb) {
|
||||||
|
self.web3.shh.newSymKey((err, id) => {
|
||||||
|
symKeyID = id;
|
||||||
|
paraCb(err);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
function(paraCb) {
|
||||||
|
self.web3.shh.newKeyPair((err, id) => {
|
||||||
|
sig = id;
|
||||||
|
paraCb(err);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
], (err) => {
|
||||||
|
if (err) {
|
||||||
|
self.logger.error('Error getting Whisper keys:', err.message || err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
self.embark.registerAPICall(
|
||||||
|
'post',
|
||||||
|
'/embark-api/communication/sendMessage',
|
||||||
|
(req, res) => {
|
||||||
|
sendMessage({
|
||||||
|
topic: req.body.topic,
|
||||||
|
data: req.body.message,
|
||||||
|
sig,
|
||||||
|
symKeyID,
|
||||||
|
fromAscii: self.web3.utils.asciiToHex,
|
||||||
|
toHex: self.web3.utils.toHex,
|
||||||
|
post: self.web3.shh.post
|
||||||
|
}, (err, result) => {
|
||||||
|
if (err) {
|
||||||
|
return res.status(500).send({error: err});
|
||||||
|
}
|
||||||
|
res.send(result);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
self.embark.registerAPICall(
|
||||||
|
'ws',
|
||||||
|
'/embark-api/communication/listenTo/:topic',
|
||||||
|
(ws, req) => {
|
||||||
|
const obs = listenTo({
|
||||||
|
toAscii: self.web3.utils.hexToAscii,
|
||||||
|
toHex: self.web3.utils.toHex,
|
||||||
|
topic: req.params.topic,
|
||||||
|
sig,
|
||||||
|
subscribe: self.web3.shh.subscribe,
|
||||||
|
symKeyID
|
||||||
|
}).pipe(takeUntil(fromEvent(ws, 'close').pipe(map(() => (
|
||||||
|
delete self.webSocketsChannels[req.params.topic]
|
||||||
|
)))));
|
||||||
|
self.webSocketsChannels[req.params.topic] = obs;
|
||||||
|
obs.subscribe(data => {
|
||||||
|
ws.send(JSON.stringify(data));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = API;
|
@ -1,21 +1,12 @@
|
|||||||
/* global __dirname module require setTimeout */
|
|
||||||
|
|
||||||
import { __ } from 'embark-i18n';
|
import { __ } from 'embark-i18n';
|
||||||
import {dappPath, canonicalHost, defaultHost} from 'embark-utils';
|
import {dappPath, canonicalHost, defaultHost} from 'embark-utils';
|
||||||
let Web3 = require('web3');
|
let Web3 = require('web3');
|
||||||
const {parallel} = require('async');
|
|
||||||
const {fromEvent} = require('rxjs');
|
|
||||||
const {map, takeUntil} = require('rxjs/operators');
|
|
||||||
const constants = require('embark-core/constants');
|
const constants = require('embark-core/constants');
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
|
const API = require('./api.js');
|
||||||
|
|
||||||
const EMBARK_RESOURCE_ORIGIN = "http://embark";
|
const EMBARK_RESOURCE_ORIGIN = "http://embark";
|
||||||
|
|
||||||
import whisper from 'embarkjs-whisper';
|
|
||||||
|
|
||||||
const sendMessage = whisper.real_sendMessage;
|
|
||||||
const listenTo = whisper.real_listenTo;
|
|
||||||
|
|
||||||
class Whisper {
|
class Whisper {
|
||||||
constructor(embark, options) {
|
constructor(embark, options) {
|
||||||
this.logger = embark.logger;
|
this.logger = embark.logger;
|
||||||
@ -37,31 +28,49 @@ class Whisper {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.connectToProvider();
|
this.api = new API(embark, this.web3);
|
||||||
|
this.api.registerAPICalls();
|
||||||
|
|
||||||
this.events.request('processes:register', 'whisper', (cb) => {
|
// ================
|
||||||
this.waitForWeb3Ready(() => {
|
// TODO:
|
||||||
this.web3.shh.getInfo((err) => {
|
// figure out best way to detect is a node exists or launch a whisper process or wait for the blockchain process
|
||||||
if (err) {
|
// ================
|
||||||
const message = err.message || err;
|
// this.events.on("blockchain:ready", this.executeEmbarkJSBlockchain.bind(this));
|
||||||
if (message.indexOf('not supported') > -1) {
|
|
||||||
this.logger.error('Whisper is not supported on your node. Are you using the simulator?');
|
this.setServiceCheck();
|
||||||
return this.logger.trace(message);
|
|
||||||
}
|
// TODO: see above, not ideal to do this, need engine.start process
|
||||||
}
|
// can also register service and instead react to it and connect
|
||||||
this.setServiceCheck();
|
// this.waitForWeb3Ready(() => {
|
||||||
this.addSetProvider();
|
// this.registerAndSetWhisper();
|
||||||
this.registerAPICalls();
|
// });
|
||||||
cb();
|
this.events.on("blockchain:ready", () => {
|
||||||
});
|
this.registerAndSetWhisper();
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// TODO: it will have the issue of waiting for the ipfs to start when the code is generator
|
// ===============================
|
||||||
// TODO: could be solved by having a list of services to wait on before attempting to execute code in the console
|
// this.connectToProvider();
|
||||||
this.addWhisperToEmbarkJS();
|
|
||||||
|
|
||||||
this.events.request('processes:launch', 'whisper');
|
// this.events.request('processes:register', 'whisper', (cb) => {
|
||||||
|
// this.waitForWeb3Ready(() => {
|
||||||
|
// this.web3.shh.getInfo((err) => {
|
||||||
|
// if (err) {
|
||||||
|
// const message = err.message || err;
|
||||||
|
// if (message.indexOf('not supported') > -1) {
|
||||||
|
// this.logger.error('Whisper is not supported on your node. Are you using the simulator?');
|
||||||
|
// return this.logger.trace(message);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// this.setServiceCheck();
|
||||||
|
// this.addWhisperToEmbarkJS();
|
||||||
|
// this.addSetProvider();
|
||||||
|
// this.registerAPICalls();
|
||||||
|
// cb();
|
||||||
|
// });
|
||||||
|
// });
|
||||||
|
// });
|
||||||
|
|
||||||
|
// this.events.request('processes:launch', 'whisper');
|
||||||
}
|
}
|
||||||
|
|
||||||
connectToProvider() {
|
connectToProvider() {
|
||||||
@ -75,6 +84,57 @@ class Whisper {
|
|||||||
this.web3.setProvider(new Web3.providers.WebsocketProvider(web3Endpoint, {headers: {Origin: EMBARK_RESOURCE_ORIGIN}}));
|
this.web3.setProvider(new Web3.providers.WebsocketProvider(web3Endpoint, {headers: {Origin: EMBARK_RESOURCE_ORIGIN}}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
registerAndSetWhisper() {
|
||||||
|
if (this.communicationConfig === {}) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ((this.communicationConfig.available_providers.indexOf('whisper') < 0) && (this.communicationConfig.provider !== 'whisper' || this.communicationConfig.enabled !== true)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// let linkedModulePath = path.join(this.modulesPath, 'embarkjs-whisper');
|
||||||
|
// if (process.platform === 'win32') linkedModulePath = linkedModulePath.replace(/\\/g, '\\\\');
|
||||||
|
|
||||||
|
// const code = `
|
||||||
|
// const __embarkWhisperNewWeb3 = EmbarkJS.isNode ? require('${linkedModulePath}') : require('embarkjs-whisper');
|
||||||
|
// EmbarkJS.Messages.registerProvider('whisper', __embarkWhisperNewWeb3.default || __embarkWhisperNewWeb3);
|
||||||
|
// `;
|
||||||
|
|
||||||
|
let code = `
|
||||||
|
const __embarkWhisperNewWeb3 = require('embarkjs-whisper');
|
||||||
|
EmbarkJS.Messages.registerProvider('whisper', __embarkWhisperNewWeb3.default || __embarkWhisperNewWeb3);
|
||||||
|
`;
|
||||||
|
|
||||||
|
let connection = this.communicationConfig.connection || {};
|
||||||
|
|
||||||
|
if (!(this.communicationConfig.provider === 'whisper' && this.communicationConfig.enabled === true)) {
|
||||||
|
return this.events.request('runcode:eval', code, () => {
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// todo: make the add code a function as well
|
||||||
|
const config = {
|
||||||
|
server: canonicalHost(connection.host || defaultHost),
|
||||||
|
port: connection.port || '8546',
|
||||||
|
type: connection.type || 'ws'
|
||||||
|
};
|
||||||
|
code += `\nEmbarkJS.Messages.setProvider('whisper', ${JSON.stringify(config)});`;
|
||||||
|
|
||||||
|
// this.embark.addCodeToEmbarkJS(code);
|
||||||
|
this.events.request('runcode:eval', code, (err) => {
|
||||||
|
// if (err) {
|
||||||
|
// return cb(err);
|
||||||
|
// }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===============================
|
||||||
|
// ===============================
|
||||||
|
// ===============================
|
||||||
|
// ===============================
|
||||||
|
// ===============================
|
||||||
|
// ===============================
|
||||||
|
|
||||||
waitForWeb3Ready(cb) {
|
waitForWeb3Ready(cb) {
|
||||||
if (this.web3Ready) {
|
if (this.web3Ready) {
|
||||||
return cb();
|
return cb();
|
||||||
@ -119,37 +179,6 @@ class Whisper {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
addWhisperToEmbarkJS() {
|
|
||||||
// TODO: make this a shouldAdd condition
|
|
||||||
if (this.communicationConfig === {}) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if ((this.communicationConfig.available_providers.indexOf('whisper') < 0) && (this.communicationConfig.provider !== 'whisper' || this.communicationConfig.enabled !== true)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let linkedModulePath = path.join(this.modulesPath, 'embarkjs-whisper');
|
|
||||||
if (process.platform === 'win32') linkedModulePath = linkedModulePath.replace(/\\/g, '\\\\');
|
|
||||||
|
|
||||||
this.events.request('version:downloadIfNeeded', 'embarkjs-whisper', (err, location) => {
|
|
||||||
if (err) {
|
|
||||||
this.logger.error(__('Error downloading embarkjs-whisper'));
|
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
|
|
||||||
const code = `
|
|
||||||
const __embarkWhisperNewWeb3 = require('${linkedModulePath}');
|
|
||||||
EmbarkJS.Messages.registerProvider('whisper', __embarkWhisperNewWeb3.default || __embarkWhisperNewWeb3);
|
|
||||||
`;
|
|
||||||
|
|
||||||
this.embark.addProviderInit("communication", code, () => { return true; });
|
|
||||||
this.embark.addConsoleProviderInit("communication", code, () => { return true; });
|
|
||||||
this.embark.addGeneratedCode((cb) => {
|
|
||||||
return cb(null, code, `embarkjs-whisper`, location);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
addSetProvider() {
|
addSetProvider() {
|
||||||
let connection = this.communicationConfig.connection || {};
|
let connection = this.communicationConfig.connection || {};
|
||||||
const shouldInit = (communicationConfig) => {
|
const shouldInit = (communicationConfig) => {
|
||||||
@ -162,13 +191,8 @@ class Whisper {
|
|||||||
port: connection.port || '8546',
|
port: connection.port || '8546',
|
||||||
type: connection.type || 'ws'
|
type: connection.type || 'ws'
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: fix storage to also use addProviderInit
|
|
||||||
// execute code called addProviderInit WHEN contracts have been deployed etc..
|
|
||||||
// TODO: diff between addConsoleProviderInit and addProviderInit
|
|
||||||
// or maybe best way is todo everything in the module
|
|
||||||
|
|
||||||
const code = `\nEmbarkJS.Messages.setProvider('whisper', ${JSON.stringify(config)});`;
|
const code = `\nEmbarkJS.Messages.setProvider('whisper', ${JSON.stringify(config)});`;
|
||||||
|
|
||||||
this.embark.addProviderInit('communication', code, shouldInit);
|
this.embark.addProviderInit('communication', code, shouldInit);
|
||||||
|
|
||||||
const consoleConfig = Object.assign({}, config, {providerOptions: {headers: {Origin: EMBARK_RESOURCE_ORIGIN}}});
|
const consoleConfig = Object.assign({}, config, {providerOptions: {headers: {Origin: EMBARK_RESOURCE_ORIGIN}}});
|
||||||
@ -176,72 +200,6 @@ class Whisper {
|
|||||||
this.embark.addConsoleProviderInit('communication', consoleCode, shouldInit);
|
this.embark.addConsoleProviderInit('communication', consoleCode, shouldInit);
|
||||||
}
|
}
|
||||||
|
|
||||||
registerAPICalls() {
|
|
||||||
const self = this;
|
|
||||||
if (self.apiCallsRegistered) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
self.apiCallsRegistered = true;
|
|
||||||
let symKeyID, sig;
|
|
||||||
parallel([
|
|
||||||
function(paraCb) {
|
|
||||||
self.web3.shh.newSymKey((err, id) => {
|
|
||||||
symKeyID = id;
|
|
||||||
paraCb(err);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
function(paraCb) {
|
|
||||||
self.web3.shh.newKeyPair((err, id) => {
|
|
||||||
sig = id;
|
|
||||||
paraCb(err);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
], (err) => {
|
|
||||||
if (err) {
|
|
||||||
self.logger.error('Error getting Whisper keys:', err.message || err);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
self.embark.registerAPICall(
|
|
||||||
'post',
|
|
||||||
'/embark-api/communication/sendMessage',
|
|
||||||
(req, res) => {
|
|
||||||
sendMessage({
|
|
||||||
topic: req.body.topic,
|
|
||||||
data: req.body.message,
|
|
||||||
sig,
|
|
||||||
symKeyID,
|
|
||||||
fromAscii: self.web3.utils.asciiToHex,
|
|
||||||
toHex: self.web3.utils.toHex,
|
|
||||||
post: self.web3.shh.post
|
|
||||||
}, (err, result) => {
|
|
||||||
if (err) {
|
|
||||||
return res.status(500).send({error: err});
|
|
||||||
}
|
|
||||||
res.send(result);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
self.embark.registerAPICall(
|
|
||||||
'ws',
|
|
||||||
'/embark-api/communication/listenTo/:topic',
|
|
||||||
(ws, req) => {
|
|
||||||
const obs = listenTo({
|
|
||||||
toAscii: self.web3.utils.hexToAscii,
|
|
||||||
toHex: self.web3.utils.toHex,
|
|
||||||
topic: req.params.topic,
|
|
||||||
sig,
|
|
||||||
subscribe: self.web3.shh.subscribe,
|
|
||||||
symKeyID
|
|
||||||
}).pipe(takeUntil(fromEvent(ws, 'close').pipe(map(() => (
|
|
||||||
delete self.webSocketsChannels[req.params.topic]
|
|
||||||
)))));
|
|
||||||
self.webSocketsChannels[req.params.topic] = obs;
|
|
||||||
obs.subscribe(data => {
|
|
||||||
ws.send(JSON.stringify(data));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = Whisper;
|
module.exports = Whisper;
|
||||||
|
@ -10,8 +10,8 @@ module.exports = (api) => {
|
|||||||
const node = cloneDeep(base);
|
const node = cloneDeep(base);
|
||||||
Object.assign(node, {
|
Object.assign(node, {
|
||||||
ignore: [
|
ignore: [
|
||||||
'src/lib/modules/pipeline/babel-loader-overrides.js',
|
'src/lib/modules/basic-pipeline/babel-loader-overrides.js',
|
||||||
'src/lib/modules/pipeline/webpack.config.js'
|
'src/lib/modules/basic-pipeline/webpack.config.js'
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
@ -135,17 +135,27 @@ class Engine {
|
|||||||
|
|
||||||
pipelineService(_options) {
|
pipelineService(_options) {
|
||||||
const self = this;
|
const self = this;
|
||||||
this.registerModulePackage('embark-pipeline', {
|
this.registerModulePackage('embark-pipeline', { plugins: this.plugins });
|
||||||
|
this.registerModule('basic-pipeline', {
|
||||||
|
plugins: this.plugins,
|
||||||
webpackConfigName: this.webpackConfigName,
|
webpackConfigName: this.webpackConfigName,
|
||||||
useDashboard: this.useDashboard
|
useDashboard: this.useDashboard
|
||||||
});
|
});
|
||||||
this.events.on('code-generator-ready', function (modifiedAssets) {
|
// this.events.on('code-generator-ready', function (modifiedAssets) {
|
||||||
self.events.request('code', function (abi, contractsJSON) {
|
// self.events.request('code', function (abi, contractsJSON) {
|
||||||
self.events.request('pipeline:build', {abi, contractsJSON, modifiedAssets}, () => {
|
// self.events.request('pipeline:build', {abi, contractsJSON, modifiedAssets}, () => {
|
||||||
self.events.emit('outputDone');
|
// self.events.emit('outputDone');
|
||||||
});
|
// });
|
||||||
|
// });
|
||||||
|
// });
|
||||||
|
|
||||||
|
// TODO: move this to cmd_controller and define all such behaviour there
|
||||||
|
this.events.on('contracts:deploy:afterAll', () => {
|
||||||
|
self.events.request('pipeline:generateAll', () => {
|
||||||
|
console.dir("outputDone")
|
||||||
|
self.events.emit('outputDone');
|
||||||
});
|
});
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
serviceMonitor() {
|
serviceMonitor() {
|
||||||
@ -180,32 +190,30 @@ class Engine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
codeGeneratorService(_options) {
|
codeGeneratorService(_options) {
|
||||||
let self = this;
|
return;
|
||||||
|
// let self = this;
|
||||||
this.registerModulePackage('embark-code-generator', {plugins: self.plugins, env: self.env});
|
//
|
||||||
|
// this.registerModulePackage('embark-code-generator', {plugins: self.plugins, env: self.env});
|
||||||
const generateCode = function (modifiedAssets, cb) {
|
//
|
||||||
self.events.request("code-generator:embarkjs:build", () => {
|
// const generateCode = function (modifiedAssets) {
|
||||||
self.events.emit('code-generator-ready', modifiedAssets);
|
// // self.events.request("module:storage:onReady", () => {
|
||||||
cb();
|
// self.events.request("code-generator:embarkjs:build", () => {
|
||||||
});
|
// self.events.emit('code-generator-ready', modifiedAssets);
|
||||||
};
|
// });
|
||||||
const cargo = async.cargo((tasks, callback) => {
|
// // });
|
||||||
const modifiedAssets = tasks.map(task => task.modifiedAsset).filter(asset => asset); // filter null elements
|
// };
|
||||||
generateCode(modifiedAssets, () => {
|
// const cargo = async.cargo((tasks, callback) => {
|
||||||
if (this.context.includes('test')) {
|
// const modifiedAssets = tasks.map(task => task.modifiedAsset).filter(asset => asset); // filter null elements
|
||||||
return callback();
|
// generateCode(modifiedAssets);
|
||||||
}
|
// self.events.once('outputDone', callback);
|
||||||
self.events.once('outputDone', callback);
|
// });
|
||||||
});
|
// const addToCargo = function (modifiedAsset) {
|
||||||
});
|
// cargo.push({modifiedAsset});
|
||||||
const addToCargo = function (modifiedAsset) {
|
// };
|
||||||
cargo.push({modifiedAsset});
|
//
|
||||||
};
|
// this.events.on('contractsDeployed', addToCargo);
|
||||||
|
// this.events.on('blockchainDisabled', addToCargo);
|
||||||
this.events.on('contractsDeployed', addToCargo);
|
// this.events.on('asset-changed', addToCargo);
|
||||||
this.events.on('blockchainDisabled', addToCargo);
|
|
||||||
this.events.on('asset-changed', addToCargo);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
setupCompilerAndContractsManagerService(options) {
|
setupCompilerAndContractsManagerService(options) {
|
||||||
@ -269,23 +277,23 @@ class Engine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
storageService(_options) {
|
storageService(_options) {
|
||||||
this.registerModulePackage('embark-ipfs');
|
// this.registerModulePackage('embark-ipfs');
|
||||||
this.registerModulePackage('embark-swarm');
|
// this.registerModulePackage('embark-swarm');
|
||||||
this.registerModulePackage('embark-storage', {plugins: this.plugins});
|
// this.registerModulePackage('embark-storage', {plugins: this.plugins});
|
||||||
|
|
||||||
this.events.setCommandHandler("module:storage:reset", (cb) => {
|
// this.events.setCommandHandler("module:storage:reset", (cb) => {
|
||||||
async.parallel([
|
// async.parallel([
|
||||||
(paraCb) => {
|
// (paraCb) => {
|
||||||
this.events.request("module:ipfs:reset", paraCb);
|
// this.events.request("module:ipfs:reset", paraCb);
|
||||||
},
|
// },
|
||||||
(paraCb) => {
|
// (paraCb) => {
|
||||||
this.events.request("module:swarm:reset", paraCb);
|
// this.events.request("module:swarm:reset", paraCb);
|
||||||
},
|
// },
|
||||||
(paraCb) => {
|
// (paraCb) => {
|
||||||
this.events.request("module:storageJS:reset", paraCb);
|
// this.events.request("module:storageJS:reset", paraCb);
|
||||||
}
|
// }
|
||||||
], cb);
|
// ], cb);
|
||||||
});
|
// });
|
||||||
}
|
}
|
||||||
|
|
||||||
web3Service(options) {
|
web3Service(options) {
|
||||||
@ -307,6 +315,7 @@ class Engine {
|
|||||||
});
|
});
|
||||||
|
|
||||||
this.registerModulePackage('embark-whisper');
|
this.registerModulePackage('embark-whisper');
|
||||||
|
this.registerModule('web3', { plugins: this.plugins });
|
||||||
}
|
}
|
||||||
|
|
||||||
libraryManagerService(_options) {
|
libraryManagerService(_options) {
|
||||||
|
@ -55,8 +55,13 @@ EventEmitter.prototype.request = function() {
|
|||||||
|
|
||||||
log("requesting: ", requestName);
|
log("requesting: ", requestName);
|
||||||
warnIfLegacy(requestName);
|
warnIfLegacy(requestName);
|
||||||
|
if (this._events && !this._events['request:' + requestName]) {
|
||||||
|
console.log("made request without listener: " + requestName)
|
||||||
|
}
|
||||||
const listenerName = 'request:' + requestName;
|
const listenerName = 'request:' + requestName;
|
||||||
|
|
||||||
|
// TODO: remove this, it will lead to illusion of things working when this situatio shouldnt' hapepn in the first place
|
||||||
|
|
||||||
// if we don't have a command handler set for this event yet,
|
// if we don't have a command handler set for this event yet,
|
||||||
// store it and fire it once a command handler is set
|
// store it and fire it once a command handler is set
|
||||||
if (!this.listeners(listenerName).length) {
|
if (!this.listeners(listenerName).length) {
|
||||||
|
@ -161,6 +161,7 @@ Plugins.prototype.getPluginsProperty = function(pluginType, property, sub_proper
|
|||||||
return matchingProperties.reduce((a,b) => { return a.concat(b); }) || [];
|
return matchingProperties.reduce((a,b) => { return a.concat(b); }) || [];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// TODO: because this is potentially hanging, we should issue a trace warning if the event does not exists
|
||||||
Plugins.prototype.runActionsForEvent = function(eventName, args, cb) {
|
Plugins.prototype.runActionsForEvent = function(eventName, args, cb) {
|
||||||
if (typeof (args) === 'function') {
|
if (typeof (args) === 'function') {
|
||||||
cb = args;
|
cb = args;
|
||||||
|
257
packages/embark/src/lib/modules/basic-pipeline/index.js
Normal file
257
packages/embark/src/lib/modules/basic-pipeline/index.js
Normal file
@ -0,0 +1,257 @@
|
|||||||
|
const async = require('async');
|
||||||
|
import { __ } from 'embark-i18n';
|
||||||
|
import { ProcessLauncher } from 'embark-core';
|
||||||
|
import { dappPath, joinPath, LongRunningProcessTimer } from 'embark-utils';
|
||||||
|
const constants = require('embark-core/constants');
|
||||||
|
const WebpackConfigReader = require('./webpackConfigReader');
|
||||||
|
|
||||||
|
class BasicPipeline {
|
||||||
|
|
||||||
|
constructor(embark, options) {
|
||||||
|
this.embark = embark;
|
||||||
|
this.assetFiles = embark.config.assetFiles;
|
||||||
|
this.isFirstBuild = true;
|
||||||
|
this.embarkConfig = embark.config.embarkConfig;
|
||||||
|
// TODO: why god why
|
||||||
|
this.useDashboard = options.useDashboard;
|
||||||
|
this.fs = embark.fs;
|
||||||
|
this.webpackConfigName = options.webpackConfigName;
|
||||||
|
this.env = embark.config.env;
|
||||||
|
this.buildDir = embark.config.buildDir;
|
||||||
|
this.contractsFiles = embark.config.contractsFiles;
|
||||||
|
this.embarkConfig = embark.config.embarkConfig;
|
||||||
|
|
||||||
|
this.logger = embark.logger;
|
||||||
|
this.events = embark.events;
|
||||||
|
this.plugins = options.plugins;
|
||||||
|
this.pipelinePlugins = this.plugins.getPluginsFor('pipeline');
|
||||||
|
this.pipelineConfig = embark.config.pipelineConfig;
|
||||||
|
let plugin = this.plugins.createPlugin('basic-pipeline', {});
|
||||||
|
|
||||||
|
plugin.registerActionForEvent("pipeline:generateAll:after", this.webpackAssets.bind(this));
|
||||||
|
|
||||||
|
// track changes to the pipeline config in the filesystem
|
||||||
|
this.events.on('config:load:pipeline', (pipelineConfig) => {
|
||||||
|
this.pipelineConfig = pipelineConfig;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
webpackAssets(params, done) {
|
||||||
|
console.dir("=======================> webpackAssets");
|
||||||
|
let self = this;
|
||||||
|
let placeholderPage;
|
||||||
|
const importsList = {};
|
||||||
|
|
||||||
|
if (!self.assetFiles || !Object.keys(self.assetFiles).length) {
|
||||||
|
return done(); // no assetFiles so nothing to do
|
||||||
|
}
|
||||||
|
|
||||||
|
let modifiedAssets = self.assetFiles;
|
||||||
|
|
||||||
|
async.waterfall([
|
||||||
|
(next) => {
|
||||||
|
console.dir("=======================> importsList");
|
||||||
|
importsList["Embark/EmbarkJS"] = dappPath(self.embarkConfig.generationDir, 'embarkjs.js');
|
||||||
|
importsList["Embark/contracts"] = this.embarkConfig.generationDir;
|
||||||
|
next();
|
||||||
|
},
|
||||||
|
function shouldRunWebpack(next) {
|
||||||
|
console.dir("=======================> shouldRunWebpack");
|
||||||
|
// assuming we got here because an asset was changed, let's check our webpack config
|
||||||
|
// to see if the changed asset requires webpack to run
|
||||||
|
if (!(modifiedAssets && modifiedAssets.length)) return next(null, false);
|
||||||
|
const configReader = new WebpackConfigReader({webpackConfigName: self.webpackConfigName});
|
||||||
|
return configReader.readConfig((err, config) => {
|
||||||
|
if (err) return next(err);
|
||||||
|
|
||||||
|
if (typeof config !== 'object' || config === null) {
|
||||||
|
return next(__('Pipeline: bad webpack config, the resolved config was null or not an object'));
|
||||||
|
}
|
||||||
|
|
||||||
|
const shouldRun = modifiedAssets.some(modifiedAsset => config.module.rules.some(rule => rule.test.test(modifiedAsset)));
|
||||||
|
return next(null, !shouldRun);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
function runWebpack(shouldNotRun, next) {
|
||||||
|
console.dir("=======================> runWebpack");
|
||||||
|
if (shouldNotRun) return next();
|
||||||
|
const assets = Object.keys(self.assetFiles).filter(key => key.match(/\.js$/));
|
||||||
|
if (!assets || !assets.length) {
|
||||||
|
return next();
|
||||||
|
}
|
||||||
|
let strAssets = '';
|
||||||
|
if (!self.useDashboard) {
|
||||||
|
assets.forEach(key => {
|
||||||
|
strAssets += ('\n ' + (joinPath(self.buildDir, key)).bold.dim);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
const timer = new LongRunningProcessTimer(
|
||||||
|
self.logger,
|
||||||
|
'webpack',
|
||||||
|
'0',
|
||||||
|
`${'Pipeline:'.cyan} Bundling dapp using '${self.webpackConfigName}' config...${strAssets}`,
|
||||||
|
`${'Pipeline:'.cyan} Still bundling dapp using '${self.webpackConfigName}' config... ({{duration}})${strAssets}`,
|
||||||
|
`${'Pipeline:'.cyan} Finished bundling dapp in {{duration}}${strAssets}`,
|
||||||
|
{
|
||||||
|
showSpinner: !self.useDashboard,
|
||||||
|
interval: self.useDashboard ? 5000 : 1000,
|
||||||
|
longRunningThreshold: 15000
|
||||||
|
}
|
||||||
|
);
|
||||||
|
timer.start();
|
||||||
|
let built = false;
|
||||||
|
const webpackProcess = new ProcessLauncher({
|
||||||
|
embark: self.embark,
|
||||||
|
plugins: self.plugins,
|
||||||
|
modulePath: joinPath(__dirname, 'webpackProcess.js'),
|
||||||
|
logger: self.logger,
|
||||||
|
events: self.events,
|
||||||
|
exitCallback: code => {
|
||||||
|
if (!built) {
|
||||||
|
return next(`Webpack build exited with code ${code} before the process finished`);
|
||||||
|
}
|
||||||
|
if (code) {
|
||||||
|
self.logger.error(__('Webpack build process exited with code ', code));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
webpackProcess.send({
|
||||||
|
action: constants.pipeline.init,
|
||||||
|
options: {
|
||||||
|
webpackConfigName: self.webpackConfigName,
|
||||||
|
pipelineConfig: self.pipelineConfig,
|
||||||
|
fs: self.embark.fs
|
||||||
|
}
|
||||||
|
});
|
||||||
|
webpackProcess.send({action: constants.pipeline.build, assets: self.assetFiles, importsList});
|
||||||
|
|
||||||
|
webpackProcess.once('result', constants.pipeline.built, (msg) => {
|
||||||
|
built = true;
|
||||||
|
webpackProcess.kill();
|
||||||
|
return next(msg.error);
|
||||||
|
});
|
||||||
|
webpackProcess.once('result', constants.pipeline.webpackDone, () => {
|
||||||
|
timer.end();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
function assetFileWrite(next) {
|
||||||
|
console.dir("=======================> assetFileWrite 136");
|
||||||
|
async.eachOf(
|
||||||
|
// assetFileWrite should not process .js files
|
||||||
|
Object.keys(self.assetFiles)
|
||||||
|
.filter(key => !key.match(/\.js$/))
|
||||||
|
.reduce((obj, key) => {
|
||||||
|
obj[key] = self.assetFiles[key];
|
||||||
|
return obj;
|
||||||
|
}, {}),
|
||||||
|
function (files, targetFile, cb) {
|
||||||
|
console.dir("== eachOf: " + targetFile);
|
||||||
|
const isDir = targetFile.slice(-1) === '/' || targetFile.slice(-1) === '\\' || targetFile.indexOf('.') === -1;
|
||||||
|
// if it's not a directory
|
||||||
|
if (!isDir) {
|
||||||
|
self.logger.info('Pipeline: '.cyan + __("_1_ writing file") + " " + (joinPath(self.buildDir, targetFile)).bold.dim);
|
||||||
|
}
|
||||||
|
console.dir("async.map")
|
||||||
|
// async.map(
|
||||||
|
async.mapLimit(
|
||||||
|
files,
|
||||||
|
1,
|
||||||
|
function (file, fileCb) {
|
||||||
|
self.logger.trace("reading " + file.path);
|
||||||
|
console.dir(":::::::: reading " + file.path);
|
||||||
|
file.content.then((fileContent) => {
|
||||||
|
self.runPlugins(file, fileContent, fileCb);
|
||||||
|
}).catch(fileCb);
|
||||||
|
},
|
||||||
|
function (err, contentFiles) {
|
||||||
|
try {
|
||||||
|
if (err) {
|
||||||
|
self.logger.error('Pipeline: '.cyan + __('errors found while generating') + ' ' + targetFile);
|
||||||
|
console.dir(err);
|
||||||
|
}
|
||||||
|
let dir = targetFile.split('/').slice(0, -1).join('/');
|
||||||
|
self.logger.trace(`${'Pipeline:'.cyan} creating dir ` + joinPath(self.buildDir, dir));
|
||||||
|
self.fs.mkdirpSync(joinPath(self.buildDir, dir));
|
||||||
|
|
||||||
|
// if it's a directory
|
||||||
|
if (isDir) {
|
||||||
|
console.dir("---> isDir")
|
||||||
|
let targetDir = targetFile;
|
||||||
|
|
||||||
|
if (targetDir.slice(-1) !== '/') {
|
||||||
|
targetDir = targetDir + '/';
|
||||||
|
}
|
||||||
|
|
||||||
|
console.dir("===> contentFiles")
|
||||||
|
console.dir(contentFiles)
|
||||||
|
console.dir("----------")
|
||||||
|
async.each(contentFiles, function (file, eachCb) {
|
||||||
|
let filename = file.path.replace(file.basedir + '/', '');
|
||||||
|
self.logger.info(`${'Pipeline:'.cyan} __ writing file ` + (joinPath(self.buildDir, targetDir, filename)).bold.dim);
|
||||||
|
|
||||||
|
self.fs.copy(file.path, joinPath(self.buildDir, targetDir, filename), {overwrite: true}, eachCb);
|
||||||
|
}, cb);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.dir("---> not a dir")
|
||||||
|
let content = contentFiles.map(file => {
|
||||||
|
if (file === undefined) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return file.content;
|
||||||
|
}).join("\n");
|
||||||
|
|
||||||
|
if (new RegExp(/^index.html?/i).test(targetFile)) {
|
||||||
|
targetFile = targetFile.replace('index', 'index-temp');
|
||||||
|
placeholderPage = targetFile;
|
||||||
|
}
|
||||||
|
console.dir("--> writing file")
|
||||||
|
self.fs.writeFile(joinPath(self.buildDir, targetFile), content, cb);
|
||||||
|
} catch(err) {
|
||||||
|
console.dir(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
next
|
||||||
|
);
|
||||||
|
},
|
||||||
|
function removePlaceholderPage(next) {
|
||||||
|
console.dir("=======================> removePlaceholderPage");
|
||||||
|
let placeholderFile = joinPath(self.buildDir, placeholderPage);
|
||||||
|
self.fs.access(joinPath(self.buildDir, placeholderPage), (err) => {
|
||||||
|
if (err) return next(); // index-temp doesn't exist, do nothing
|
||||||
|
|
||||||
|
// rename index-temp.htm/l to index.htm/l, effectively replacing our placeholder page
|
||||||
|
// with the contents of the built index.html page
|
||||||
|
self.fs.move(placeholderFile, placeholderFile.replace('index-temp', 'index'), {overwrite: true}, next);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
], done);
|
||||||
|
}
|
||||||
|
|
||||||
|
runPlugins(file, fileContent, fileCb) {
|
||||||
|
const self = this;
|
||||||
|
if (self.pipelinePlugins.length <= 0) {
|
||||||
|
return fileCb(null, {content: fileContent, path: file.path, basedir: file.basedir, modified: true});
|
||||||
|
}
|
||||||
|
async.eachSeries(self.pipelinePlugins, (plugin, pluginCB) => {
|
||||||
|
if (file.options && file.options.skipPipeline) {
|
||||||
|
return pluginCB();
|
||||||
|
}
|
||||||
|
|
||||||
|
fileContent = plugin.runPipeline({targetFile: file.path, source: fileContent});
|
||||||
|
file.modified = true;
|
||||||
|
pluginCB();
|
||||||
|
}, err => {
|
||||||
|
if (err) {
|
||||||
|
self.logger.error(err.message);
|
||||||
|
}
|
||||||
|
return fileCb(null, {content: fileContent, path: file.path, basedir: file.basedir, modified: true});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = BasicPipeline;
|
181
packages/embark/src/lib/modules/web3/index.js
Normal file
181
packages/embark/src/lib/modules/web3/index.js
Normal file
@ -0,0 +1,181 @@
|
|||||||
|
require('ejs');
|
||||||
|
import { embarkPath } from "embark-utils";
|
||||||
|
import { transform } from "@babel/core";
|
||||||
|
|
||||||
|
const Templates = {
|
||||||
|
vanilla_contract: require('./vanilla-contract.js.ejs')
|
||||||
|
};
|
||||||
|
|
||||||
|
// TODO: this should be moved to the embark-web3 module from master
|
||||||
|
class Web3Plugin {
|
||||||
|
|
||||||
|
constructor(embark, options) {
|
||||||
|
this.embarkConfig = embark.config.embarkConfig;
|
||||||
|
this.logger = embark.logger;
|
||||||
|
this.events = embark.events;
|
||||||
|
this.plugins = options.plugins;
|
||||||
|
let plugin = this.plugins.createPlugin('web3plugin', {});
|
||||||
|
|
||||||
|
plugin.registerActionForEvent("deploy:contract:deployed", this.registerInVm.bind(this));
|
||||||
|
plugin.registerActionForEvent("deploy:contract:deployed", this.addContractJSONToPipeline.bind(this));
|
||||||
|
plugin.registerActionForEvent("deploy:contract:deployed", this.addContractFileToPipeline.bind(this));
|
||||||
|
plugin.registerActionForEvent("pipeline:generateAll:before", this.addEmbarkJSNode.bind(this));
|
||||||
|
plugin.registerActionForEvent("pipeline:generateAll:before", this.addContractIndexToPipeline.bind(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
registerInVm(params, cb) {
|
||||||
|
let contract = params.contract;
|
||||||
|
let abi = JSON.stringify(contract.abiDefinition);
|
||||||
|
let gasLimit = 6000000;
|
||||||
|
let contractCode = Templates.vanilla_contract({ className: contract.className, abi: abi, contract: contract, gasLimit: gasLimit });
|
||||||
|
|
||||||
|
this.events.request('runcode:eval', contractCode, (err) => {
|
||||||
|
if (err) {
|
||||||
|
return cb(err);
|
||||||
|
}
|
||||||
|
this.events.request('runcode:eval', contract.className, (err, result) => {
|
||||||
|
if (err) {
|
||||||
|
return cb(err);
|
||||||
|
}
|
||||||
|
this.events.emit("runcode:register", contract.className, result, () => { cb() });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
addContractJSONToPipeline(params, cb) {
|
||||||
|
// TODO: check if this is correct json object to generate
|
||||||
|
const contract = params.contract;
|
||||||
|
|
||||||
|
this.events.request("pipeline:register", {
|
||||||
|
path: [this.embarkConfig.buildDir, 'contracts'],
|
||||||
|
file: contract.className + '.json',
|
||||||
|
format: 'json',
|
||||||
|
content: contract
|
||||||
|
}, cb);
|
||||||
|
}
|
||||||
|
|
||||||
|
addContractFileToPipeline(params, cb) {
|
||||||
|
const contract = params.contract;
|
||||||
|
const contractName = contract.className;
|
||||||
|
console.dir("--------------");
|
||||||
|
console.dir("--------------");
|
||||||
|
console.dir(contract.className);
|
||||||
|
const contractJSON = contract.abiDefinition;
|
||||||
|
|
||||||
|
const contractCode = `
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
const isNode = (typeof process !== 'undefined' && process.versions && process.versions.node);
|
||||||
|
const lib = isNode ? '../embarkjs.node' : '../embarkjs';
|
||||||
|
|
||||||
|
const EmbarkJSNode = isNode && require('../embarkjs.node');
|
||||||
|
let EmbarkJSBrowser;
|
||||||
|
try {
|
||||||
|
EmbarkJSBrowser = require('../embarkjs').default;
|
||||||
|
} catch(e) {};
|
||||||
|
|
||||||
|
const EmbarkJS = isNode ? EmbarkJSNode : EmbarkJSBrowser;
|
||||||
|
|
||||||
|
let ${contractName}JSONConfig = ${JSON.stringify(contractJSON)};
|
||||||
|
let ${contractName} = new EmbarkJS.Blockchain.Contract(${contractName}JSONConfig);
|
||||||
|
module.exports = ${contractName};
|
||||||
|
`.trim().replace(/^[\t\s]+/gm, '');
|
||||||
|
|
||||||
|
this.events.request("pipeline:register", {
|
||||||
|
path: [this.embarkConfig.generationDir, 'contracts'],
|
||||||
|
file: contract.className + '.js',
|
||||||
|
format: 'js',
|
||||||
|
content: contractCode
|
||||||
|
}, cb);
|
||||||
|
}
|
||||||
|
|
||||||
|
addContractIndexToPipeline(_params, cb) {
|
||||||
|
this.events.request("contracts:list", (err, contracts) => {
|
||||||
|
contracts.forEach(console.dir)
|
||||||
|
let imports = contracts.filter(c => c.deployedAddress || c.deploy).map((c) => {
|
||||||
|
return `"${c.className}": require('./${c.className}').default`;
|
||||||
|
}).join(",\n");
|
||||||
|
|
||||||
|
let code = 'module.exports = {\n';
|
||||||
|
code += imports;
|
||||||
|
code += '\n};';
|
||||||
|
|
||||||
|
this.events.request("pipeline:register", {
|
||||||
|
path: [this.embarkConfig.generationDir, 'contracts'],
|
||||||
|
file: 'index.js',
|
||||||
|
format: 'js',
|
||||||
|
content: code
|
||||||
|
}, cb);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: ideally shouldn't be done here
|
||||||
|
addEmbarkJSNode(_params, cb) {
|
||||||
|
let embarkjsCode = '';
|
||||||
|
|
||||||
|
// TODO: the symblink is unclear at this point, but if needed, it should be done at the pipeline through a request
|
||||||
|
// TODO: embarkjs stuff should also be in a embark-embarkjs module
|
||||||
|
// self.generateSymlink(location, 'embarkjs', (err, symlinkDest) => {
|
||||||
|
// if (err) {
|
||||||
|
// self.logger.error(__('Error creating a symlink to EmbarkJS'));
|
||||||
|
// return next(err);
|
||||||
|
// }
|
||||||
|
// embarkjsCode += `\nconst EmbarkJS = require("${symlinkDest}").default || require("${symlinkDest}");`;
|
||||||
|
embarkjsCode += `\nconst EmbarkJS = require("embarkjs").default;`;
|
||||||
|
// embarkjsCode += `\nEmbarkJS.environment = '${self.env}';`;
|
||||||
|
embarkjsCode += "\nglobal.EmbarkJS = EmbarkJS;";
|
||||||
|
// next();
|
||||||
|
// });
|
||||||
|
|
||||||
|
let code = "";
|
||||||
|
code += "\n" + embarkjsCode + "\n";
|
||||||
|
|
||||||
|
code += "\nexport default EmbarkJS;";
|
||||||
|
code += "\nif (typeof module !== 'undefined' && module.exports) {" +
|
||||||
|
"\n\tmodule.exports = EmbarkJS;" +
|
||||||
|
"\n}";
|
||||||
|
code += '\n/* eslint-enable */\n';
|
||||||
|
|
||||||
|
// TODO: should be done in async.waterfall
|
||||||
|
this.events.request("pipeline:register", {
|
||||||
|
path: [this.embarkConfig.generationDir],
|
||||||
|
file: 'embarkjs.js',
|
||||||
|
format: 'js',
|
||||||
|
content: code
|
||||||
|
});
|
||||||
|
|
||||||
|
// embark.js
|
||||||
|
// self.generateArtifact(code, constants.dappArtifacts.embarkjs, '', next);
|
||||||
|
|
||||||
|
transform(code, {
|
||||||
|
cwd: embarkPath(),
|
||||||
|
"presets": [
|
||||||
|
[
|
||||||
|
"@babel/preset-env", {
|
||||||
|
"targets": {
|
||||||
|
"node": "8.11.3"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}, (err, result) => {
|
||||||
|
if (err) {
|
||||||
|
return cb(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.events.request("pipeline:register", {
|
||||||
|
path: [this.embarkConfig.generationDir],
|
||||||
|
file: 'embarkjs.node.js',
|
||||||
|
format: 'js',
|
||||||
|
content: code
|
||||||
|
}, cb);
|
||||||
|
|
||||||
|
// self.generateArtifact(result.code, constants.dappArtifacts.embarkjsnode, '', next);
|
||||||
|
});
|
||||||
|
|
||||||
|
// embark.node.js
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = Web3Plugin;
|
@ -0,0 +1,9 @@
|
|||||||
|
<%- className %>Abi = <%- abi %>;
|
||||||
|
<%- className %> = new web3.eth.Contract(<%- className %>Abi);
|
||||||
|
<%- className %>.options.address = '<%- contract.deployedAddress %>';
|
||||||
|
<%- className %>.address = '<%- contract.deployedAddress %>';
|
||||||
|
<%- className %>.options.from = web3.eth.defaultAccount;
|
||||||
|
<% if (gasLimit != false) { %>
|
||||||
|
<%- className %>.options.gas = <%- gasLimit %>;
|
||||||
|
<%- className %>.options.gasLimit = <%- gasLimit %>;
|
||||||
|
<% } %>
|
40
packages/embarkjs-connector-web3/package.json
Normal file
40
packages/embarkjs-connector-web3/package.json
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
{
|
||||||
|
"name": "embarkjs-connector-web3",
|
||||||
|
"version": "4.1.0-beta.2",
|
||||||
|
"author": "Iuri Matias <iuri.matias@gmail.com>",
|
||||||
|
"contributors": [],
|
||||||
|
"description": "Web3.js Connector for EmbarkJS",
|
||||||
|
"homepage": "https://github.com/embark-framework/embark/tree/master/packages/embarkjs-connector-web3#readme",
|
||||||
|
"bugs": "https://github.com/embark-framework/embark/issues",
|
||||||
|
"keywords": [
|
||||||
|
"embark",
|
||||||
|
"web3",
|
||||||
|
"node",
|
||||||
|
"ethereum",
|
||||||
|
"smart-contract"
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"repository": {
|
||||||
|
"directory": "packages/embarkjs-connector-web3",
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/embark-framework/embark.git"
|
||||||
|
},
|
||||||
|
"main": "index.js",
|
||||||
|
"files": [
|
||||||
|
"embarkJSConnectorWeb3.js"
|
||||||
|
],
|
||||||
|
"scripts": {
|
||||||
|
"ci": "npm run qa",
|
||||||
|
"clean": "npm run reset",
|
||||||
|
"package": "npm pack",
|
||||||
|
"qa": "npm run package",
|
||||||
|
"reset": "npx rimraf embark-*.tgz package"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"embark-utils": "^4.1.0-beta.2",
|
||||||
|
"embark-i18n": "^4.1.0-beta.2"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"rimraf": "2.6.3"
|
||||||
|
}
|
||||||
|
}
|
@ -51,24 +51,6 @@ Blockchain.connect = function(options, callback) {
|
|||||||
return connect(options);
|
return connect(options);
|
||||||
};
|
};
|
||||||
|
|
||||||
Blockchain.connectConsole = function(doneCb) {
|
|
||||||
this.doFirst((cb) => {
|
|
||||||
this.blockchainConnector.getAccounts(async (err, accounts) => {
|
|
||||||
if (accounts) {
|
|
||||||
this.blockchainConnector.setDefaultAccount(accounts[0]);
|
|
||||||
}
|
|
||||||
let _err = err;
|
|
||||||
try {
|
|
||||||
await cb(_err);
|
|
||||||
} catch (e) {
|
|
||||||
_err = e;
|
|
||||||
} finally {
|
|
||||||
doneCb(_err);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
Blockchain.doFirst = function(todo) {
|
Blockchain.doFirst = function(todo) {
|
||||||
todo((err) => {
|
todo((err) => {
|
||||||
this.done = true;
|
this.done = true;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user