From 94ce0cc152d6db35fd70e8bfef06e1eedd0b9c0f Mon Sep 17 00:00:00 2001 From: Laura Barcziova Date: Wed, 7 Feb 2024 20:02:10 +0100 Subject: [PATCH] Unify interface for labels Needed for packit/packit-service#2334 --- COMPATIBILITY.md | 1 - ogr/abstract.py | 38 ++++++++++++++++++- ogr/services/github/issue.py | 10 +++-- ogr/services/github/label.py | 32 ++++++++++++++++ ogr/services/github/pull_request.py | 10 +++-- ogr/services/gitlab/issue.py | 7 ++-- ogr/services/gitlab/label.py | 26 +++++++++++++ ogr/services/gitlab/pull_request.py | 7 ++-- ogr/services/pagure/issue.py | 7 ++-- ogr/services/pagure/label.py | 26 +++++++++++++ ogr/services/pagure/pull_request.py | 14 ++++++- tests/integration/gitlab/test_issues.py | 6 +-- .../integration/gitlab/test_pull_requests.py | 4 +- tests/integration/pagure/test_issues.py | 2 +- 14 files changed, 164 insertions(+), 26 deletions(-) create mode 100644 ogr/services/github/label.py create mode 100644 ogr/services/gitlab/label.py create mode 100644 ogr/services/pagure/label.py diff --git a/COMPATIBILITY.md b/COMPATIBILITY.md index 92bcb0ad..a2758c72 100644 --- a/COMPATIBILITY.md +++ b/COMPATIBILITY.md @@ -34,7 +34,6 @@ In case you find any error, please [create a new issue](https://github.com/packi | ----------------- | :----: | :----: | :----: | | `add_label` | ✔ | ✔ | ✘ | | `get_all_commits` | ✔ | ✔ | ✘ | -| `labels` | ✔ | ✔ | ✘ | ## Release diff --git a/ogr/abstract.py b/ogr/abstract.py index e68625c5..c7792bca 100644 --- a/ogr/abstract.py +++ b/ogr/abstract.py @@ -332,7 +332,7 @@ def created(self) -> datetime.datetime: raise NotImplementedError() @property - def labels(self) -> list: + def labels(self) -> list["IssueLabel"]: """Labels of the issue.""" raise NotImplementedError() @@ -624,7 +624,7 @@ def created(self) -> datetime.datetime: raise NotImplementedError() @property - def labels(self) -> list[Any]: + def labels(self) -> list["PRLabel"]: """Labels of the pull request.""" raise NotImplementedError() @@ -2062,3 +2062,37 @@ def get_forks(self) -> Sequence["GitProject"]: Sequence of forks in user's namespace. """ raise NotImplementedError() + + +class Label(OgrAbstractClass): + """ + Represents labels on PRs and issues. + """ + + def __init__(self, parent: Any) -> None: + self._parent = parent + + @property + def name(self) -> str: + """Name of the label.""" + raise NotImplementedError() + + +class IssueLabel(Label): + @property + def issue(self) -> "Issue": + """Issue of issue label.""" + return self._parent + + def __str__(self) -> str: + return "Issue" + super().__str__() + + +class PRLabel(Label): + @property + def pull_request(self) -> "PullRequest": + """Pull request of pull request label.""" + return self._parent + + def __str__(self) -> str: + return "PR" + super().__str__() diff --git a/ogr/services/github/issue.py b/ogr/services/github/issue.py index 6095e66d..00a452cc 100644 --- a/ogr/services/github/issue.py +++ b/ogr/services/github/issue.py @@ -8,7 +8,7 @@ from github import UnknownObjectException from github.Issue import Issue as _GithubIssue -from ogr.abstract import Issue, IssueComment, IssueStatus +from ogr.abstract import Issue, IssueComment, IssueLabel, IssueStatus from ogr.exceptions import ( GithubAPIException, IssueTrackerDisabled, @@ -17,6 +17,7 @@ from ogr.services import github as ogr_github from ogr.services.base import BaseIssue from ogr.services.github.comments import GithubIssueComment +from ogr.services.github.label import GithubIssueLabel class GithubIssue(BaseIssue): @@ -75,8 +76,11 @@ def created(self) -> datetime.datetime: return self._raw_issue.created_at @property - def labels(self) -> list: - return list(self._raw_issue.get_labels()) + def labels(self) -> list[IssueLabel]: + return [ + GithubIssueLabel(raw_label, self) + for raw_label in self._raw_issue.get_labels() + ] def __str__(self) -> str: return "Github" + super().__str__() diff --git a/ogr/services/github/label.py b/ogr/services/github/label.py new file mode 100644 index 00000000..f70561f5 --- /dev/null +++ b/ogr/services/github/label.py @@ -0,0 +1,32 @@ +# Copyright Contributors to the Packit project. +# SPDX-License-Identifier: MIT +from typing import Union + +from github.Label import Label as _GithubLabel + +from ogr.abstract import Issue, IssueLabel, Label, PRLabel, PullRequest + + +class GithubLabel(Label): + def __init__( + self, + raw_label: _GithubLabel, + parent: Union[PullRequest, Issue], + ) -> None: + super().__init__(parent) + self._raw_label = raw_label + + def __str__(self) -> str: + return f'GithubLabel(name="{self.name}")' + + @property + def name(self): + return self._raw_label.name + + +class GithubPRLabel(GithubLabel, PRLabel): + pass + + +class GithubIssueLabel(GithubLabel, IssueLabel): + pass diff --git a/ogr/services/github/pull_request.py b/ogr/services/github/pull_request.py index 0c964bd9..80b43e87 100644 --- a/ogr/services/github/pull_request.py +++ b/ogr/services/github/pull_request.py @@ -9,16 +9,16 @@ import requests from github import UnknownObjectException from github.IssueComment import IssueComment as _GithubIssueComment -from github.Label import Label as GithubLabel from github.PullRequest import PullRequest as _GithubPullRequest from github.PullRequestComment import PullRequestComment as _GithubPullRequestComment from github.Repository import Repository as _GithubRepository -from ogr.abstract import MergeCommitStatus, PRComment, PRStatus, PullRequest +from ogr.abstract import MergeCommitStatus, PRComment, PRLabel, PRStatus, PullRequest from ogr.exceptions import GithubAPIException, OgrNetworkError from ogr.services import github as ogr_github from ogr.services.base import BasePullRequest from ogr.services.github.comments import GithubPRComment +from ogr.services.github.label import GithubPRLabel logger = logging.getLogger(__name__) @@ -77,8 +77,10 @@ def created(self) -> datetime.datetime: return self._raw_pr.created_at @property - def labels(self) -> list[GithubLabel]: - return list(self._raw_pr.get_labels()) + def labels(self) -> list[PRLabel]: + return [ + GithubPRLabel(raw_label, self) for raw_label in self._raw_pr.get_labels() + ] @property def diff_url(self) -> str: diff --git a/ogr/services/gitlab/issue.py b/ogr/services/gitlab/issue.py index 90f28ae1..3d2cd49d 100644 --- a/ogr/services/gitlab/issue.py +++ b/ogr/services/gitlab/issue.py @@ -7,11 +7,12 @@ import gitlab from gitlab.v4.objects import Issue as _GitlabIssue -from ogr.abstract import Issue, IssueComment, IssueStatus +from ogr.abstract import Issue, IssueComment, IssueLabel, IssueStatus from ogr.exceptions import GitlabAPIException, IssueTrackerDisabled from ogr.services import gitlab as ogr_gitlab from ogr.services.base import BaseIssue from ogr.services.gitlab.comments import GitlabIssueComment +from ogr.services.gitlab.label import GitlabIssueLabel class GitlabIssue(BaseIssue): @@ -71,8 +72,8 @@ def created(self) -> datetime.datetime: return self._raw_issue.created_at @property - def labels(self) -> list: - return self._raw_issue.labels + def labels(self) -> list[IssueLabel]: + return [GitlabIssueLabel(label, self) for label in self._raw_issue.labels] def __str__(self) -> str: return "Gitlab" + super().__str__() diff --git a/ogr/services/gitlab/label.py b/ogr/services/gitlab/label.py new file mode 100644 index 00000000..f19b5b63 --- /dev/null +++ b/ogr/services/gitlab/label.py @@ -0,0 +1,26 @@ +# Copyright Contributors to the Packit project. +# SPDX-License-Identifier: MIT +from typing import Union + +from ogr.abstract import Issue, IssueLabel, Label, PRLabel, PullRequest + + +class GitlabLabel(Label): + def __init__(self, name: str, parent: Union[PullRequest, Issue]) -> None: + super().__init__(parent) + self._name = name + + def __str__(self) -> str: + return f'GitlabLabel(name="{self.name}")' + + @property + def name(self): + return self._name + + +class GitlabPRLabel(GitlabLabel, PRLabel): + pass + + +class GitlabIssueLabel(GitlabLabel, IssueLabel): + pass diff --git a/ogr/services/gitlab/pull_request.py b/ogr/services/gitlab/pull_request.py index 130517d9..0e5941e2 100644 --- a/ogr/services/gitlab/pull_request.py +++ b/ogr/services/gitlab/pull_request.py @@ -9,11 +9,12 @@ from gitlab.exceptions import GitlabGetError from gitlab.v4.objects import MergeRequest as _GitlabMergeRequest -from ogr.abstract import MergeCommitStatus, PRComment, PRStatus, PullRequest +from ogr.abstract import MergeCommitStatus, PRComment, PRLabel, PRStatus, PullRequest from ogr.exceptions import GitlabAPIException, OgrNetworkError from ogr.services import gitlab as ogr_gitlab from ogr.services.base import BasePullRequest from ogr.services.gitlab.comments import GitlabPRComment +from ogr.services.gitlab.label import GitlabPRLabel class GitlabPullRequest(BasePullRequest): @@ -79,8 +80,8 @@ def created(self) -> datetime.datetime: return self._raw_pr.created_at @property - def labels(self) -> list[str]: - return self._raw_pr.labels + def labels(self) -> list[PRLabel]: + return [GitlabPRLabel(label, self) for label in self._raw_pr.labels] @property def diff_url(self) -> str: diff --git a/ogr/services/pagure/issue.py b/ogr/services/pagure/issue.py index 9a983898..02e1d017 100644 --- a/ogr/services/pagure/issue.py +++ b/ogr/services/pagure/issue.py @@ -4,7 +4,7 @@ import datetime from typing import Any, Optional, Union, cast -from ogr.abstract import Issue, IssueComment, IssueStatus +from ogr.abstract import Issue, IssueComment, IssueLabel, IssueStatus from ogr.exceptions import ( IssueTrackerDisabled, OperationNotSupported, @@ -13,6 +13,7 @@ from ogr.services import pagure as ogr_pagure from ogr.services.base import BaseIssue from ogr.services.pagure.comments import PagureIssueComment +from ogr.services.pagure.label import PagureIssueLabel class PagureIssue(BaseIssue): @@ -84,8 +85,8 @@ def created(self) -> datetime.datetime: return datetime.datetime.fromtimestamp(int(self._raw_issue["date_created"])) @property - def labels(self) -> list[str]: - return self._raw_issue["tags"] + def labels(self) -> list[IssueLabel]: + return [PagureIssueLabel(label, self) for label in self._raw_issue["tags"]] def __str__(self) -> str: return "Pagure" + super().__str__() diff --git a/ogr/services/pagure/label.py b/ogr/services/pagure/label.py new file mode 100644 index 00000000..3688296b --- /dev/null +++ b/ogr/services/pagure/label.py @@ -0,0 +1,26 @@ +# Copyright Contributors to the Packit project. +# SPDX-License-Identifier: MIT +from typing import Union + +from ogr.abstract import Issue, IssueLabel, Label, PRLabel, PullRequest + + +class PagureLabel(Label): + def __init__(self, name: str, parent: Union[PullRequest, Issue]) -> None: + super().__init__(parent) + self._name = name + + def __str__(self) -> str: + return f'PagureLabel(name="{self.name}")' + + @property + def name(self): + return self._name + + +class PagurePRLabel(PagureLabel, PRLabel): + pass + + +class PagureIssueLabel(PagureLabel, IssueLabel): + pass diff --git a/ogr/services/pagure/pull_request.py b/ogr/services/pagure/pull_request.py index 49d9c5bc..55a38125 100644 --- a/ogr/services/pagure/pull_request.py +++ b/ogr/services/pagure/pull_request.py @@ -6,11 +6,19 @@ from time import sleep from typing import Any, Optional, Union -from ogr.abstract import CommitFlag, CommitStatus, PRComment, PRStatus, PullRequest +from ogr.abstract import ( + CommitFlag, + CommitStatus, + PRComment, + PRLabel, + PRStatus, + PullRequest, +) from ogr.exceptions import PagureAPIException from ogr.services import pagure as ogr_pagure from ogr.services.base import BasePullRequest from ogr.services.pagure.comments import PagurePRComment +from ogr.services.pagure.label import PagurePRLabel logger = logging.getLogger(__name__) @@ -132,6 +140,10 @@ def closed_by(self) -> Optional[str]: closed_by = self._raw_pr["closed_by"] return closed_by["name"] if closed_by else None + @property + def labels(self) -> list[PRLabel]: + return [PagurePRLabel(label, self) for label in self._raw_pr["tags"]] + def __str__(self) -> str: return "Pagure" + super().__str__() diff --git a/tests/integration/gitlab/test_issues.py b/tests/integration/gitlab/test_issues.py index c030e189..f0ab5022 100644 --- a/tests/integration/gitlab/test_issues.py +++ b/tests/integration/gitlab/test_issues.py @@ -68,7 +68,7 @@ def test_create_issue(self): assert issue.title == issue_title assert issue.description == issue_desc for issue_label, label in zip(issue.labels, labels): - assert issue_label == label + assert issue_label.name == label issue2 = self.project.create_issue(title=issue_title, body=issue_desc) assert issue2.title == issue_title @@ -155,8 +155,8 @@ def test_issue_labels(self): issue.add_label("test_lb1", "test_lb2") labels = self.project.get_issue(1).labels assert len(labels) == 2 - assert labels[0] == "test_lb1" - assert labels[1] == "test_lb2" + assert labels[0].name == "test_lb1" + assert labels[1].name == "test_lb2" def test_issue_assignees(self): """ diff --git a/tests/integration/gitlab/test_pull_requests.py b/tests/integration/gitlab/test_pull_requests.py index 650c3ed0..4cfa3701 100644 --- a/tests/integration/gitlab/test_pull_requests.py +++ b/tests/integration/gitlab/test_pull_requests.py @@ -125,8 +125,8 @@ def test_pr_labels(self): labels = self.project.get_pr(1).labels assert len(labels) == 2 - assert labels[0] == "test_lb1" - assert labels[1] == "test_lb2" + assert labels[0].name == "test_lb1" + assert labels[1].name == "test_lb2" def test_get_pr_comments_author_regex(self): comments = self.project.get_pr(1).get_comments( diff --git a/tests/integration/pagure/test_issues.py b/tests/integration/pagure/test_issues.py index a627ebc1..15937172 100644 --- a/tests/integration/pagure/test_issues.py +++ b/tests/integration/pagure/test_issues.py @@ -84,7 +84,7 @@ def test_create_issue(self): assert issue.description == description assert issue.private for issue_label, label in zip(issue.labels, labels): - assert issue_label == label + assert issue_label.name == label def test_create_issue_with_assignees(self): random_str = "something"