Merge branch 'beforeDeploy' into develop

This commit is contained in:
hodlbank 2018-01-17 23:08:22 +00:00
commit ffe9af74bb
4 changed files with 124 additions and 55 deletions

View File

@ -29,6 +29,7 @@ The ``embark`` object then provides an api to extend different functionality of
* plugin to add standard contracts or a contract framework (``embark.registerContractConfiguration`` and ``embark.addContractFile``) * plugin to add standard contracts or a contract framework (``embark.registerContractConfiguration`` and ``embark.addContractFile``)
* plugin to make some contracts available in all environments for use by other contracts or the dapp itself e.g a Token, a DAO, ENS, etc.. (``embark.registerContractConfiguration`` and ``embark.addContractFile``) * plugin to make some contracts available in all environments for use by other contracts or the dapp itself e.g a Token, a DAO, ENS, etc.. (``embark.registerContractConfiguration`` and ``embark.addContractFile``)
* plugin to add a libraries such as react or boostrap (``embark.addFileToPipeline``) * plugin to add a libraries such as react or boostrap (``embark.addFileToPipeline``)
* plugin to process contract's binary code before deployment (``embark.beforeDeploy``)
* plugin to specify a particular web3 initialization for special provider uses (``embark.registerClientWeb3Provider``) * plugin to specify a particular web3 initialization for special provider uses (``embark.registerClientWeb3Provider``)
* plugin to create a different contract wrapper (``embark.registerContractsGeneration``) * plugin to create a different contract wrapper (``embark.registerContractsGeneration``)
* plugin to add new console commands (``embark.registerConsoleCommand``) * plugin to add new console commands (``embark.registerConsoleCommand``)
@ -137,6 +138,30 @@ This call is used to add a file to the pipeline so it's included with the dapp o
embark.addFileToPipeline("./jquery.js", {skipPipeline: true}); embark.addFileToPipeline("./jquery.js", {skipPipeline: true});
} }
**embark.registerBeforeDeploy(callback(options))**
This call can be used to add handler to process contract code after it was generated, but immediately before it is going to be deployed.
It is useful to replace placeholders with dynamic values.
options available:
* embarkDeploy - instance of Deploy class. Has following fields: web3, contractsManager, logger, env, chainConfig, gasLimit.
* pluginConfig - plugin configuration object from embark.json
* deploymentAccount - address of account which will be used to deploy this contract
* contract - contract object.
* callback - callback function that handler must call with result object as the only argument. Result object must have field contractCode with (un)modified code from contract.code
expected return: ignored
example:
.. code:: javascript
module.exports = function(embark) {
embark.registerBeforeDeploy(function(options) {
return options.contract.code.replace(/deaddeaddeaddeaddeaddeaddeaddeaddeaddead/ig, 'c0dec0dec0dec0dec0dec0dec0dec0dec0dec0de');
});
}
**embark.registerClientWeb3Provider(callback(options))** **embark.registerClientWeb3Provider(callback(options))**
@ -211,11 +236,8 @@ expected return: ``string`` (output to print in console) or ``boolean`` (skip co
expected doneCallback arguments: ``err`` and ``hash`` of compiled contracts expected doneCallback arguments: ``err`` and ``hash`` of compiled contracts
* Hash of objects containing the compiled contracts. (key: contractName, value: contract object) * Hash of objects containing the compiled contracts. (key: contractName, value: contract object)
* code - contract bytecode (string) * code - contract bytecode (string)
* runtimeBytecode - contract runtimeBytecode (string) * runtimeBytecode - contract runtimeBytecode (string)
* gasEstimates - gas estimates for constructor and methods (hash) * gasEstimates - gas estimates for constructor and methods (hash)
* e.g ``{"creation":[20131,38200],"external":{"get()":269,"set(uint256)":20163,"storedData()":224},"internal":{}}`` * e.g ``{"creation":[20131,38200],"external":{"get()":269,"set(uint256)":20163,"storedData()":224},"internal":{}}``
* functionHashes - object with methods and their corresponding hash identifier (hash) * functionHashes - object with methods and their corresponding hash identifier (hash)
@ -273,13 +295,10 @@ This call is used to listen and react to events that happen in Embark such as co
* eventName - name of event to listen to * eventName - name of event to listen to
* available events: * available events:
* "contractsDeployed" - triggered when contracts have been deployed * "contractsDeployed" - triggered when contracts have been deployed
* "file-add", "file-change", "file-remove", "file-event" - triggered on * "file-add", "file-change", "file-remove", "file-event" - triggered on a file change, args is (filetype, path)
a file change, args is (filetype, path) * "abi", "abi-vanila", "abi-contracts-vanila" - triggered when contracts have been deployed and returns the generated JS code
* "abi", "abi-vanila", "abi-contracts-vanila" - triggered when contracts
have been deployed and returns the generated JS code
* "outputDone" - triggered when dapp is (re)generated * "outputDone" - triggered when dapp is (re)generated
* "firstDeploymentDone" - triggered when the dapp is deployed and generated * "firstDeploymentDone" - triggered when the dapp is deployed and generated for the first time
for the first time
.. code:: javascript .. code:: javascript
@ -293,4 +312,3 @@ This call is used to listen and react to events that happen in Embark such as co
} }
}); });
} }

