示例#1
0
    def __handle_project_create_fail(self, exception: PagureAPIException,
                                     namespace: str) -> None:
        if (exception.pagure_response
                and exception.pagure_response["errors"]["namespace"][0]
                == "Not a valid choice"):
            request_url = self.get_api_url("group", namespace)

            try:
                self.call_api(request_url, data={"projects": False})
            except PagureAPIException:
                raise OgrException(f"Namespace doesn't exist ({namespace}).")

            raise OgrException(
                f"Cannot create project in given namespace (permissions).")

        raise exception
示例#2
0
    def get_fork(self, create: bool = True) -> Optional["PagureProject"]:
        """
        Provide GitProject instance of a fork of this project.

        Returns None if this is a fork.

        :param create: create a fork if it doesn't exist
        :return: instance of GitProject or None
        """
        if self.is_fork:
            raise OgrException("Cannot create fork from fork.")

        for fork in self.get_forks():
            fork_info = fork.get_project_info()
            if self._user in fork_info["user"]["name"]:
                return fork

        if not self.is_forked():
            if create:
                return self.fork_create()
            else:
                logger.info(
                    f"Fork of {self.repo}"
                    " does not exist and we were asked not to create it."
                )
                return None
        return self._construct_fork_project()
示例#3
0
def get_project(
    url,
    service_mapping_update: Dict[str, Type[GitService]] = None,
    custom_instances: List[GitService] = None,
    **kwargs,
) -> GitProject:
    """
    Return the project for the given url.

    :param url: str (url of the project, e.g. "https://github.com/packit-service/ogr")
    :param service_mapping_update: custom mapping from  service url (str) to service class
    :param custom_instances: list of instances that will be used when creating a project instance
    :param kwargs: arguments forwarded to __init__ of the matching service
    :return: GitProject using the matching implementation
    """
    kls = get_service_class(url=url,
                            service_mapping_update=service_mapping_update)

    if custom_instances:
        for service_inst in custom_instances:
            if isinstance(service_inst,
                          kls) and service_inst.instance_url in url:
                service = service_inst
                break
        else:
            raise OgrException(
                f"Instance of type {kls.__name__} "
                f"matching instance url '{url}' was not provided.")
    else:
        repo_url = parse_git_repo(potential_url=url)
        service = kls(instance_url=repo_url.get_instance_url(), **kwargs)
    project = service.get_project_from_url(url=url)
    return project
示例#4
0
文件: tokman.py 项目: mmuzila/ogr
    def get_token(self, namespace: str, repo: str) -> str:
        response = requests.get(f"{self._instance_url}/api/{namespace}/{repo}")

        if not response.ok:
            raise OgrException(
                f"Couldn't retrieve token from Tokman: ({response.status_code}) {response.text}"
            )

        return response.json().get("access_token", None)
示例#5
0
文件: factory.py 项目: packit/ogr
def get_project(
    url,
    service_mapping_update: Dict[str, Type[GitService]] = None,
    custom_instances: Iterable[GitService] = None,
    force_custom_instance: bool = True,
    **kwargs,
) -> GitProject:
    """
    Return the project for the given URL.

    Args:
        url: URL of the project, e.g. `"https://github.com/packit/ogr"`.
        service_mapping_update: Custom mapping from
            service url (`str`) to service class.

            Defaults to no mapping.
        custom_instances: List of instances that will be
            used when creating a project instance.

            Defaults to `None`.
        force_custom_instance: Force picking a Git service from the
            `custom_instances` list, if there is any provided, raise an error if
            that is not possible.

            Defaults to `True`.
        **kwargs: Arguments forwarded to __init__ of the matching service.

    Returns:
        `GitProject` using the matching implementation.
    """
    mapping = service_mapping_update.copy() if service_mapping_update else {}
    custom_instances = custom_instances or []
    for instance in custom_instances:
        mapping[instance.instance_url] = instance.__class__

    kls = get_service_class(url=url, service_mapping_update=mapping)
    parsed_repo_url = parse_git_repo(url)

    service = None
    if custom_instances:
        for service_inst in custom_instances:
            if (isinstance(service_inst, kls)
                    and service_inst.hostname == parsed_repo_url.hostname):
                service = service_inst
                break
        else:
            if force_custom_instance:
                raise OgrException(
                    f"Instance of type {kls.__name__} "
                    f"matching instance url '{url}' was not provided.")
    if not service:
        service = kls(instance_url=parsed_repo_url.get_instance_url(),
                      **kwargs)
    return service.get_project_from_url(url=url)
示例#6
0
    def private_key(self) -> str:
        if self._private_key:
            return self._private_key

        if self._private_key_path:
            if not Path(self._private_key_path).is_file():
                raise OgrException(f"File with the github-app private key "
                                   f"({self._private_key_path}) "
                                   f"does not exist.")
            return Path(self._private_key_path).read_text()

        return None
