summaryrefslogtreecommitdiff
path: root/gitlab/v4/objects/issues.py
diff options
context:
space:
mode:
Diffstat (limited to 'gitlab/v4/objects/issues.py')
-rw-r--r--gitlab/v4/objects/issues.py229
1 files changed, 229 insertions, 0 deletions
diff --git a/gitlab/v4/objects/issues.py b/gitlab/v4/objects/issues.py
new file mode 100644
index 0000000..1d8358d
--- /dev/null
+++ b/gitlab/v4/objects/issues.py
@@ -0,0 +1,229 @@
+from gitlab import types
+from gitlab.base import * # noqa
+from gitlab.mixins import * # noqa
+from .award_emojis import ProjectIssueAwardEmojiManager
+from .discussions import ProjectIssueDiscussionManager
+from .events import (
+ ProjectIssueResourceLabelEventManager,
+ ProjectIssueResourceMilestoneEventManager,
+)
+from .notes import ProjectIssueNoteManager
+
+
+class Issue(RESTObject):
+ _url = "/issues"
+ _short_print_attr = "title"
+
+
+class IssueManager(RetrieveMixin, RESTManager):
+ _path = "/issues"
+ _obj_cls = Issue
+ _list_filters = (
+ "state",
+ "labels",
+ "milestone",
+ "scope",
+ "author_id",
+ "assignee_id",
+ "my_reaction_emoji",
+ "iids",
+ "order_by",
+ "sort",
+ "search",
+ "created_after",
+ "created_before",
+ "updated_after",
+ "updated_before",
+ )
+ _types = {"labels": types.ListAttribute}
+
+
+class GroupIssue(RESTObject):
+ pass
+
+
+class GroupIssueManager(ListMixin, RESTManager):
+ _path = "/groups/%(group_id)s/issues"
+ _obj_cls = GroupIssue
+ _from_parent_attrs = {"group_id": "id"}
+ _list_filters = (
+ "state",
+ "labels",
+ "milestone",
+ "order_by",
+ "sort",
+ "iids",
+ "author_id",
+ "assignee_id",
+ "my_reaction_emoji",
+ "search",
+ "created_after",
+ "created_before",
+ "updated_after",
+ "updated_before",
+ )
+ _types = {"labels": types.ListAttribute}
+
+
+class ProjectIssue(
+ UserAgentDetailMixin,
+ SubscribableMixin,
+ TodoMixin,
+ TimeTrackingMixin,
+ ParticipantsMixin,
+ SaveMixin,
+ ObjectDeleteMixin,
+ RESTObject,
+):
+ _short_print_attr = "title"
+ _id_attr = "iid"
+ _managers = (
+ ("awardemojis", "ProjectIssueAwardEmojiManager"),
+ ("discussions", "ProjectIssueDiscussionManager"),
+ ("links", "ProjectIssueLinkManager"),
+ ("notes", "ProjectIssueNoteManager"),
+ ("resourcelabelevents", "ProjectIssueResourceLabelEventManager"),
+ ("resourcemilestoneevents", "ProjectIssueResourceMilestoneEventManager"),
+ )
+
+ @cli.register_custom_action("ProjectIssue", ("to_project_id",))
+ @exc.on_http_error(exc.GitlabUpdateError)
+ def move(self, to_project_id, **kwargs):
+ """Move the issue to another project.
+
+ Args:
+ to_project_id(int): ID of the target project
+ **kwargs: Extra options to send to the server (e.g. sudo)
+
+ Raises:
+ GitlabAuthenticationError: If authentication is not correct
+ GitlabUpdateError: If the issue could not be moved
+ """
+ path = "%s/%s/move" % (self.manager.path, self.get_id())
+ data = {"to_project_id": to_project_id}
+ server_data = self.manager.gitlab.http_post(path, post_data=data, **kwargs)
+ self._update_attrs(server_data)
+
+ @cli.register_custom_action("ProjectIssue")
+ @exc.on_http_error(exc.GitlabGetError)
+ def related_merge_requests(self, **kwargs):
+ """List merge requests related to the issue.
+
+ Args:
+ **kwargs: Extra options to send to the server (e.g. sudo)
+
+ Raises:
+ GitlabAuthenticationError: If authentication is not correct
+ GitlabGetErrot: If the merge requests could not be retrieved
+
+ Returns:
+ list: The list of merge requests.
+ """
+ path = "%s/%s/related_merge_requests" % (self.manager.path, self.get_id())
+ return self.manager.gitlab.http_get(path, **kwargs)
+
+ @cli.register_custom_action("ProjectIssue")
+ @exc.on_http_error(exc.GitlabGetError)
+ def closed_by(self, **kwargs):
+ """List merge requests that will close the issue when merged.
+
+ Args:
+ **kwargs: Extra options to send to the server (e.g. sudo)
+
+ Raises:
+ GitlabAuthenticationError: If authentication is not correct
+ GitlabGetErrot: If the merge requests could not be retrieved
+
+ Returns:
+ list: The list of merge requests.
+ """
+ path = "%s/%s/closed_by" % (self.manager.path, self.get_id())
+ return self.manager.gitlab.http_get(path, **kwargs)
+
+
+class ProjectIssueManager(CRUDMixin, RESTManager):
+ _path = "/projects/%(project_id)s/issues"
+ _obj_cls = ProjectIssue
+ _from_parent_attrs = {"project_id": "id"}
+ _list_filters = (
+ "iids",
+ "state",
+ "labels",
+ "milestone",
+ "scope",
+ "author_id",
+ "assignee_id",
+ "my_reaction_emoji",
+ "order_by",
+ "sort",
+ "search",
+ "created_after",
+ "created_before",
+ "updated_after",
+ "updated_before",
+ )
+ _create_attrs = (
+ ("title",),
+ (
+ "description",
+ "confidential",
+ "assignee_ids",
+ "assignee_id",
+ "milestone_id",
+ "labels",
+ "created_at",
+ "due_date",
+ "merge_request_to_resolve_discussions_of",
+ "discussion_to_resolve",
+ ),
+ )
+ _update_attrs = (
+ tuple(),
+ (
+ "title",
+ "description",
+ "confidential",
+ "assignee_ids",
+ "assignee_id",
+ "milestone_id",
+ "labels",
+ "state_event",
+ "updated_at",
+ "due_date",
+ "discussion_locked",
+ ),
+ )
+ _types = {"labels": types.ListAttribute}
+
+
+class ProjectIssueLink(ObjectDeleteMixin, RESTObject):
+ _id_attr = "issue_link_id"
+
+
+class ProjectIssueLinkManager(ListMixin, CreateMixin, DeleteMixin, RESTManager):
+ _path = "/projects/%(project_id)s/issues/%(issue_iid)s/links"
+ _obj_cls = ProjectIssueLink
+ _from_parent_attrs = {"project_id": "project_id", "issue_iid": "iid"}
+ _create_attrs = (("target_project_id", "target_issue_iid"), tuple())
+
+ @exc.on_http_error(exc.GitlabCreateError)
+ def create(self, data, **kwargs):
+ """Create a new object.
+
+ Args:
+ data (dict): parameters to send to the server to create the
+ resource
+ **kwargs: Extra options to send to the server (e.g. sudo)
+
+ Returns:
+ RESTObject, RESTObject: The source and target issues
+
+ Raises:
+ GitlabAuthenticationError: If authentication is not correct
+ GitlabCreateError: If the server cannot perform the request
+ """
+ self._check_missing_create_attrs(data)
+ server_data = self.gitlab.http_post(self.path, post_data=data, **kwargs)
+ source_issue = ProjectIssue(self._parent.manager, server_data["source_issue"])
+ target_issue = ProjectIssue(self._parent.manager, server_data["target_issue"])
+ return source_issue, target_issue