View File

@ -13,6 +13,7 @@ class Deploy {
this.logger = options.logger; this.logger = options.logger;
this.env = options.env; this.env = options.env;
this.chainConfig = options.chainConfig; this.chainConfig = options.chainConfig;
this.plugins = options.plugins;
this.gasLimit = options.gasLimit; this.gasLimit = options.gasLimit;
} }
@ -182,6 +183,8 @@ class Deploy {
} }
let contractCode = contract.code; let contractCode = contract.code;
// Applying linked contracts
let contractsList = self.contractsManager.listContracts(); let contractsList = self.contractsManager.listContracts();
for (let contractObj of contractsList) { for (let contractObj of contractsList) {
let filename = contractObj.filename; let filename = contractObj.filename;
@ -204,6 +207,43 @@ class Deploy {
contractCode = contractCode.replace(new RegExp(toReplace, "g"), deployedAddress); contractCode = contractCode.replace(new RegExp(toReplace, "g"), deployedAddress);
} }
// saving code changes back to contract object
contract.code = contractCode;
// selected in deploy_manager
let deploymentAccount = self.web3.eth.defaultAccount || accounts[0];
let beforeDeployPlugins = self.plugins.getPluginsFor('beforeDeploy');
async.waterfall([
(asyncCallback)=>{
//self.logger.info("applying beforeDeploy plugins...", beforeDeployPlugins.length);
async.eachSeries(beforeDeployPlugins, (plugin, eachPluginCb)=>{
self.logger.info("running beforeDeploy plugin " + plugin.name + " .");
// calling each beforeDeploy handler declared by the plugin
async.eachSeries(plugin.beforeDeploy, (beforeDeployFn, eachCb)=>{
beforeDeployFn({
embarkDeploy: self,
pluginConfig: plugin.pluginConfig,
deploymentAccount: deploymentAccount,
contract: contract,
callback:
(function(resObj){
contract.code = resObj.contractCode;
eachCb();
})
});
}, ()=>{
//self.logger.info('All beforeDeploy handlers of the plugin has processed.');
eachPluginCb();
});
}, ()=>{
//self.logger.info('All beforeDeploy plugins has been processed.');
contractCode = contract.code;
asyncCallback();
});
},
(asyncCallback)=>{
let contractObject = new self.web3.eth.Contract(contract.abiDefinition); let contractObject = new self.web3.eth.Contract(contract.abiDefinition);
let deployObject; let deployObject;
@ -220,7 +260,7 @@ class Deploy {
self.logger.info("deploying " + contract.className.bold.cyan + " with ".green + contract.gas + " gas".green); self.logger.info("deploying " + contract.className.bold.cyan + " with ".green + contract.gas + " gas".green);
deployObject.send({ deployObject.send({
from: accounts[0], from: deploymentAccount,
gas: contract.gas, gas: contract.gas,
gasPrice: contract.gasPrice gasPrice: contract.gasPrice
}).on('receipt', function(receipt) { }).on('receipt', function(receipt) {
@ -245,6 +285,10 @@ class Deploy {
}).on('error', function(error) { }).on('error', function(error) {
return callback(new Error("error deploying =" + contract.className + "= due to error: " + error.message)); return callback(new Error("error deploying =" + contract.className + "= due to error: " + error.message));
}); });
}
]); // end of async.waterfall
}); });
} }

View File

@ -77,6 +77,7 @@ class DeployManager {
logger: self.logger, logger: self.logger,
chainConfig: self.chainConfig, chainConfig: self.chainConfig,
env: self.config.env, env: self.config.env,
plugins: self.plugins,
gasLimit: self.gasLimit gasLimit: self.gasLimit
}); });

View File

@ -11,6 +11,7 @@ var Plugin = function(options) {
this.pluginConfig = options.pluginConfig; this.pluginConfig = options.pluginConfig;
this.shouldInterceptLogs = options.interceptLogs; this.shouldInterceptLogs = options.interceptLogs;
this.clientWeb3Providers = []; this.clientWeb3Providers = [];
this.beforeDeploy = [];
this.contractsGenerators = []; this.contractsGenerators = [];
this.pipeline = []; this.pipeline = [];
this.pipelineFiles = []; this.pipelineFiles = [];
@ -85,6 +86,11 @@ Plugin.prototype.registerClientWeb3Provider = function(cb) {
this.pluginTypes.push('clientWeb3Provider'); this.pluginTypes.push('clientWeb3Provider');
}; };
Plugin.prototype.registerBeforeDeploy = function(cb) {
this.beforeDeploy.push(cb);
this.pluginTypes.push('beforeDeploy');
};
Plugin.prototype.registerContractsGeneration = function(cb) { Plugin.prototype.registerContractsGeneration = function(cb) {
this.contractsGenerators.push(cb); this.contractsGenerators.push(cb);
this.pluginTypes.push('contractGeneration'); this.pluginTypes.push('contractGeneration');