Merge pull request #745 from embark-framework/deployIf

deployIf field + minor refactor
This commit is contained in:
Iuri Matias 2018-08-24 10:33:58 -04:00 committed by GitHub
commit 864b41a2c2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 73 additions and 20 deletions

View File

@ -167,7 +167,7 @@ class Engine {
this.registerModule('solidity', {ipc: self.ipc, useDashboard: this.useDashboard}); this.registerModule('solidity', {ipc: self.ipc, useDashboard: this.useDashboard});
this.registerModule('vyper'); this.registerModule('vyper');
this.registerModule('profiler'); this.registerModule('profiler');
this.registerModule('deploytracker'); this.registerModule('deploytracker', {trackContracts: options.trackContracts});
this.registerModule('specialconfigs'); this.registerModule('specialconfigs');
this.registerModule('console_listener', {ipc: self.ipc}); this.registerModule('console_listener', {ipc: self.ipc});
this.registerModule('contracts_manager'); this.registerModule('contracts_manager');

View File

@ -138,15 +138,18 @@ Plugins.prototype.runActionsForEvent = function(eventName, args, cb) {
let actionPlugins = this.getPluginsProperty('eventActions', 'eventActions', eventName); let actionPlugins = this.getPluginsProperty('eventActions', 'eventActions', eventName);
if (actionPlugins.length === 0) { if (actionPlugins.length === 0) {
return cb(); return cb(args);
} }
async.eachLimit(actionPlugins, 1, function(plugin, nextEach) { async.reduce(actionPlugins, args, function(current_args, plugin, nextEach) {
if (typeof (args) === 'function') { if (typeof (args) === 'function') {
plugin.call(plugin, nextEach); plugin.call(plugin, (params) => {
nextEach(null, (params || current_args));
});
} else { } else {
//plugin.call(plugin, ...args, nextEach); plugin.call(plugin, args, (params) => {
plugin.call(plugin, args, nextEach); nextEach(null, (params || current_args));
});
} }
}, cb); }, cb);
}; };

View File

