Exemplo n.º 1
0
    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}'."
            )
Exemplo n.º 2
0
    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
Exemplo n.º 3
0
    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}'.")
Exemplo n.º 4
0
    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}'.")
Exemplo n.º 5
0
    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.")
Exemplo n.º 6
0
    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]
Exemplo n.º 7
0
    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