diff --git a/ogr/abstract.py b/ogr/abstract.py index dea00865a..3d379e5e9 100644 --- a/ogr/abstract.py +++ b/ogr/abstract.py @@ -477,6 +477,13 @@ def get_comments( """ raise NotImplementedError() + def who_can_close() -> set[str]: + """ + Returns: + Set of usernames who can close the issue. + """ + raise NotImplementedError() + def can_close(self, username: str) -> bool: """ Check if user have permissions to modify an issue. @@ -889,6 +896,34 @@ def close(self) -> "PullRequest": """ raise NotImplementedError() + def who_can_close() -> set[str]: + """ + Returns: + Set of usernames who can close the pull request. + """ + raise NotImplementedError() + + def who_can_merge() -> set[str]: + """ + Returns: + Set of usernames who can merge the pull request. + """ + raise NotImplementedError() + + def can_close(self, username: str) -> bool: + """ + Returns: + `True` if user can close the pull request, `False` otherwise. + """ + raise NotImplementedError() + + def can_merge(self, username: str) -> bool: + """ + Returns: + `True` if user can merge the pull request, `False` otherwise. + """ + raise NotImplementedError() + def merge(self) -> "PullRequest": """ Merge the pull request. @@ -1536,6 +1571,16 @@ def who_can_close_issue(self) -> set[str]: """ raise NotImplementedError() + def can_close_issue(username: str) -> bool: + """ + Args: + username: Login of the user. + + Returns: + `True` if user can close the issue, `False` otherwise. + """ + raise NotImplementedError() + def who_can_merge_pr(self) -> set[str]: """ Returns: diff --git a/ogr/services/base.py b/ogr/services/base.py index 6c89637e7..4cdfede5e 100644 --- a/ogr/services/base.py +++ b/ogr/services/base.py @@ -46,6 +46,12 @@ class BaseGitProject(GitProject): def full_repo_name(self) -> str: return f"{self.namespace}/{self.repo}" + def can_close_issue(self, username: str) -> bool: + return username in self.who_can_close_issue() + + def can_merge_pr(self, username: str) -> bool: + return username in self.who_can_merge_pr() + class BasePullRequest(PullRequest): @property @@ -81,6 +87,12 @@ def get_statuses(self) -> list[CommitFlag]: commit = self.get_all_commits()[-1] return self.target_project.get_commit_statuses(commit) + def can_close(self, username): + return self.status == "open" and username in self.who_can_close() + + def can_merge(self, username) -> bool: + return self.status == "open" and username in self.who_can_merge() + class BaseGitUser(GitUser): pass @@ -97,7 +109,7 @@ def get_comments( return filter_comments(all_comments, filter_regex, reverse, author) def can_close(self, username: str) -> bool: - return username == self.author or username in self.project.who_can_close_issue() + return username == self.author or username in self.who_can_close() class BaseCommitFlag(CommitFlag): diff --git a/ogr/services/github/issue.py b/ogr/services/github/issue.py index 00a452cc8..a6e37afa0 100644 --- a/ogr/services/github/issue.py +++ b/ogr/services/github/issue.py @@ -167,6 +167,12 @@ def close(self) -> "Issue": self._raw_issue.edit(state="closed") return self + def who_can_close(self) -> set[str]: + return self.project.who_can_close_issue() + + def can_close(self, username): + return username == self.author or username in self.who_can_close() + def add_label(self, *labels: str) -> None: for label in labels: self._raw_issue.add_to_labels(label) diff --git a/ogr/services/github/project.py b/ogr/services/github/project.py index 9e263c280..323064752 100644 --- a/ogr/services/github/project.py +++ b/ogr/services/github/project.py @@ -240,6 +240,9 @@ def who_can_close_issue(self) -> set[str]: def who_can_merge_pr(self) -> set[str]: return self.__get_collaborators() + def can_close_issue(self, username: str) -> bool: + return username in self.who_can_close_issue() + def can_merge_pr(self, username) -> bool: return ( self.github_repo.get_collaborator_permission(username) diff --git a/ogr/services/github/pull_request.py b/ogr/services/github/pull_request.py index 80b43e870..d64d3c807 100644 --- a/ogr/services/github/pull_request.py +++ b/ogr/services/github/pull_request.py @@ -260,3 +260,25 @@ 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)) + + def who_can_close(self) -> set[str]: + people_who_can_close: set[str] = set() + + people_who_can_close.add(self.author) + project = self._target_project + people_who_can_close.update(project.__get_collaborators()) + + return people_who_can_close + + def can_close(self, username): + return username == self.author or username in self.who_can_close() + + def who_can_merge(self) -> set[str]: + people_who_can_merge: set[str] = set() + project = self._target_project + people_who_can_merge.update(project.__get_collaborators()) + + return people_who_can_merge + + def can_merge(self, username): + return username in self.who_can_merge() diff --git a/ogr/services/gitlab/issue.py b/ogr/services/gitlab/issue.py index 3d2cd49df..43e784f7e 100644 --- a/ogr/services/gitlab/issue.py +++ b/ogr/services/gitlab/issue.py @@ -183,3 +183,6 @@ def add_assignee(self, *assignees: str) -> None: def get_comment(self, comment_id: int) -> IssueComment: return GitlabIssueComment(self._raw_issue.notes.get(comment_id)) + + def who_can_close(self) -> set[str]: + return self.project.who_can_close_issue() diff --git a/ogr/services/gitlab/project.py b/ogr/services/gitlab/project.py index 9cc08fb79..b72b07ada 100644 --- a/ogr/services/gitlab/project.py +++ b/ogr/services/gitlab/project.py @@ -184,6 +184,9 @@ def who_can_merge_pr(self) -> set[str]: ), ) + def can_close_issue(self, username): + return username in self.who_can_close_issue() + def can_merge_pr(self, username) -> bool: return username in self.who_can_merge_pr() diff --git a/ogr/services/gitlab/pull_request.py b/ogr/services/gitlab/pull_request.py index 0e5941e2e..6a98b6530 100644 --- a/ogr/services/gitlab/pull_request.py +++ b/ogr/services/gitlab/pull_request.py @@ -299,3 +299,25 @@ def add_label(self, *labels: str) -> None: def get_comment(self, comment_id: int) -> PRComment: return GitlabPRComment(self._raw_pr.notes.get(comment_id)) + + def who_can_close(self) -> set[str]: + people_who_can_close: set[str] = set() + people_who_can_close.add(self.author) + + project = self._target_project + people_who_can_close.update(set(project.get_owners())) + + return people_who_can_close + + def can_close(self, username): + return username in self.who_can_close() + + def who_can_merge(self) -> set[str]: + people_who_can_merge: set[str] = set() + project = self._target_project + people_who_can_merge.update(set(project.get_owners())) + + return people_who_can_merge + + def can_merge(self, username): + return username in self.who_can_merge() diff --git a/ogr/services/pagure/issue.py b/ogr/services/pagure/issue.py index 1fe6014eb..c06d7e595 100644 --- a/ogr/services/pagure/issue.py +++ b/ogr/services/pagure/issue.py @@ -241,3 +241,6 @@ def get_comment(self, comment_id: int) -> IssueComment: method="GET", ), ) + + def who_can_close_issue(self) -> set[str]: + return self.project.who_can_close_issue() diff --git a/ogr/services/pagure/project.py b/ogr/services/pagure/project.py index 703bc57b0..095d2881d 100644 --- a/ogr/services/pagure/project.py +++ b/ogr/services/pagure/project.py @@ -236,6 +236,9 @@ def which_groups_can_merge_pr(self) -> set[str]: groups.update(project["access_groups"]["commit"]) return groups + def can_close_issue(self, username): + return username in self.who_can_close_issue() + def can_merge_pr(self, username) -> bool: accounts_that_can_merge_pr = self.who_can_merge_pr() diff --git a/ogr/services/pagure/pull_request.py b/ogr/services/pagure/pull_request.py index 55a381256..251e83224 100644 --- a/ogr/services/pagure/pull_request.py +++ b/ogr/services/pagure/pull_request.py @@ -394,3 +394,20 @@ def get_comment(self, comment_id: int) -> PRComment: f"No comment with id#{comment_id} in PR#{self.id} found.", response_code=404, ) + + def who_can_close(self) -> set[str]: + people_who_can_close: set[str] = set() + people_who_can_close.add(self.author) + + project: ogr_pagure.PagureProject = self.target_project + people_who_can_close.update(project.get_owners()) + return people_who_can_close + + def can_close(self, username): + return username in self.who_can_close() + + def who_can_merge(self) -> set[str]: + return self._target_project.who_can_merge_pr() + + def can_merge(self, username): + return username in self.who_can_merge()