From d4c04bbed7668f6d4acdd2c183a57b6a2ab4c98a Mon Sep 17 00:00:00 2001 From: Eric Mastro Date: Mon, 21 May 2018 21:43:36 +1000 Subject: [PATCH 1/2] Improve dapp imports to allow alternate syntax for importing contracts * Now supports alternate import statements: * import {Token} from 'Embark/contracts'; * import * as Contracts from 'Embark/contracts'; as well as the existing syntax: * import Token from 'Embark/contracts/Token'; * Contracts js files moved from .embark to .embark/contracts * .embark/contracts/index.js generated on the fly which requires all contracts in .embark/contract automatically and then creates a module.exports with each of them. --- lib/i18n/locales/en.json | 9 +++++++-- lib/pipeline/pipeline.js | 30 +++++++++++++++++++++++------- 2 files changed, 30 insertions(+), 9 deletions(-) diff --git a/lib/i18n/locales/en.json b/lib/i18n/locales/en.json index c3618b9d2..160bbf292 100644 --- a/lib/i18n/locales/en.json +++ b/lib/i18n/locales/en.json @@ -109,5 +109,10 @@ "{{className}} has code associated to it but it's configured as an instanceOf {{parentContractName}}": "{{className}} has code associated to it but it's configured as an instanceOf {{parentContractName}}", "downloading {{packageName}} {{version}}....": "downloading {{packageName}} {{version}}....", "Swarm node is offline...": "Swarm node is offline...", - "Swarm node detected...": "Swarm node detected..." -} + "Swarm node detected...": "Swarm node detected...", + "Cannot find file %s Please ensure you are running this command inside the Dapp folder": "Cannot find file %s Please ensure you are running this command inside the Dapp folder", + "finished building": "finished building", + "compiling Vyper contracts": "compiling Vyper contracts", + "Vyper exited with error code ": "Vyper exited with error code ", + "attempted to deploy %s without specifying parameters": "attempted to deploy %s without specifying parameters" +} \ No newline at end of file diff --git a/lib/pipeline/pipeline.js b/lib/pipeline/pipeline.js index b11299324..30f02b118 100644 --- a/lib/pipeline/pipeline.js +++ b/lib/pipeline/pipeline.js @@ -36,6 +36,7 @@ class Pipeline { function createImportList(next) { importsList["Embark/EmbarkJS"] = fs.dappPath(".embark", 'embark.js'); importsList["Embark/web3"] = fs.dappPath(".embark", 'web3_instance.js'); + importsList["Embark/contracts"] = fs.dappPath(".embark/contracts", ''); self.plugins.getPluginsProperty('imports', 'imports').forEach(function (importObject) { let [importName, importLocation] = importObject; @@ -44,15 +45,30 @@ class Pipeline { next(); }, - function writeContracts(next) { + function writeContracts(next) { self.events.request('contracts:list', (contracts) => { - async.each(contracts, (contract, eachCb) => { - self.events.request('code-generator:contract', contract.className, (contractCode) => { - let filePath = fs.dappPath(".embark", contract.className + '.js'); - importsList["Embark/contracts/" + contract.className] = filePath; - fs.writeFile(filePath, contractCode, eachCb); + // ensure the .embark/contracts directory exists (create if not exists) + fs.mkdirp(fs.dappPath(".embark/contracts", ''), (err) => { + if(err) return next(err); + async.each(contracts, (contract, eachCb) => { + self.events.request('code-generator:contract', contract.className, (contractCode) => { + let filePath = fs.dappPath(".embark/contracts", contract.className + '.js'); + importsList["Embark/contracts/" + contract.className] = filePath; + fs.writeFile(filePath, contractCode, eachCb); + }); + }, function(){ + // create a file .embark/contracts/index.js that requires all files in the .embark/contracts directory + // except for itself. Used to enable alternate import syntax: + // e.g. import {Token} from 'Embark/contracts' + // e.g. import * as Contracts from 'Embark/contracts' + let importsHelper = `module.exports = (ctx => { + let keys = ctx.keys(); + let values = keys.map(ctx); + return keys.reduce((o, k, i) => { o[k.replace('./', '').replace('.js', '')] = values[i].default; return o; }, {}); + })(require.context('./', true, /^(?!.*index).*\.js$/));`; + fs.writeFile(fs.dappPath('.embark/contracts/index.js'), importsHelper, next); }); - }, next); + }); }); }, function assetFileWrite(next) { From 85919a4f6dc4107e6fe085d0b554dbc95f4e3758 Mon Sep 17 00:00:00 2001 From: emizzle Date: Tue, 22 May 2018 12:11:45 +1000 Subject: [PATCH 2/2] Update to make the imports 'shim' more readable as requested. --- lib/i18n/locales/en.json | 6 +++++- lib/pipeline/pipeline.js | 26 +++++++++++++++----------- 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/lib/i18n/locales/en.json b/lib/i18n/locales/en.json index 160bbf292..767cd38a0 100644 --- a/lib/i18n/locales/en.json +++ b/lib/i18n/locales/en.json @@ -114,5 +114,9 @@ "finished building": "finished building", "compiling Vyper contracts": "compiling Vyper contracts", "Vyper exited with error code ": "Vyper exited with error code ", - "attempted to deploy %s without specifying parameters": "attempted to deploy %s without specifying parameters" + "attempted to deploy %s without specifying parameters": "attempted to deploy %s without specifying parameters", + "adding %s to ipfs": "adding %s to ipfs", + "DApp available at": "DApp available at", + "successfully uploaded to ipfs": "successfully uploaded to ipfs", + "finished building DApp and deploying to": "finished building DApp and deploying to" } \ No newline at end of file diff --git a/lib/pipeline/pipeline.js b/lib/pipeline/pipeline.js index 30f02b118..8eb33703a 100644 --- a/lib/pipeline/pipeline.js +++ b/lib/pipeline/pipeline.js @@ -50,23 +50,27 @@ class Pipeline { // ensure the .embark/contracts directory exists (create if not exists) fs.mkdirp(fs.dappPath(".embark/contracts", ''), (err) => { if(err) return next(err); - async.each(contracts, (contract, eachCb) => { + + // Create a file .embark/contracts/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 = fs.createWriteStream(fs.dappPath(".embark/contracts", 'index.js')); + importsHelperFile.write('module.exports = {\n'); + + async.eachOf(contracts, (contract, idx, eachCb) => { self.events.request('code-generator:contract', contract.className, (contractCode) => { let filePath = fs.dappPath(".embark/contracts", contract.className + '.js'); importsList["Embark/contracts/" + contract.className] = filePath; fs.writeFile(filePath, contractCode, eachCb); + + // add the contract to the exports list to support alternate import syntax + importsHelperFile.write(`"${contract.className}": require('./${contract.className}').default`); + if(idx < contracts.length - 1) importsHelperFile.write(',\n'); // add a comma if we have more contracts to add }); }, function(){ - // create a file .embark/contracts/index.js that requires all files in the .embark/contracts directory - // except for itself. Used to enable alternate import syntax: - // e.g. import {Token} from 'Embark/contracts' - // e.g. import * as Contracts from 'Embark/contracts' - let importsHelper = `module.exports = (ctx => { - let keys = ctx.keys(); - let values = keys.map(ctx); - return keys.reduce((o, k, i) => { o[k.replace('./', '').replace('.js', '')] = values[i].default; return o; }, {}); - })(require.context('./', true, /^(?!.*index).*\.js$/));`; - fs.writeFile(fs.dappPath('.embark/contracts/index.js'), importsHelper, next); + importsHelperFile.write('\n}'); // close the module.exports = {} + importsHelperFile.close(next); // close the write stream }); }); });