示例#7
0
    def get_project_from_url(self, url: str) -> "GitProject":
        """
        Args:
            url: URL of the git repository.

        Returns:
            Object that represents project from the parsed URL.
        """
        repo_url = parse_git_repo(potential_url=url)
        if not repo_url:
            raise OgrException(f"Failed to find repository for url: {url}")
        return self.get_project(repo=repo_url.repo,
                                namespace=repo_url.namespace)
示例#8
0
文件: service.py 项目: packit/ogr
    def get_project_from_url(self, url: str) -> "PagureProject":
        repo_url = parse_git_repo(potential_url=url)
        if not repo_url:
            raise OgrException(f"Cannot parse project url: '{url}'")

        if not repo_url.is_fork:
            repo_url.username = None

        project = self.get_project(
            repo=repo_url.repo,
            namespace=repo_url.namespace,
            is_fork=repo_url.is_fork,
            username=repo_url.username,
        )
        return project
示例#9
0
def get_service_class(
    url: str,
    service_mapping_update: Dict[str, Type[GitService]] = None
) -> Type[GitService]:
    """
    Get the matching service class from the url.

    :param url: str (url of the project, e.g. "https://github.com/packit-service/ogr")
    :param service_mapping_update: custom mapping from  service url (str) to service class
    :return: Matched class (subclass of GitService)
    """
    service_kls = get_service_class_or_none(
        url=url, service_mapping_update=service_mapping_update)
    if service_kls:
        return service_kls
    raise OgrException("No matching service was found.")
示例#10
0
文件: project.py 项目: packit/ogr
    def get_fork(self, create: bool = True) -> Optional["PagureProject"]:
        if self.is_fork:
            raise OgrException("Cannot create fork from fork.")

        for fork in self.get_forks():
            fork_info = fork.get_project_info()
            if self._user in fork_info["user"]["name"]:
                return fork

        if not self.is_forked():
            if create:
                return self.fork_create()
            else:
                logger.info(
                    f"Fork of {self.repo}"
                    " does not exist and we were asked not to create it.")
                return None
        return self._construct_fork_project()
示例#11
0
def get_project(
    url,
    service_mapping_update: Dict[str, Type[GitService]] = None,
    custom_instances: Iterable[GitService] = None,
    force_custom_instance: bool = True,
    **kwargs,
) -> GitProject:
    """
    Return the project for the given url.

    :param url: str (url of the project, e.g. "https://github.com/packit/ogr")
    :param service_mapping_update: custom mapping from  service url (str) to service class
    :param custom_instances: list of instances that will be used when creating a project instance
    :param force_custom_instance: force picking a Git service from the custom_instances list,
        if there is any provided, raise an error if that's not possible
    :param kwargs: arguments forwarded to __init__ of the matching service
    :return: GitProject using the matching implementation
    """
    mapping = service_mapping_update.copy() if service_mapping_update else {}
    custom_instances = custom_instances or []
    for instance in custom_instances:
        mapping[instance.instance_url] = instance.__class__

    kls = get_service_class(url=url, service_mapping_update=mapping)
    parsed_repo_url = parse_git_repo(url)

    service = None
    if custom_instances:
        for service_inst in custom_instances:
            if (
                isinstance(service_inst, kls)
                and service_inst.hostname == parsed_repo_url.hostname
            ):
                service = service_inst
                break
        else:
            if force_custom_instance:
                raise OgrException(
                    f"Instance of type {kls.__name__} "
                    f"matching instance url '{url}' was not provided."
                )
    if not service:
        service = kls(instance_url=parsed_repo_url.get_instance_url(), **kwargs)
    return service.get_project_from_url(url=url)
示例#12
0
文件: factory.py 项目: yzhang2907/ogr
def get_service_class(
    url: str, service_mapping_update: Dict[str, Type[GitService]] = None
) -> Type[GitService]:
    """
    Get the matching service class from the url.

    :param url: str (url of the project, e.g. "https://github.com/packit-service/ogr")
    :param service_mapping_update: custom mapping from  service url (str) to service class
    :return: Matched class (subclass of GitService)
    """
    mapping = {}
    mapping.update(_SERVICE_MAPPING)
    if service_mapping_update:
        mapping.update(service_mapping_update)

    for service, service_kls in mapping.items():
        if service in url:
            return service_kls
    raise OgrException("No matching service was found.")
示例#13
0
    def get_token(self, namespace: str, repo: str) -> str:
        if not self.private_key:
            return None

        inst_id = self.integration.get_installation(namespace, repo).id
        # PyGithub<1.52 returned an object for id, with a value attribute,
        # which was None or an ID.
        # This was changed in:
        # https://github.com/PyGithub/PyGithub/commit/61808da15e8e3bcb660acd0e7947326a4a6c0c7a#diff-b8f1ee87df332916352809a397ea259aL54
        # 'id' is now None or an ID.
        inst_id = (inst_id if isinstance(inst_id, int) or inst_id is None else
                   inst_id.value)
        if not inst_id:
            raise OgrException(
                f"No installation ID provided for {namespace}/{repo}: "
                "please make sure that you provided correct credentials of your GitHub app."
            )
        inst_auth = self.integration.get_access_token(inst_id)
        return inst_auth.token
