From f45191d0e81e3ad3873e78c3891fdd5f9e9fd55c Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Thu, 15 Mar 2018 17:08:48 +0100 Subject: Support proper semver version ranges --- packages/deployer/src/compiler.ts | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) (limited to 'packages/deployer/src/compiler.ts') diff --git a/packages/deployer/src/compiler.ts b/packages/deployer/src/compiler.ts index 4563752f6..942777458 100644 --- a/packages/deployer/src/compiler.ts +++ b/packages/deployer/src/compiler.ts @@ -5,6 +5,7 @@ import 'isomorphic-fetch'; import * as _ from 'lodash'; import * as path from 'path'; import * as requireFromString from 'require-from-string'; +import * as semver from 'semver'; import solc = require('solc'); import * as Web3 from 'web3'; @@ -23,7 +24,7 @@ import { import { utils } from './utils/utils'; const ALL_CONTRACTS_IDENTIFIER = '*'; -const SOLIDITY_VERSION_REGEX = /(?:solidity\s\^?)(\d+\.\d+\.\d+)/; +const SOLIDITY_VERSION_RANGE_REGEX = /pragma solidity (.*);/; const SOLIDITY_FILE_EXTENSION_REGEX = /(.*\.sol)/; const IMPORT_REGEX = /(import\s)/; const DEPENDENCY_PATH_REGEX = /"([^"]+)"/; // Source: https://github.com/BlockChainCompany/soljitsu/blob/master/lib/shared.js @@ -85,10 +86,10 @@ export class Compiler { private static _getContractSpecificSourceData(source: string): ContractSpecificSourceData { const dependencies: string[] = []; const sourceHash = ethUtil.sha3(source); - const solcVersion = Compiler._parseSolidityVersion(source); + const solcVersionRange = Compiler._parseSolidityVersionRange(source); const contractSpecificSourceData: ContractSpecificSourceData = { dependencies, - solcVersion, + solcVersionRange, sourceHash, }; const lines = source.split('\n'); @@ -105,17 +106,17 @@ export class Compiler { return contractSpecificSourceData; } /** - * Searches Solidity source code for compiler version. + * Searches Solidity source code for compiler version range. * @param source Source code of contract. - * @return Solc compiler version. + * @return Solc compiler version range. */ - private static _parseSolidityVersion(source: string): string { - const solcVersionMatch = source.match(SOLIDITY_VERSION_REGEX); - if (_.isNull(solcVersionMatch)) { - throw new Error('Could not find Solidity version in source'); + private static _parseSolidityVersionRange(source: string): string { + const solcVersionRangeMatch = source.match(SOLIDITY_VERSION_RANGE_REGEX); + if (_.isNull(solcVersionRangeMatch)) { + throw new Error('Could not find Solidity version range in source'); } - const solcVersion = solcVersionMatch[1]; - return solcVersion; + const solcVersionRange = solcVersionRangeMatch[1]; + return solcVersionRange; } /** * Normalizes the path found in the error message. @@ -189,8 +190,12 @@ export class Compiler { if (!shouldCompile) { return; } - - const fullSolcVersion = binPaths[contractSpecificSourceData.solcVersion]; + const availableCompilerVersions = _.keys(binPaths); + const solcVersion = semver.maxSatisfying( + availableCompilerVersions, + contractSpecificSourceData.solcVersionRange, + ); + const fullSolcVersion = binPaths[solcVersion]; const compilerBinFilename = path.join(__dirname, '../../solc_bin', fullSolcVersion); let solcjs: string; const isCompilerAvailableLocally = fs.existsSync(compilerBinFilename); @@ -208,7 +213,7 @@ export class Compiler { } const solcInstance = solc.setupMethods(requireFromString(solcjs, compilerBinFilename)); - logUtils.log(`Compiling ${fileName}...`); + logUtils.log(`Compiling ${fileName} with Solidity v${solcVersion}...`); const source = this._contractSources[fileName]; const input = { [fileName]: source, @@ -243,7 +248,7 @@ export class Compiler { const sources = _.keys(compiled.sources); const updated_at = Date.now(); const contractNetworkData: ContractNetworkData = { - solc_version: contractSpecificSourceData.solcVersion, + solc_version: solcVersion, keccak256: sourceHash, source_tree_hash: sourceTreeHash, optimizer_enabled: this._optimizerEnabled, -- cgit v1.2.3