def find_best_solc_version( contract_sources: Dict[str, str], install_needed: bool = False, install_latest: bool = False, silent: bool = True, ) -> str: """ Analyzes contract pragmas and finds the best version compatible with all sources. Args: contract_sources: a dictionary in the form of {'path': "source code"} install_needed: if True, will install when no installed version matches the contract pragma install_latest: if True, will install when a newer version is available than the installed one silent: set to False to enable verbose reporting Returns: version string """ available_versions, installed_versions = _get_solc_version_list() for path, source in contract_sources.items(): pragma_string = next(PRAGMA_REGEX.finditer(source), None) if pragma_string is None: raise PragmaError(f"No version pragma in '{path}'") pragma_spec = NpmSpec(pragma_string.groups()[0]) installed_versions = [ i for i in installed_versions if i in pragma_spec ] available_versions = [ i for i in available_versions if i in pragma_spec ] if not available_versions: raise IncompatibleSolcVersion( "No installable solc version compatible across all sources") if not installed_versions and not (install_needed or install_latest): raise IncompatibleSolcVersion( "No installed solc version compatible across all sources") if max(available_versions) > max(installed_versions, default=Version("0.0.0")): if install_latest or (install_needed and not installed_versions): install_solc(max(available_versions)) return str(max(available_versions)) if not silent: print( f"New compatible solc version available: {max(available_versions)}" ) return str(max(installed_versions))
def set_solc_version(version: Union[str, Version]) -> str: """Sets the solc version. If not available it will be installed.""" if not isinstance(version, Version): version = Version(version.lstrip("v")) if version < Version("0.4.22"): raise IncompatibleSolcVersion("Brownie only supports Solidity versions >=0.4.22") try: solcx.set_solc_version(version, silent=True) except solcx.exceptions.SolcNotInstalled: if version not in _get_solc_version_list()[0]: raise IncompatibleSolcVersion( f"Cannot install Solidity v{version} on this OS. You may be able to " f"manually compile from source with `solcx.compile_solc('{version}')`" ) install_solc(version) solcx.set_solc_version(version, silent=True) return str(solcx.get_solc_version())
def set_solc_version(version: str) -> str: """Sets the solc version. If not available it will be installed.""" if Version(version.lstrip("v")) < Version("0.4.22"): raise IncompatibleSolcVersion("Brownie only supports Solidity versions >=0.4.22") try: solcx.set_solc_version(version, silent=True) except solcx.exceptions.SolcNotInstalled: install_solc(version) solcx.set_solc_version(version, silent=True) return str(solcx.get_solc_version())
def set_solc_version(version): '''Sets the solc version. If not available it will be installed.''' if Version(version.lstrip('v')) < Version('0.4.22'): raise IncompatibleSolcVersion( "Brownie only supports Solidity versions >=0.4.22") try: solcx.set_solc_version(version, silent=True) except solcx.exceptions.SolcNotInstalled: install_solc(version) solcx.set_solc_version(version, silent=True) return solcx.get_solc_version_string()
def find_solc_versions( contract_sources: Dict[str, str], install_needed: bool = False, install_latest: bool = False, silent: bool = True, ) -> Dict: """ Analyzes contract pragmas and determines which solc version(s) to use. Args: contract_sources: a dictionary in the form of {'path': "source code"} install_needed: if True, will install when no installed version matches the contract pragma install_latest: if True, will install when a newer version is available than the installed one silent: set to False to enable verbose reporting Returns: dictionary of {'version': ['path', 'path', ..]} """ available_versions, installed_versions = _get_solc_version_list() pragma_specs: Dict = {} to_install = set() new_versions = set() for path, source in contract_sources.items(): pragma_specs[path] = sources.get_pragma_spec(source, path) version = pragma_specs[path].select(installed_versions) if not version and not (install_needed or install_latest): raise IncompatibleSolcVersion( f"No installed solc version matching '{pragma_specs[path]}' in '{path}'" ) # if no installed version of solc matches the pragma, find the latest available version latest = pragma_specs[path].select(available_versions) if not version and not latest: raise IncompatibleSolcVersion( f"No installable solc version matching '{pragma_specs[path]}' in '{path}'" ) if not version or (install_latest and latest > version): to_install.add(latest) elif latest and latest > version: new_versions.add(str(version)) # install new versions if needed if to_install: install_solc(*to_install) installed_versions = solcx.get_installed_solc_versions() elif new_versions and not silent: print( f"New compatible solc version{'s' if len(new_versions) > 1 else ''}" f" available: {', '.join(new_versions)}" ) # organize source paths by latest available solc version compiler_versions: Dict = {} for path, spec in pragma_specs.items(): version = spec.select(installed_versions) compiler_versions.setdefault(str(version), []).append(path) return compiler_versions
def find_solc_versions(contracts, install_needed=False, install_latest=False, silent=True): '''Analyzes contract pragmas and determines which solc version(s) to use. Args: contracts: a dictionary in the form of {'path': "source code"} install_needed: if True, will install when no installed version matches the contract pragma install_latest: if True, will install when a newer version is available than the installed one silent: enables verbose reporting Returns: dictionary of {'version': ['path', 'path', ..]} ''' installed_versions = [ Version(i[1:]) for i in solcx.get_installed_solc_versions() ] try: available_versions = [ Version(i[1:]) for i in solcx.get_available_solc_versions() ] except ConnectionError: if not installed_versions: raise ConnectionError( "Solc not installed and cannot connect to GitHub") available_versions = installed_versions pragma_regex = re.compile(r"pragma +solidity([^;]*);") version_regex = re.compile(r"(([<>]?=?|\^)\d+\.\d+\.\d+)+") pragma_specs = dict((i, set()) for i in contracts) to_install = set() for path, source in contracts.items(): try: pragma_string = next(pragma_regex.finditer(source))[0] except StopIteration: raise PragmaError(f"No version pragma in '{path}'") from None # convert pragma to Version objects comparator_set_range = pragma_string.replace(" ", "").split('||') for comparator_set in comparator_set_range: spec = Spec(*(i[0] for i in version_regex.findall(comparator_set))) spec = _standardize_spec(spec) pragma_specs[path].add(spec) # if no installed version of solc matches the pragma, find the latest available version if not next( (i for i in pragma_specs[path] if i.select(installed_versions)), None): try: version = _select_max(pragma_specs[path], available_versions) to_install.add(version) except ValueError: raise PragmaError( f"No installable solc version matching '{pragma_string}' in '{path}'" ) from None if not install_needed: raise IncompatibleSolcVersion( f"No installed solc version matching '{pragma_string}' in '{path}'" ) # install new versions if needed if to_install: install_solc(*to_install) installed_versions = [ Version(i[1:]) for i in solcx.get_installed_solc_versions() ] # organize source paths by latest available solc version compiler_versions = {} new_versions = set() for path, spec_list in pragma_specs.items(): version = _select_max(spec_list, installed_versions) compiler_versions.setdefault(str(version), []).append(path) latest = _select_max(spec_list, available_versions) if latest > version: new_versions.add(str(latest)) if new_versions: if install_latest: install_solc(*new_versions) return find_solc_versions(contracts) if not silent: print( f"New compatible solc version{'s' if len(new_versions) > 1 else ''}" f" available: {', '.join(new_versions)}") return compiler_versions
def find_solc_versions( contracts: Dict[str, str], install_needed: bool = False, install_latest: bool = False, silent: bool = True, ) -> Dict: """Analyzes contract pragmas and determines which solc version(s) to use. Args: contracts: a dictionary in the form of {'path': "source code"} install_needed: if True, will install when no installed version matches the contract pragma install_latest: if True, will install when a newer version is available than the installed one silent: set to False to enable verbose reporting Returns: dictionary of {'version': ['path', 'path', ..]} """ installed_versions = [ Version(i[1:]) for i in solcx.get_installed_solc_versions() ] try: available_versions = [ Version(i[1:]) for i in solcx.get_available_solc_versions() ] except ConnectionError: if not installed_versions: raise ConnectionError( "Solc not installed and cannot connect to GitHub") available_versions = installed_versions pragma_regex = re.compile(r"pragma +solidity([^;]*);") pragma_specs: Dict = {} to_install = set() new_versions = set() for path, source in contracts.items(): pragma_string = next(pragma_regex.finditer(source), None) if pragma_string is None: raise PragmaError(f"No version pragma in '{path}'") pragma_specs[path] = NpmSpec(pragma_string.groups()[0]) version = pragma_specs[path].select(installed_versions) if not version and not (install_needed or install_latest): raise IncompatibleSolcVersion( f"No installed solc version matching '{pragma_string[0]}' in '{path}'" ) # if no installed version of solc matches the pragma, find the latest available version latest = pragma_specs[path].select(available_versions) if not version and not latest: raise PragmaError( f"No installable solc version matching '{pragma_string[0]}' in '{path}'" ) if not version or (install_latest and latest > version): to_install.add(latest) elif latest > version: new_versions.add(str(version)) # install new versions if needed if to_install: install_solc(*to_install) installed_versions = [ Version(i[1:]) for i in solcx.get_installed_solc_versions() ] elif new_versions and not silent: print( f"New compatible solc version{'s' if len(new_versions) > 1 else ''}" f" available: {', '.join(new_versions)}") # organize source paths by latest available solc version compiler_versions: Dict = {} for path, spec in pragma_specs.items(): version = spec.select(installed_versions) compiler_versions.setdefault(str(version), []).append(path) return compiler_versions