def get_release(self, repo_path: str, version: str) -> GitRelease: """ Get a release from Github. Args: repo_path (str): The path on Github to the repository, e.g. ``OpenZeppelin/openzeppelin-contracts``. version (str): The version of the release to get. Pass in ``"latest"`` to get the latest release. Returns: github.GitRelease.GitRelease """ repo = self._client.get_repo(repo_path) if version == "latest": return repo.get_latest_release() if not version.startswith("v"): version = f"v{version}" try: return repo.get_release(version) except UnknownObjectException: raise ProjectError( f"Unknown version '{version.lstrip('v')}' for repo '{repo.name}'." )
def _extract_local_manifest(self, project_path: Path): project_path = project_path.resolve() contracts_folder = project_path / self.contracts_folder project = self.project_manager.get_project( project_path, contracts_folder=contracts_folder, name=self.name, version=self.version, ) all_sources = get_all_files_in_directory(project.contracts_folder) excluded_files = set() for pattern in set(self.exclude): excluded_files.update( {f for f in project.contracts_folder.glob(pattern)}) sources = [s for s in all_sources if s not in excluded_files] project_manifest = project.create_manifest(file_paths=sources) if not project_manifest.contract_types: raise ProjectError( f"No contract types found in dependency '{self.name}'. " "Do you have the correct compilers installed?") # Cache the manifest for future use outside of this tempdir. self._target_manifest_cache_file.parent.mkdir(exist_ok=True, parents=True) self._target_manifest_cache_file.write_text( json.dumps(project_manifest.dict())) return project_manifest
def __getattr__(self, item: str) -> "ContractContainer": manifest = self.extract_manifest() if hasattr(manifest, item): return self.create_contract_container( contract_type=getattr(manifest, item)) raise ProjectError( f"Dependency project '{self.name}' has no contract '{item}'.")
def decode_dependency(self, config_dependency_data: Dict) -> DependencyAPI: for key, dependency_cls in self.dependency_types.items(): if key in config_dependency_data: return dependency_cls( **config_dependency_data, ) # type: ignore dep_id = config_dependency_data.get("name", json.dumps(config_dependency_data)) raise ProjectError(f"No installed dependency API that supports '{dep_id}'.")
def get_project( self, path: Path, contracts_folder: Optional[Path] = None, name: Optional[str] = None, version: Optional[str] = None, ) -> ProjectAPI: """ Get the project at the given path. Returns the first :class:`~ape.api.projects.ProjectAPI` it finds where it is valid. Args: path (pathlib.Path): The path to the project. contracts_folder (pathlib.Path): The path to the contracts folder. Defaults to ``<path>/contracts``. name (str): The name of the project. Only necessary when this project is a dependency. Defaults to ``None``. version (str): The project's version. Only necessary when this project is a dependency. Defaults to ``None``. Returns: :class:`~ape.api.projects.ProjectAPI` """ def _try_create_project( proj_cls: Type[ProjectAPI]) -> Optional[ProjectAPI]: with self.config_manager.using_project( path, contracts_folder=contracts_folder): proj = proj_cls( contracts_folder=contracts_folder, name=name, path=path, version=version, ) # type: ignore if proj.is_valid: return proj return None project_plugin_types = [ pt for pt in self.project_types if not issubclass(pt, ApeProject) ] for project_cls in project_plugin_types: project = _try_create_project(project_cls) if project: return project # Try 'ApeProject' last, in case there was a more specific one earlier. ape_project = _try_create_project(ApeProject) if ape_project: return ape_project raise ProjectError( f"'{self.path.name}' is not recognized as a project.")
def get_repo(self, repo_path: str) -> GithubRepository: """ Get a repository from GitHub. Args: repo_path (str): The path to the repository, such as ``OpenZeppelin/openzeppelin-contracts``. Returns: github.Repository.Repository """ if repo_path not in self._repo_cache: try: self._repo_cache[repo_path] = self._client.get_repo(repo_path) return self._repo_cache[repo_path] except UnknownObjectException as err: raise ProjectError( f"Unknown repository '{repo_path}'") from err else: return self._repo_cache[repo_path]
def path(self) -> Path: given_path = Path(self.local) if not given_path.exists(): raise ProjectError(f"No project exists at path '{given_path}'.") return given_path