def find_best_vyper_version( contract_sources: Dict[str, str], install_needed: bool = False, install_latest: bool = False, silent: bool = True, ) -> str: """ Analyze contract pragma and find the best compatible version across multiple 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_vyper_version_list() for path, source in contract_sources.items(): pragma_spec = sources.get_vyper_pragma_spec(source, path) 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 IncompatibleVyperVersion( "No installable vyper version compatible across all sources") if not installed_versions and not (install_needed or install_latest): raise IncompatibleVyperVersion( "No installed vyper 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_vyper(max(available_versions)) return str(max(available_versions)) if not silent: print( f"New compatible vyper version available: {max(available_versions)}" ) return str(max(installed_versions))
def find_vyper_versions( contract_sources: Dict[str, str], install_needed: bool = False, install_latest: bool = False, silent: bool = True, ) -> Dict: """ Analyzes contract pragmas and determines which vyper 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_vyper_version_list() pragma_specs: Dict = {} to_install = set() new_versions = set() for path, source in contract_sources.items(): pragma_specs[path] = sources.get_vyper_pragma_spec(source, path) version = pragma_specs[path].select(installed_versions) if not version and not (install_needed or install_latest): raise IncompatibleVyperVersion( f"No installed vyper version matching '{pragma_specs[path]}' in '{path}'" ) # if no installed version of vyper matches the pragma, find the latest available version latest = pragma_specs[path].select(available_versions) if not version and not latest: raise IncompatibleVyperVersion( f"No installable vyper 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_vyper(*to_install) _, installed_versions = _get_vyper_version_list() elif new_versions and not silent: print( f"New compatible vyper version{'s' if len(new_versions) > 1 else ''}" f" available: {', '.join(new_versions)}") # organize source paths by latest available vyper 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 test_get_vyper_pragma_spec(version, spec): source = f"""# @version {version}""" assert sources.get_vyper_pragma_spec(source) == spec