示例#14
0
    def github_instance(self):
        if not self._github_instance:
            if self.service.github_app_id and self.service.github_app_private_key:
                integration = GithubIntegration(
                    self.service.github_app_id,
                    self.service.github_app_private_key)
                inst_id = integration.get_installation(self.namespace,
                                                       self.repo).id.value
                if not inst_id:
                    raise OgrException(
                        f"No installation ID provided for {self.namespace}/{self.repo}: "
                        "please make sure that you provided correct credentials of your GitHub app."
                    )
                inst_auth = integration.get_access_token(inst_id)
                self._github_instance = github.Github(
                    login_or_token=inst_auth.token)
            else:
                self._github_instance = self.service.github

        return self._github_instance
示例#15
0
文件: factory.py 项目: packit/ogr
def get_service_class(
    url: str,
    service_mapping_update: Dict[str, Type[GitService]] = None
) -> Type[GitService]:
    """
    Get the matching service class from the URL.

    Args:
        url: URL of the project, e.g. `"https://github.com/packit/ogr"`.
        service_mapping_update: Custom mapping from service url (str) to service
            class.

            Defaults to `None`.

    Returns:
        Matched class (subclass of `GitService`).
    """
    service_kls = get_service_class_or_none(
        url=url, service_mapping_update=service_mapping_update)
    if service_kls:
        return service_kls
    raise OgrException("No matching service was found.")
示例#16
0
    def project_create(
        self,
        repo: str,
        namespace: Optional[str] = None,
        description: Optional[str] = None,
    ) -> PagureProject:
        request_url = self.get_api_url("new")

        parameters = {"name": repo, "description": description, "wait": True}
        if not description:
            parameters["description"] = repo
        if namespace:
            parameters["namespace"] = namespace

        try:
            self.call_api(request_url, "POST", data=parameters)
        except PagureAPIException as ex:
            if (ex.pagure_response
                    and ex.pagure_response["errors"]["namespace"][0]
                    == "Not a valid choice"):
                raise OgrException(
                    f"Cannot create project in given namespace ({namespace}).")
            raise ex
        return PagureProject(repo=repo, namespace=namespace, service=self)
示例#17
0
 def get_project_from_url(self, url: str) -> "GitProject":
     repo_url = parse_git_repo(potential_url=url)
     if not repo_url:
         raise OgrException(f"Failed to find repository for url: {url}")
     return self.get_project(repo=repo_url.repo,
                             namespace=repo_url.namespace)
示例#18
0
 def get_project_from_url(self, url: str) -> "GitProject":
     repo_url = parse_git_repo(potential_url=url)
     if not repo_url:
         raise OgrException(f"Cannot parse project url: '{url}'")
     return self.get_project(repo=repo_url.repo,
                             namespace=repo_url.namespace)
示例#19
0
文件: factory.py 项目: packit/ogr
def get_instances_from_dict(instances: Dict) -> Set[GitService]:
    """
    Load the service instances from the dictionary in the following form:

    - `key`   : hostname, url or name that can be mapped to the service-type
    - `value` : dictionary with arguments used when creating a new instance of the
    service (passed to the `__init__` method)

    e.g.:
    ```py
    get_instances_from_dict({
        "github.com": {"token": "abcd"},
        "pagure": {
            "token": "abcd",
            "instance_url": "https://src.fedoraproject.org",
        },
    }) == {
        GithubService(token="abcd"),
        PagureService(token="abcd", instance_url="https://src.fedoraproject.org")
    }
    ```

    When the mapping `key->service-type` is not recognised, you can add a `type`
    key to the dictionary and specify the type of the instance.
    (It can be either name, hostname or url. The used mapping is same as for
    key->service-type.)

    The provided `key` is used as an `instance_url` and passed to the `__init__`
    method as well.

    e.g.:
    ```py
    get_instances_from_dict({
        "https://my.gtlb": {"token": "abcd", "type": "gitlab"},
    }) == {GitlabService(token="abcd", instance_url="https://my.gtlb")}
    ```

    Args:
        instances: Mapping from service name/url/hostname to attributes for the
            service creation.

    Returns:
        Set of the service instances.
    """
    services = set()
    for key, value in instances.items():
        service_kls = get_service_class_or_none(url=key)
        if not service_kls:
            if "type" not in value:
                raise OgrException(
                    f"No matching service was found for url '{key}'. "
                    f"Add the service name as a `type` attribute.")
            service_type = value["type"]
            if service_type not in _SERVICE_MAPPING:
                raise OgrException(
                    f"No matching service was found for type '{service_type}'."
                )

            service_kls = _SERVICE_MAPPING[service_type]
            value.setdefault("instance_url", key)
            del value["type"]

        service_instance = service_kls(**value)
        services.add(service_instance)

    return services