diff --git a/lib/core/config.js b/lib/core/config.js index 26743320c..09c01ffb5 100644 --- a/lib/core/config.js +++ b/lib/core/config.js @@ -1,8 +1,9 @@ -var fs = require('./fs.js'); -var File = require('./file.js'); -var Plugins = require('./plugins.js'); -var utils = require('../utils/utils.js'); -var path = require('path'); +const fs = require('./fs.js'); +const File = require('./file.js'); +const Plugins = require('./plugins.js'); +const utils = require('../utils/utils.js'); +const path = require('path'); +const request = require('request'); var Config = function(options) { this.env = options.env; @@ -142,6 +143,48 @@ Config.prototype.loadContractsConfigFile = function() { this.contractsConfig = this._mergeConfig(configFilePath, configObject, this.env); }; +Config.prototype.getExternalContractUrl = function (contract) { + let url; + const RAW_URL = 'https://raw.githubusercontent.com/'; + const MALFORMED_ERROR = 'Malformed Github URL for '; + if (contract.file.startsWith('https://github')) { + const match = contract.file.match(/https:\/\/github\.[a-z]+\/(.*)/); + if (!match) { + this.logger.error(MALFORMED_ERROR + contract.file); + return ''; + } + url = `${RAW_URL}${match[1].replace('blob/', '')}`; + } else if (contract.file.startsWith('git')) { + // Match values + // [0] entire input + // [1] git:// + // [2] user + // [3] repository + // [4] path + // [5] branch + const match = contract.file.match( + /(git:\/\/)?github\.[a-z]+\/([a-zA-Z0-9_\-.]+)\/([a-zA-Z0-9_\-7]+)\/([a-zA-Z0-9_\-\/.]+)#?([a-zA-Z0-1_\-.]*)?/ + ); + if (!match) { + this.logger.error(MALFORMED_ERROR + contract.file); + return ''; + } + let branch = match[5]; + if (!branch) { + branch = 'master'; + } + url = `${RAW_URL}${match[2]}/${match[3]}/${branch}/${match[4]}`; + } else { + url = contract.file; + } + return url; +}; + +Config.prototype.loadContractOnTheWeb = function (contract) { + const url = this.getExternalContractUrl(contract); + request(url).pipe(fs.createWriteStream('doodle.png')); +}; + Config.prototype.loadExternalContractsFiles = function() { let contracts = this.contractsConfig.contracts; for (let contractName in contracts) { @@ -149,7 +192,9 @@ Config.prototype.loadExternalContractsFiles = function() { if (!contract.file) { continue; } - if (fs.existsSync(contract.file)) { + if (contract.file.startsWith('http') || contract.file.startsWith('git')) { + this.loadContractOnTheWeb(contract); + } else if (fs.existsSync(contract.file)) { this.contractsFiles.push(new File({filename: contract.file, type: "dapp_file", basedir: '', path: contract.file})); } else if (fs.existsSync(path.join('./node_modules/', contract.file))) { this.contractsFiles.push(new File({filename: path.join('./node_modules/', contract.file), type: "dapp_file", basedir: '', path: path.join('./node_modules/', contract.file)})); diff --git a/package.json b/package.json index ff6c94ef6..fd8a1d65c 100644 --- a/package.json +++ b/package.json @@ -24,11 +24,11 @@ "async": "^2.0.1", "babel-core": "^6.26.0", "babel-loader": "^7.1.2", + "babel-plugin-webpack-aliases": "^1.1.3", "babel-preset-es2015": "^6.24.1", "babel-preset-es2016": "^6.24.1", "babel-preset-es2017": "6.24.1", "babel-preset-react": "^6.24.1", - "babel-plugin-webpack-aliases": "^1.1.3", "blessed": "^0.1.81", "chokidar": "^1.6.0", "colors": "^1.1.2", @@ -49,6 +49,7 @@ "parse-json": "^4.0.0", "promptly": "^2.1.0", "propose": "0.0.5", + "request": "^2.85.0", "serve-static": "^1.11.1", "shelljs": "^0.5.0", "solc": "0.4.17", diff --git a/test/config.js b/test/config.js index eb04d9709..79660f841 100644 --- a/test/config.js +++ b/test/config.js @@ -1,17 +1,19 @@ /*globals describe, it*/ -let Config = require('../lib/core/config.js'); -let Plugins = require('../lib/core/plugins.js'); -let assert = require('assert'); +const Config = require('../lib/core/config.js'); +const Plugins = require('../lib/core/plugins.js'); +const assert = require('assert'); +const TestLogger = require('../lib/tests/test_logger.js'); -describe('embark.Config', function() { +describe('embark.Config', function () { let config = new Config({ env: 'myenv', configDir: './test/test1/config/' }); config.plugins = new Plugins({plugins: {}}); + config.logger = new TestLogger({}); - describe('#loadBlockchainConfigFile', function() { - it('should load blockchain config correctly', function() { + describe('#loadBlockchainConfigFile', function () { + it('should load blockchain config correctly', function () { config.loadBlockchainConfigFile(); let expectedConfig = { "enabled": true, @@ -32,30 +34,97 @@ describe('embark.Config', function() { }); }); - describe('#loadContractsConfigFile', function() { - it('should load contract config correctly', function() { - config.loadContractsConfigFile(); - let expectedConfig = { - versions: { 'web3.js': '1.0.0-beta', solc: '0.4.17' }, - deployment: { host: 'localhost', port: 8545, type: 'rpc' }, - dappConnection: [ '$WEB3', 'localhost:8545' ], - "gas": "auto", - "contracts": { - "SimpleStorage": { - "args": [ - 100 - ], - "gas": 123456 - }, - "Token": { - "args": [ - 200 - ] - } + describe('#loadContractsConfigFile', function () { + it('should load contract config correctly', function () { + config.loadContractsConfigFile(); + let expectedConfig = { + versions: {'web3.js': '1.0.0-beta', solc: '0.4.17'}, + deployment: {host: 'localhost', port: 8545, type: 'rpc'}, + dappConnection: ['$WEB3', 'localhost:8545'], + "gas": "auto", + "contracts": { + "SimpleStorage": { + "args": [100], + "gas": 123456 + }, + "Token": { + "args": [200] } - }; + } + }; - assert.deepEqual(config.contractsConfig, expectedConfig); + assert.deepEqual(config.contractsConfig, expectedConfig); + }); + }); + + describe('#getExternalContractUrl', function () { + it('should get the right url for a https://github file', function () { + const url = config.getExternalContractUrl( + {file: 'https://github.com/embark-framework/embark/blob/master/test_app/app/contracts/simple_storage.sol'} + ); + assert.strictEqual(url, + 'https://raw.githubusercontent.com/embark-framework/embark/master/test_app/app/contracts/simple_storage.sol'); + }); + + it('should fail for a malformed https://github file', function () { + const url = config.getExternalContractUrl( + {file: 'https://github/embark-framework/embark/blob/master/test_app/app/contracts/simple_storage.sol'} + ); + assert.strictEqual(url, ''); + }); + + it('should get the right url for a git:// file with no branch #', function () { + const url = config.getExternalContractUrl( + {file: 'git://github.com/status-im/contracts/contracts/identity/ERC725.sol'} + ); + console.log(url); + assert.strictEqual(url, + 'https://raw.githubusercontent.com/status-im/contracts/master/contracts/identity/ERC725.sol'); + }); + + it('should get the right url for a git:// file with a branch #', function () { + const url = config.getExternalContractUrl( + {file: 'git://github.com/status-im/contracts/contracts/identity/ERC725.sol#myBranch'} + ); + assert.strictEqual(url, + 'https://raw.githubusercontent.com/status-im/contracts/myBranch/contracts/identity/ERC725.sol'); + }); + + it('should fail when the git:// file is malformed', function () { + const url = config.getExternalContractUrl( + {file: 'git://github.com/identity/ERC725.sol#myBranch'} + ); + assert.strictEqual(url, ''); + }); + + it('should get the right url with a github.com file without branch #', function () { + const url = config.getExternalContractUrl( + {file: 'github.com/status-im/contracts/contracts/identity/ERC725.sol'} + ); + assert.strictEqual(url, + 'https://raw.githubusercontent.com/status-im/contracts/master/contracts/identity/ERC725.sol'); + }); + + it('should get the right url with a github.com file with branch #', function () { + const url = config.getExternalContractUrl( + {file: 'github.com/status-im/contracts/contracts/identity/ERC725.sol#theBranch'} + ); + assert.strictEqual(url, + 'https://raw.githubusercontent.com/status-im/contracts/theBranch/contracts/identity/ERC725.sol'); + }); + + it('should fail with a malformed github.com url', function () { + const url = config.getExternalContractUrl( + {file: 'github/status-im/contracts/contracts/identity/ERC725.sol#theBranch'} + ); + assert.strictEqual(url, ''); + }); + + it('should succeed with a generic http url', function () { + const url = config.getExternalContractUrl( + {file: 'http://myurl.com/myFile.sol'} + ); + assert.strictEqual(url, 'http://myurl.com/myFile.sol'); }); });