Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions COMPATIBILITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,14 @@ In case you find any error, please [create a new issue](https://github.com/packi
| ----------------- | :----: | :----: | :----: | :-----: |
| `add_label` | ✔ | ✔ | ✘ | ✔ |
| `get_all_commits` | ✔ | ✔ | ✘ | ✔ |
| `changes` | ✔ | ✘ | ✘ | ✘ |

## GitCommit

| | GitHub | GitLab | Pagure | Forgejo |
| --------- | :----: | :----: | :----: | :-----: |
| `changes` | ✔ | ✘ | ✘ | ✘ |
| `get_prs` | ✘ | ✘ | ✘ | ✘ |

## Release

Expand Down Expand Up @@ -63,6 +71,7 @@ In case you find any error, please [create a new issue](https://github.com/packi
| `which_groups_can_merge_pr` | ✘ | ✘ | ✔ | ✘ |
| `get_pr_files_diff` | ✘ | ✘ | ✔ | ✘ |
| `get_users_with_given_access` | ✘ | ✘ | ✔ | ✔ |
| `get_commit` | ✔ | ✘ | ✘ | ✘ |

## User

Expand Down
2 changes: 2 additions & 0 deletions ogr/abstract/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
PRComment,
Reaction,
)
from ogr.abstract.commit import GitCommit
from ogr.abstract.commit_flag import CommitFlag
from ogr.abstract.git_project import GitProject
from ogr.abstract.git_service import GitService
Expand All @@ -34,6 +35,7 @@
PRComment.__name__,
Reaction.__name__,
CommitFlag.__name__,
GitCommit.__name__,
GitProject.__name__,
GitService.__name__,
GitTag.__name__,
Expand Down
80 changes: 80 additions & 0 deletions ogr/abstract/commit.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# Copyright Contributors to the Packit project.
# SPDX-License-Identifier: MIT

from collections.abc import Iterable
from typing import Any, Union

from ogr import abstract as _abstract
from ogr.abstract.abstract_class import OgrAbstractClass
from ogr.abstract.git_project import GitProject


class GitCommit(OgrAbstractClass):
"""
Class representing a git commit

Attributes:
project (GitProject): Git project where the commit belongs to.
"""

def __init__(self, raw_commit: Any, project: "GitProject") -> None:
self._raw_commit = raw_commit
self.project = project

@property
def sha(self) -> str:
"""Commit hash."""
raise NotImplementedError()

@property
def changes(self) -> "CommitChanges":
"""Commit change information."""
raise NotImplementedError()

def get_prs(self) -> Iterable["_abstract.PullRequest"]:
"""Get the associated pull requests"""
raise NotImplementedError()


class CommitLikeChanges(OgrAbstractClass):
"""
Class representing a commit-like changes.

Can be from a single commit or aggregated like from a PR.
"""

@property
def parent(self) -> Union["GitCommit", "_abstract.PullRequest"]:
"""Parent object containing the changes."""
raise NotImplementedError()

@property
def files(self) -> Union[list[str], Iterable[str]]:
"""Files changed by the current change."""
raise NotImplementedError()

@property
def patch(self) -> bytes:
"""Patch of the changes."""
raise NotImplementedError()

@property
def diff_url(self) -> str:
"""Web URL to the diff of the pull request."""
raise NotImplementedError()


class CommitChanges(CommitLikeChanges):
"""
Class representing a Commit's change

Attributes:
commit (GitCommit): Parent commit.
"""

def __init__(self, commit: "GitCommit") -> None:
self.commit = commit

@property
def parent(self) -> "GitCommit":
return self.commit
10 changes: 10 additions & 0 deletions ogr/abstract/git_project.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,16 @@ def default_branch(self) -> str:
"""Default branch (usually `main`, `master` or `trunk`)."""
raise NotImplementedError()

def get_commit(self, sha: str) -> "_abstract.GitCommit":
"""
Get a specific commit information.

Args:
sha: Specific sha of the commit

"""
raise NotImplementedError()

def get_commits(self, ref: Optional[str] = None) -> Union[list[str], Iterable[str]]:
"""
Get list of commits for the project.
Expand Down
22 changes: 22 additions & 0 deletions ogr/abstract/pull_request.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

from ogr import abstract as _abstract
from ogr.abstract.abstract_class import OgrAbstractClass
from ogr.abstract.commit import CommitLikeChanges
from ogr.abstract.commit_flag import CommitFlag
from ogr.abstract.git_project import GitProject
from ogr.abstract.status import MergeCommitStatus, PRStatus
Expand Down Expand Up @@ -81,6 +82,11 @@ def labels(self) -> Union[list["_abstract.PRLabel"], Iterable["_abstract.PRLabel
"""Labels of the pull request."""
raise NotImplementedError()

@property
def changes(self) -> "PullRequestChanges":
"""Commit-like change information."""
raise NotImplementedError()

@property
def diff_url(self) -> str:
"""Web URL to the diff of the pull request."""
Expand Down Expand Up @@ -381,3 +387,19 @@ def get_comment(self, comment_id: int) -> "_abstract.PRComment":
Object representing a PR comment.
"""
raise NotImplementedError()


class PullRequestChanges(CommitLikeChanges):
"""
Class representing a PullRequest's changes

Attributes:
pull_request (PullRequest): Parent pull request.
"""

def __init__(self, pull_request: "PullRequest") -> None:
self.pull_request = pull_request

@property
def parent(self) -> "PullRequest":
return self.pull_request
5 changes: 5 additions & 0 deletions ogr/services/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from ogr.abstract import (
CommitFlag,
CommitStatus,
GitCommit,
GitProject,
GitService,
GitUser,
Expand Down Expand Up @@ -86,6 +87,10 @@ def get_statuses(self) -> Union[list[CommitFlag], Iterable[CommitFlag]]:
return self.target_project.get_commit_statuses(commit)


class BaseGitCommit(GitCommit):
pass


class BaseGitUser(GitUser):
pass

Expand Down
2 changes: 2 additions & 0 deletions ogr/services/github/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

from ogr.services.github.check_run import GithubCheckRun
from ogr.services.github.comments import GithubIssueComment, GithubPRComment
from ogr.services.github.commit import GithubCommit
from ogr.services.github.issue import GithubIssue
from ogr.services.github.project import GithubProject
from ogr.services.github.pull_request import GithubPullRequest
Expand All @@ -12,6 +13,7 @@

__all__ = [
GithubCheckRun.__name__,
GithubCommit.__name__,
GithubPullRequest.__name__,
GithubIssueComment.__name__,
GithubPRComment.__name__,
Expand Down
66 changes: 66 additions & 0 deletions ogr/services/github/commit.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# Copyright Contributors to the Packit project.
# SPDX-License-Identifier: MIT
from collections.abc import Iterable

import github
import requests
from github.Commit import Commit as _GitCommit

from ogr.abstract.commit import CommitChanges
from ogr.exceptions import GithubAPIException, OgrNetworkError
from ogr.services import github as ogr_github
from ogr.services.base import BaseGitCommit
from ogr.services.github.pull_request import GithubPullRequest


class GithubCommit(BaseGitCommit):
_raw_commit: _GitCommit
_changes: "GithubCommitChanges" = None

@property
def sha(self) -> str:
return self._raw_commit.sha

@property
def changes(self) -> "GithubCommitChanges":
if not self._changes:
self._changes = GithubCommitChanges(self)
return self._changes

def get_prs(self) -> Iterable[GithubPullRequest]:
for pr in self._raw_commit.get_pulls():
yield GithubPullRequest(pr, self.project)

@staticmethod
def get(project: "ogr_github.GithubProject", sha: str) -> "GithubCommit":
try:
commit = project.github_repo.get_commit(sha=sha)
except github.UnknownObjectException as ex:
raise GithubAPIException(f"No git commit with id {sha} found") from ex
return GithubCommit(commit, project)


class GithubCommitChanges(CommitChanges):
commit: "ogr_github.GithubCommit"

@property
def files(self) -> Iterable[str]:
for file in self.commit._raw_commit.files:
yield file.filename

@property
def patch(self) -> bytes:
patch_url = f"{self.commit._raw_commit.html_url}.patch"
response = requests.get(patch_url)

if not response.ok:
cls = OgrNetworkError if response.status_code >= 500 else GithubAPIException
raise cls(
f"Couldn't get patch from {patch_url} because {response.reason}.",
)

return response.content

@property
def diff_url(self) -> str:
return f"{self.commit._raw_commit.html_url}.diff"
6 changes: 6 additions & 0 deletions ogr/services/github/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
CommitComment,
CommitFlag,
CommitStatus,
GitCommit,
GitTag,
Issue,
IssueStatus,
Expand All @@ -35,6 +36,7 @@
GithubCheckRunStatus,
)
from ogr.services.github.comments import GithubCommitComment
from ogr.services.github.commit import GithubCommit
from ogr.services.github.flag import GithubCommitFlag
from ogr.services.github.issue import GithubIssue
from ogr.services.github.pull_request import GithubPullRequest
Expand Down Expand Up @@ -301,6 +303,10 @@ def get_pr_list(self, status: PRStatus = PRStatus.open) -> list[PullRequest]:
def get_pr(self, pr_id: int) -> PullRequest:
pass

@indirect(GithubCommit.get)
def get_commit(self, sha: str) -> GitCommit:
pass

def get_sha_from_tag(self, tag_name: str) -> str:
# TODO: This is ugly. Can we do it better?
all_tags = self.github_repo.get_tags()
Expand Down
34 changes: 34 additions & 0 deletions ogr/services/github/pull_request.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from github.Repository import Repository as _GithubRepository

from ogr.abstract import MergeCommitStatus, PRComment, PRLabel, PRStatus, PullRequest
from ogr.abstract.pull_request import PullRequestChanges
from ogr.exceptions import GithubAPIException, OgrNetworkError
from ogr.services import github as ogr_github
from ogr.services.base import BasePullRequest
Expand All @@ -28,6 +29,7 @@ class GithubPullRequest(BasePullRequest):
_raw_pr: _GithubPullRequest
_target_project: "ogr_github.GithubProject"
_source_project: "ogr_github.GithubProject" = None
_changes: "GithubPullRequestChanges" = None

@property
def title(self) -> str:
Expand Down Expand Up @@ -83,6 +85,12 @@ def labels(self) -> list[PRLabel]:
GithubPRLabel(raw_label, self) for raw_label in self._raw_pr.get_labels()
]

@property
def changes(self) -> "GithubPullRequestChanges":
if not self._changes:
self._changes = GithubPullRequestChanges(self)
return self._changes

@property
def diff_url(self) -> str:
return f"{self._raw_pr.html_url}/files"
Expand Down Expand Up @@ -268,3 +276,29 @@ def add_label(self, *labels: str) -> None:

def get_comment(self, comment_id: int) -> PRComment:
return GithubPRComment(self._raw_pr.get_issue_comment(comment_id))


class GithubPullRequestChanges(PullRequestChanges):
pull_request: "ogr_github.GithubPullRequest"

@property
def files(self) -> Iterable[str]:
for file in self.pull_request._raw_pr.get_files():
yield file.filename

@property
def patch(self) -> bytes:
patch_url = self.pull_request._raw_pr.patch_url
response = requests.get(patch_url)

if not response.ok:
cls = OgrNetworkError if response.status_code >= 500 else GithubAPIException
raise cls(
f"Couldn't get patch from {patch_url} because {response.reason}.",
)

return response.content

@property
def diff_url(self) -> str:
return f"{self.pull_request._raw_pr.html_url}.diff"
Loading
Loading