Skip to content

Commit

Permalink
Implement get_commit_comment method and refactor CommitComment (#865)
Browse files Browse the repository at this point in the history
Implement get_commit_comment method and refactor CommitComment

Make the CommitComment inherit from Comment directly to share the common functionality (e.g. adding emojis).
Needed for packit/packit-service#2589
RELEASE NOTES BEGIN
There is a new method for getting a single commit comment, supporting also retrieval and adding reactions in GitHub.
RELEASE NOTES END

Reviewed-by: Matej Focko
  • Loading branch information
softwarefactory-project-zuul[bot] authored Oct 22, 2024
2 parents fb44e4c + f4889b9 commit b589984
Show file tree
Hide file tree
Showing 11 changed files with 1,725 additions and 20 deletions.
24 changes: 20 additions & 4 deletions ogr/abstract.py
Original file line number Diff line number Diff line change
Expand Up @@ -1031,18 +1031,21 @@ def edited(self) -> datetime.datetime:
raise NotImplementedError()


class CommitComment(OgrAbstractClass):
class CommitComment(Comment):
"""
Attributes:
sha (str): Hash of the related commit.
body (str): Body of the comment.
author (str): Login of the author.
"""

def __init__(self, sha: str, body: str, author: str) -> None:
def __init__(
self,
sha: str,
raw_comment: Any,
) -> None:
super().__init__(raw_comment=raw_comment)
self.sha = sha
self.body = body
self.author = author

@property # type: ignore
@deprecate_and_set_removal(
Expand Down Expand Up @@ -1875,6 +1878,19 @@ def get_commit_comments(self, commit: str) -> list[CommitComment]:
"""
raise NotImplementedError()

def get_commit_comment(self, commit_sha: str, comment_id: int) -> CommitComment:
"""
Get commit comment.
Args:
commit_sha: SHA of the commit
comment_id: ID of the commit comment
Returns:
Object representing the commit comment.
"""
raise NotImplementedError()

def set_commit_status(
self,
commit: str,
Expand Down
2 changes: 1 addition & 1 deletion ogr/read_only.py
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ def commit_comment(
commit: str,
body: str,
) -> "CommitComment":
return CommitComment(sha=commit, body=body, author=cls.author)
return CommitComment(sha=commit, raw_comment=original_object)

@classmethod
def set_commit_status(
Expand Down
14 changes: 12 additions & 2 deletions ogr/services/github/comments.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@
import datetime
from typing import Union

from github.CommitComment import CommitComment as _GithubCommitComment
from github.IssueComment import IssueComment as _GithubIssueComment
from github.PullRequestComment import PullRequestComment as _GithubPullRequestComment
from github.Reaction import Reaction as _Reaction

from ogr.abstract import Comment, IssueComment, PRComment, Reaction
from ogr.abstract import Comment, CommitComment, IssueComment, PRComment, Reaction


class GithubReaction(Reaction):
Expand All @@ -24,7 +25,11 @@ def delete(self) -> None:
class GithubComment(Comment):
def _from_raw_comment(
self,
raw_comment: Union[_GithubIssueComment, _GithubPullRequestComment],
raw_comment: Union[
_GithubIssueComment,
_GithubPullRequestComment,
_GithubCommitComment,
],
) -> None:
self._raw_comment = raw_comment
self._id = raw_comment.id
Expand Down Expand Up @@ -60,3 +65,8 @@ def __str__(self) -> str:
class GithubPRComment(GithubComment, PRComment):
def __str__(self) -> str:
return "Github" + super().__str__()


class GithubCommitComment(GithubComment, CommitComment):
def __str__(self) -> str:
return "Github" + super().__str__()
15 changes: 10 additions & 5 deletions ogr/services/github/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import github
from github import UnknownObjectException
from github.Commit import Commit
from github.CommitComment import CommitComment as GithubCommitComment
from github.CommitComment import CommitComment as _GithubCommitComment
from github.GithubException import GithubException
from github.Repository import Repository

Expand All @@ -34,6 +34,7 @@
GithubCheckRunResult,
GithubCheckRunStatus,
)
from ogr.services.github.comments import GithubCommitComment
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 @@ -345,11 +346,10 @@ def commit_comment(

@staticmethod
def _commit_comment_from_github_object(
raw_commit_coment: GithubCommitComment,
raw_commit_coment: _GithubCommitComment,
) -> CommitComment:
return CommitComment(
body=raw_commit_coment.body,
author=raw_commit_coment.user.login,
return GithubCommitComment(
raw_comment=raw_commit_coment,
sha=raw_commit_coment.commit_id,
)

Expand All @@ -360,6 +360,11 @@ def get_commit_comments(self, commit: str) -> list[CommitComment]:
for comment in github_commit.get_comments()
]

def get_commit_comment(self, commit_sha: str, comment_id: int) -> CommitComment:
return self._commit_comment_from_github_object(
self.github_repo.get_comment(comment_id),
)

@if_readonly(
return_function=GitProjectReadOnly.set_commit_status,
log_message="Create a status on a commit",
Expand Down
51 changes: 47 additions & 4 deletions ogr/services/gitlab/comments.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,25 @@

import gitlab.exceptions
from gitlab.v4.objects import (
ProjectCommitComment,
ProjectCommitDiscussionNote,
ProjectIssueNote,
ProjectIssueNoteAwardEmoji,
ProjectMergeRequestAwardEmoji,
ProjectMergeRequestNote,
)

from ogr.abstract import Comment, IssueComment, PRComment, Reaction
from ogr.exceptions import GitlabAPIException
from ogr.abstract import Comment, CommitComment, IssueComment, PRComment, Reaction
from ogr.exceptions import GitlabAPIException, OperationNotSupported

logger = logging.getLogger(__name__)


class GitlabReaction(Reaction):
_raw_reaction: Union[ProjectIssueNoteAwardEmoji, ProjectMergeRequestAwardEmoji]
_raw_reaction: Union[
ProjectIssueNoteAwardEmoji,
ProjectMergeRequestAwardEmoji,
]

def __str__(self) -> str:
return "Gitlab" + super().__str__()
Expand All @@ -32,7 +37,12 @@ def delete(self) -> None:
class GitlabComment(Comment):
def _from_raw_comment(
self,
raw_comment: Union[ProjectIssueNote, ProjectMergeRequestNote],
raw_comment: Union[
ProjectIssueNote,
ProjectMergeRequestNote,
ProjectCommitDiscussionNote,
ProjectCommitComment,
],
) -> None:
self._raw_comment = raw_comment
self._id = raw_comment.get_id()
Expand Down Expand Up @@ -94,3 +104,36 @@ def __str__(self) -> str:
class GitlabPRComment(GitlabComment, PRComment):
def __str__(self) -> str:
return "Gitlab" + super().__str__()


class GitlabCommitComment(GitlabComment, CommitComment):
def __str__(self) -> str:
return "Gitlab" + super().__str__()

@property
def body(self) -> str:
# TODO: ideally, the raw comment should be of the same type for both
# individual and all comments retrievals, this comes from the
# Gitlab API inconsistency (see get_commit_comment vs get_commit_comments)
if isinstance(self._raw_comment, ProjectCommitComment):
return self._raw_comment.note

return self._raw_comment.body

@body.setter
def body(self, new_body: str) -> None:
if isinstance(self._raw_comment, ProjectCommitComment):
self._raw_comment.note = new_body
else:
self._raw_comment.body = new_body
self._raw_comment.save()

def get_reactions(self) -> list[Reaction]:
raise OperationNotSupported(
"Interacting with award emojis on commit comments is not supported via API.",
)

def add_reaction(self, reaction: str) -> GitlabReaction:
raise OperationNotSupported(
"Interacting with award emojis on commit comments is not supported via API.",
)
40 changes: 36 additions & 4 deletions ogr/services/gitlab/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
from ogr.exceptions import GitlabAPIException, OperationNotSupported
from ogr.services import gitlab as ogr_gitlab
from ogr.services.base import BaseGitProject
from ogr.services.gitlab.comments import GitlabCommitComment
from ogr.services.gitlab.flag import GitlabCommitFlag
from ogr.services.gitlab.issue import GitlabIssue
from ogr.services.gitlab.pull_request import GitlabPullRequest
Expand Down Expand Up @@ -294,11 +295,10 @@ def commit_comment(
return self._commit_comment_from_gitlab_object(raw_comment, commit)

@staticmethod
def _commit_comment_from_gitlab_object(raw_comment, commit) -> CommitComment:
return CommitComment(
def _commit_comment_from_gitlab_object(raw_comment, commit: str) -> CommitComment:
return GitlabCommitComment(
raw_comment=raw_comment,
sha=commit,
body=raw_comment.note,
author=raw_comment.author["username"],
)

def get_commit_comments(self, commit: str) -> list[CommitComment]:
Expand All @@ -313,6 +313,38 @@ def get_commit_comments(self, commit: str) -> list[CommitComment]:
for comment in commit_object.comments.list()
]

def get_commit_comment(self, commit_sha: str, comment_id: int) -> CommitComment:
try:
commit_object: ProjectCommit = self.gitlab_repo.commits.get(commit_sha)
except gitlab.exceptions.GitlabGetError as ex:
logger.error(f"Commit with SHA {commit_sha} was not found: {ex}")
raise GitlabAPIException(
f"Commit with SHA {commit_sha} was not found.",
) from ex

try:
discussions = commit_object.discussions.list(all=True)
comment = None

for discussion in discussions:
note_ids = [note["id"] for note in discussion.attributes["notes"]]
if comment_id in note_ids:
comment = discussion.notes.get(comment_id)
break

if comment is None:
raise GitlabAPIException(
f"Comment with ID {comment_id} not found in commit {commit_sha}.",
)

except gitlab.exceptions.GitlabGetError as ex:
logger.error(f"Failed to retrieve comment with ID {comment_id}: {ex}")
raise GitlabAPIException(
f"Failed to retrieve comment with ID {comment_id}.",
) from ex

return self._commit_comment_from_gitlab_object(comment, commit_sha)

@indirect(GitlabCommitFlag.set)
def set_commit_status(
self,
Expand Down
3 changes: 3 additions & 0 deletions ogr/services/pagure/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -482,6 +482,9 @@ def commit_comment(
def get_commit_comments(self, commit: str) -> list[CommitComment]:
raise OperationNotSupported("Commit comments are not supported on Pagure.")

def get_commit_comment(self, commit_sha: str, comment_id: int) -> CommitComment:
raise OperationNotSupported("Commit comments are not supported on Pagure.")

@if_readonly(return_function=GitProjectReadOnly.set_commit_status)
@indirect(PagureCommitFlag.set)
def set_commit_status(
Expand Down
Loading

2 comments on commit b589984

@lbarcziova
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/packit-stg build

@lbarcziova
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/packit-stg build

Please sign in to comment.