[+] Added beforeDeploy handlers.

[+] Plugins can call embark.registerBeforeDeploy() to register beforeDeploy handlers.
This commit is contained in:
hodlbank 2018-01-17 23:04:19 +00:00
parent de72733c31
commit 07c6be968a
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 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 process contract's binary code before deployment (``embark.beforeDeploy``)
* plugin to specify a particular web3 initialization for special provider uses (``embark.registerClientWeb3Provider``)
* plugin to create a different contract wrapper (``embark.registerContractsGeneration``)
* 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.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))**
@ -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
* Hash of objects containing the compiled contracts. (key: contractName, value: contract object)
* code - contract bytecode (string)
* runtimeBytecode - contract runtimeBytecode (string)
* gasEstimates - gas estimates for constructor and methods (hash)
* e.g ``{"creation":[20131,38200],"external":{"get()":269,"set(uint256)":20163,"storedData()":224},"internal":{}}``
* 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
* available events:
* "contractsDeployed" - triggered when contracts have been deployed
* "file-add", "file-change", "file-remove", "file-event" - triggered on
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
* "file-add", "file-change", "file-remove", "file-event" - triggered on 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
* "outputDone" - triggered when dapp is (re)generated
* "firstDeploymentDone" - triggered when the dapp is deployed and generated
for the first time
* "firstDeploymentDone" - triggered when the dapp is deployed and generated for the first time
.. 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.env = options.env;
this.chainConfig = options.chainConfig;
this.plugins = options.plugins;
this.gasLimit = options.gasLimit;
}
@ -182,6 +183,8 @@ class Deploy {
}
let contractCode = contract.code;
// Applying linked contracts
let contractsList = self.contractsManager.listContracts();
for (let contractObj of contractsList) {
let filename = contractObj.filename;
@ -204,6 +207,43 @@ class Deploy {
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 deployObject;
@ -220,7 +260,7 @@ class Deploy {
self.logger.info("deploying " + contract.className.bold.cyan + " with ".green + contract.gas + " gas".green);
deployObject.send({
from: accounts[0],
from: deploymentAccount,
gas: contract.gas,
gasPrice: contract.gasPrice
}).on('receipt', function(receipt) {
@ -245,6 +285,10 @@ class Deploy {
}).on('error', function(error) {
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,
chainConfig: self.chainConfig,
env: self.config.env,
plugins: self.plugins,
gasLimit: self.gasLimit
});

View File

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