@ -7,7 +7,7 @@ let utils = require('../../utils/utils.js');
// TODO: create a contract object // TODO: create a contract object
class ContractsManager { class ContractsManager {
constructor(embark) { constructor(embark, options) {
const self = this; const self = this;
this.logger = embark.logger; this.logger = embark.logger;
this.events = embark.events; this.events = embark.events;
@ -16,6 +16,7 @@ class ContractsManager {
this.contractDependencies = {}; this.contractDependencies = {};
this.deployOnlyOnConfig = false; this.deployOnlyOnConfig = false;
this.compileError = false; this.compileError = false;
this.compileOnceOnly = options.compileOnceOnly;
self.events.setCommandHandler('contracts:list', (cb) => { self.events.setCommandHandler('contracts:list', (cb) => {
cb(self.compileError, self.listContracts()); cb(self.compileError, self.listContracts());
@ -77,7 +78,7 @@ class ContractsManager {
}, },
function compileContracts(callback) { function compileContracts(callback) {
self.events.emit("status", __("Compiling...")); self.events.emit("status", __("Compiling..."));
if (process.env.isTest && self.compiledContracts && Object.keys(self.compiledContracts).length) { if (self.compileOnceOnly && self.compiledContracts && Object.keys(self.compiledContracts).length) {
// Only compile once for tests // Only compile once for tests
return callback(); return callback();
} }

View File

@ -140,13 +140,12 @@ class ContractDeployer {
return next(); return next();
} }
// TODO find a better way to do that self.plugins.emitAndRunActionsForEvent('deploy:contract:shouldDeploy', {contract: contract, shouldDeploy: true}, function(_err, params) {
if (process.env.isTest) { let trackedContract = params.contract;
return self.deployContract(contract, next); if (!params.shouldDeploy) {
return next();
} }
// TODO: this should be a plugin API instead, if not existing, it should by default deploy the contract if (!trackedContract.address) {
self.events.request("deploy:contract:shouldDeploy", contract, function(trackedContract) {
if (!trackedContract) {
return self.deployContract(contract, next); return self.deployContract(contract, next);
} }
@ -213,7 +212,9 @@ class ContractDeployer {
}); });
}, },
function applyBeforeDeploy(next) { function applyBeforeDeploy(next) {
self.plugins.emitAndRunActionsForEvent('deploy:contract:beforeDeploy', {contract: contract}, next); self.plugins.emitAndRunActionsForEvent('deploy:contract:beforeDeploy', {contract: contract}, (_params) => {
next();
});
}, },
function getGasPriceForNetwork(next) { function getGasPriceForNetwork(next) {
self.events.request("blockchain:gasPrice", (gasPrice) => { self.events.request("blockchain:gasPrice", (gasPrice) => {

View File

@ -6,6 +6,8 @@ class DeployTracker {
constructor(embark, options) { constructor(embark, options) {
this.logger = embark.logger; this.logger = embark.logger;
this.events = embark.events; this.events = embark.events;
this.embark = embark;
this.trackContracts = (options.trackContracts !== false);
// TODO: unclear where it comes from // TODO: unclear where it comes from
this.env = options.env; this.env = options.env;
@ -24,9 +26,20 @@ class DeployTracker {
self.save(); self.save();
}); });
this.events.setCommandHandler("deploy:contract:shouldDeploy", (contract, cb) => { self.embark.registerActionForEvent("deploy:contract:shouldDeploy", (params, cb) => {
if (!self.trackContracts) {
return cb(params);
}
let contract = params.contract;
let trackedContract = self.getContract(contract.className, contract.realRuntimeBytecode, contract.realArgs); let trackedContract = self.getContract(contract.className, contract.realRuntimeBytecode, contract.realArgs);
cb(trackedContract); if (trackedContract) {
params.contract.address = trackedContract.address;
}
if (params.shouldDeploy && trackedContract) {
params.shouldDeploy = true;
}
cb(params);
}); });
} }

View File

@ -12,6 +12,7 @@ class SpecialConfigs {
this.registerAfterDeployAction(); this.registerAfterDeployAction();
this.registerOnDeployAction(); this.registerOnDeployAction();
this.registerDeployIfAction();
} }
replaceWithAddresses(cmd, cb) { replaceWithAddresses(cmd, cb) {
@ -104,6 +105,30 @@ class SpecialConfigs {
}); });
} }
registerDeployIfAction() {
const self = this;
self.embark.registerActionForEvent("deploy:contract:shouldDeploy", (params, cb) => {
let cmd = params.contract.deployIf;
if (!cmd) {
return cb(params);
}
self.events.request('runcode:eval', cmd, (err, result) => {
if (err) {
self.logger.error(params.contract.className + ' deployIf directive has an error; contract will not deploy');
self.logger.error(err);
params.shouldDeploy = false;
} else if (!result) {
self.logger.info(params.contract.className + ' deployIf directive returned false; contract will not deploy');
params.shouldDeploy = false;
}
cb(params);
});
});
}
} }
module.exports = SpecialConfigs; module.exports = SpecialConfigs;

View File

@ -24,7 +24,6 @@ function getFilesFromDir(filePath, cb) {
module.exports = { module.exports = {
run: function (options) { run: function (options) {
process.env.isTest = true;
let failures = 0; let failures = 0;
let filePath = options.file; let filePath = options.file;
const loglevel = options.loglevel || 'warn'; const loglevel = options.loglevel || 'warn';

View File

@ -108,7 +108,8 @@ class Test {
web3: this.web3 web3: this.web3
}); });
this.engine.startService("deployment", { this.engine.startService("deployment", {
trackContracts: false trackContracts: false,
compileOnceOnly: true
}); });
this.events.request('deploy:setGasLimit', 6000000); this.events.request('deploy:setGasLimit', 6000000);
this.engine.startService("codeCoverage"); this.engine.startService("codeCoverage");

View File

@ -53,6 +53,7 @@ module.exports = {
} }
}, },
SomeContract: { SomeContract: {
deployIf: 'MyToken.methods.isAvailable().call()',
args: [ args: [
["$MyToken2", "$SimpleStorage"], ["$MyToken2", "$SimpleStorage"],
100 100

View File

@ -63,4 +63,7 @@ contract Token {
function safeToAdd(uint a, uint b) internal pure returns (bool) { function safeToAdd(uint a, uint b) internal pure returns (bool) {
return (a + b >= a); return (a + b >= a);
} }
function isAvailable() public constant returns (bool) {
return false;
}
} }

View File

@ -5,6 +5,7 @@ const MyToken = require('Embark/contracts/MyToken');
const MyToken2 = require('Embark/contracts/MyToken2'); const MyToken2 = require('Embark/contracts/MyToken2');
const AlreadyDeployedToken = require('Embark/contracts/AlreadyDeployedToken'); const AlreadyDeployedToken = require('Embark/contracts/AlreadyDeployedToken');
const Test = require('Embark/contracts/Test'); const Test = require('Embark/contracts/Test');
const SomeContract = require('Embark/contracts/SomeContract');
config({ config({
contracts: { contracts: {
@ -40,6 +41,7 @@ config({
} }
}, },
SomeContract: { SomeContract: {
deployIf: "MyToken.methods.isAvailable().call()",
args: [ args: [
["$MyToken2", "$SimpleStorage"], ["$MyToken2", "$SimpleStorage"],
100 100
@ -79,4 +81,8 @@ describe("Token", function () {
let result = await Test.methods.addr().call(); let result = await Test.methods.addr().call();
assert.strictEqual(result, MyToken.options.address); assert.strictEqual(result, MyToken.options.address);
}); });
it("should not deploy if deployIf returns false", async function() {
assert.ok(!SomeContract.options.address);
});
}); });