UNPKG

@truffle/compile-solidity

Version:

Compiler helper and artifact manager for Solidity files

133 lines (113 loc) 4.08 kB
const path = require("path"); const fs = require("fs"); const semver = require("semver"); const { Docker, Local, Native, VersionRange } = require("./loadingStrategies"); const defaultSolcVersion = "0.5.16"; class CompilerSupplier { constructor({ events, solcConfig }) { const { version, docker, compilerRoots, parser, spawn } = solcConfig; this.events = events; this.parser = parser; this.version = version ? version : defaultSolcVersion; this.docker = docker; this.compilerRoots = compilerRoots; this.strategyOptions = {}; if (version) this.strategyOptions.version = this.version; if (docker) this.strategyOptions.docker = compilerRoots; if (compilerRoots) this.strategyOptions.compilerRoots = compilerRoots; if (events) this.strategyOptions.events = events; if (spawn) this.strategyOptions.spawn = spawn; } badInputError(userSpecification) { const message = `Could not find a compiler version matching ${userSpecification}. ` + `compilers.solc.version option must be a string specifying:\n` + ` - a path to a locally installed solcjs\n` + ` - a solc version or range (ex: '0.4.22' or '^0.5.0')\n` + ` - a docker image name (ex: 'stable')\n` + ` - 'native' to use natively installed solc\n`; return new Error(message); } async downloadAndCacheSolc(version) { if (semver.validRange(version)) { return await new VersionRange(this.strategyOptions).getSolcFromCacheOrUrl( version ); } const message = `You must specify a valid solc version to download` + `Please ensure that the version you entered, ` + `${version}, is valid.`; throw new Error(message); } async load() { const userSpecification = this.version; let strategy; const useDocker = this.docker; const useNative = userSpecification === "native"; const useSpecifiedLocal = userSpecification && this.fileExists(userSpecification); const isValidVersionRange = semver.validRange(userSpecification); if (useDocker) { strategy = new Docker(this.strategyOptions); } else if (useNative) { strategy = new Native(this.strategyOptions); } else if (useSpecifiedLocal) { strategy = new Local(this.strategyOptions); } else if (isValidVersionRange) { strategy = new VersionRange(this.strategyOptions); } if (strategy) { const solc = await strategy.load(userSpecification); const parserSolc = await this.loadParserSolc(this.parser, solc); return { solc, parserSolc }; } else { throw this.badInputError(userSpecification); } } async loadParserSolc(parser, solc) { if (parser) { this.checkParser(parser); const solcVersion = solc.version(); const normalizedSolcVersion = semver.coerce(solcVersion).version; const options = Object.assign({}, this.strategyOptions, { version: normalizedSolcVersion }); return await new VersionRange(options).load(normalizedSolcVersion); } return false; } checkParser(parser) { if (parser !== "solcjs") throw new Error( `Unsupported parser "${parser}" found in truffle-config.js` ); } fileExists(localPath) { return fs.existsSync(localPath) || path.isAbsolute(localPath); } getDockerTags() { return new Docker(this.strategyOptions).getDockerTags(); } getReleases() { return new VersionRange(this.strategyOptions) .getSolcVersions() .then(list => { const prereleases = list.builds .filter(build => build["prerelease"]) .map(build => build["longVersion"]); const { rsort } = semver; // ensure releases are listed in descending order const releases = rsort(Object.keys(list.releases)); return { prereleases: prereleases, releases: releases, latestRelease: list.latestRelease }; }); } static getDefaultVersion() { return defaultSolcVersion; } } module.exports = CompilerSupplier;