diff options
-rw-r--r-- | docs/gl_objects/milestones.py | 10 | ||||
-rw-r--r-- | docs/gl_objects/milestones.rst | 12 | ||||
-rw-r--r-- | gitlab/v4/objects.py | 80 | ||||
-rw-r--r-- | tools/python_test_v4.py | 16 |
4 files changed, 106 insertions, 12 deletions
diff --git a/docs/gl_objects/milestones.py b/docs/gl_objects/milestones.py index 19770bc..d1985d9 100644 --- a/docs/gl_objects/milestones.py +++ b/docs/gl_objects/milestones.py @@ -1,13 +1,16 @@ # list -milestones = project.milestones.list() +p_milestones = project.milestones.list() +g_milestones = group.milestones.list() # end list # filter -milestones = project.milestones.list(state='closed') +p_milestones = project.milestones.list(state='closed') +g_milestones = group.milestones.list(state='active') # end filter # get -milestone = project.milestones.get(milestone_id) +p_milestone = project.milestones.get(milestone_id) +g_milestone = group.milestones.get(milestone_id) # end get # create @@ -36,4 +39,3 @@ issues = milestone.issues() # merge_requests merge_requests = milestone.merge_requests() # end merge_requests - diff --git a/docs/gl_objects/milestones.rst b/docs/gl_objects/milestones.rst index fbe5d87..c96560a 100644 --- a/docs/gl_objects/milestones.rst +++ b/docs/gl_objects/milestones.rst @@ -11,6 +11,10 @@ Reference + :class:`gitlab.v4.objects.ProjectMilestoneManager` + :attr:`gitlab.v4.objects.Project.milestones` + + :class:`gitlab.v4.objects.GroupMilestone` + + :class:`gitlab.v4.objects.GroupMilestoneManager` + + :attr:`gitlab.v4.objects.Group.milestones` + * v3 API: + :class:`gitlab.v3.objects.ProjectMilestone` @@ -18,12 +22,15 @@ Reference + :attr:`gitlab.v3.objects.Project.milestones` + :attr:`gitlab.Gitlab.project_milestones` -* GitLab API: https://docs.gitlab.com/ce/api/milestones.html +* GitLab API: + + + https://docs.gitlab.com/ce/api/milestones.html + + https://docs.gitlab.com/ce/api/group_milestones.html Examples -------- -List the milestones for a project: +List the milestones for a project or a group: .. literalinclude:: milestones.py :start-after: # list @@ -33,6 +40,7 @@ You can filter the list using the following parameters: * ``iid``: unique ID of the milestone for the project * ``state``: either ``active`` or ``closed`` +* ``search``: to search using a string .. literalinclude:: milestones.py :start-after: # filter diff --git a/gitlab/v4/objects.py b/gitlab/v4/objects.py index 1fb32b4..535c23c 100644 --- a/gitlab/v4/objects.py +++ b/gitlab/v4/objects.py @@ -395,6 +395,75 @@ class GroupMemberManager(GetFromListMixin, CreateMixin, UpdateMixin, _update_attrs = (('access_level', ), ('expires_at', )) +class GroupMergeRequest(RESTObject): + pass + + +class GroupMergeRequestManager(RESTManager): + pass + + +class GroupMilestone(SaveMixin, ObjectDeleteMixin, RESTObject): + _short_print_attr = 'title' + + @cli.register_custom_action('GroupMilestone') + @exc.on_http_error(exc.GitlabListError) + def issues(self, **kwargs): + """List issues related to this milestone. + + Args: + **kwargs: Extra options to send to the server (e.g. sudo) + + Raises: + GitlabAuthenticationError: If authentication is not correct + GitlabListError: If the list could not be retrieved + + Returns: + RESTObjectList: The list of issues + """ + + path = '%s/%s/issues' % (self.manager.path, self.get_id()) + data_list = self.manager.gitlab.http_list(path, as_list=False, + **kwargs) + manager = GroupIssueManager(self.manager.gitlab, + parent=self.manager._parent) + # FIXME(gpocentek): the computed manager path is not correct + return RESTObjectList(manager, GroupIssue, data_list) + + @cli.register_custom_action('GroupMilestone') + @exc.on_http_error(exc.GitlabListError) + def merge_requests(self, **kwargs): + """List the merge requests related to this milestone. + + Args: + **kwargs: Extra options to send to the server (e.g. sudo) + + Raises: + GitlabAuthenticationError: If authentication is not correct + GitlabListError: If the list could not be retrieved + + Returns: + RESTObjectList: The list of merge requests + """ + path = '%s/%s/merge_requests' % (self.manager.path, self.get_id()) + data_list = self.manager.gitlab.http_list(path, as_list=False, + **kwargs) + manager = GroupIssueManager(self.manager.gitlab, + parent=self.manager._parent) + # FIXME(gpocentek): the computed manager path is not correct + return RESTObjectList(manager, GroupMergeRequest, data_list) + + +class GroupMilestoneManager(CRUDMixin, RESTManager): + _path = '/groups/%(group_id)s/milestones' + _obj_cls = GroupMilestone + _from_parent_attrs = {'group_id': 'id'} + _create_attrs = (('title', ), ('description', 'due_date', 'start_date')) + _update_attrs = (tuple(), ('title', 'description', 'due_date', + 'start_date', 'state_event')) + _list_filters = ('iids', 'state', 'search') + + class GroupNotificationSettings(NotificationSettings): pass @@ -434,6 +503,7 @@ class Group(SaveMixin, ObjectDeleteMixin, RESTObject): _managers = ( ('accessrequests', 'GroupAccessRequestManager'), ('members', 'GroupMemberManager'), + ('milestones', 'GroupMilestoneManager'), ('notificationsettings', 'GroupNotificationSettingsManager'), ('projects', 'GroupProjectManager'), ('issues', 'GroupIssueManager'), @@ -1293,8 +1363,8 @@ class ProjectMilestone(SaveMixin, ObjectDeleteMixin, RESTObject): path = '%s/%s/issues' % (self.manager.path, self.get_id()) data_list = self.manager.gitlab.http_list(path, as_list=False, **kwargs) - manager = ProjectCommitManager(self.manager.gitlab, - parent=self.manager._parent) + manager = ProjectIssueManager(self.manager.gitlab, + parent=self.manager._parent) # FIXME(gpocentek): the computed manager path is not correct return RESTObjectList(manager, ProjectIssue, data_list) @@ -1316,8 +1386,8 @@ class ProjectMilestone(SaveMixin, ObjectDeleteMixin, RESTObject): path = '%s/%s/merge_requests' % (self.manager.path, self.get_id()) data_list = self.manager.gitlab.http_list(path, as_list=False, **kwargs) - manager = ProjectCommitManager(self.manager.gitlab, - parent=self.manager._parent) + manager = ProjectMergeRequestManager(self.manager.gitlab, + parent=self.manager._parent) # FIXME(gpocentek): the computed manager path is not correct return RESTObjectList(manager, ProjectMergeRequest, data_list) @@ -1330,7 +1400,7 @@ class ProjectMilestoneManager(CRUDMixin, RESTManager): 'state_event')) _update_attrs = (tuple(), ('title', 'description', 'due_date', 'start_date', 'state_event')) - _list_filters = ('iids', 'state') + _list_filters = ('iids', 'state', 'search') class ProjectLabel(SubscribableMixin, SaveMixin, ObjectDeleteMixin, diff --git a/tools/python_test_v4.py b/tools/python_test_v4.py index 386b59b..1c1d4d3 100644 --- a/tools/python_test_v4.py +++ b/tools/python_test_v4.py @@ -170,6 +170,18 @@ settings.save() settings = group2.notificationsettings.get() assert(settings.level == 'disabled') +# group milestones +gm1 = group1.milestones.create({'title': 'groupmilestone1'}) +assert(len(group1.milestones.list()) == 1) +gm1.due_date = '2020-01-01T00:00:00Z' +gm1.save() +gm1.state_event = 'close' +gm1.save() +gm1 = group1.milestones.get(gm1.id) +assert(gm1.state == 'closed') +assert(len(gm1.issues()) == 0) +assert(len(gm1.merge_requests()) == 0) + # group variables group1.variables.create({'key': 'foo', 'value': 'bar'}) g_v = group1.variables.get('foo') @@ -330,8 +342,10 @@ m1.due_date = '2020-01-01T00:00:00Z' m1.save() m1.state_event = 'close' m1.save() -m1 = admin_project.milestones.get(1) +m1 = admin_project.milestones.get(m1.id) assert(m1.state == 'closed') +assert(len(m1.issues()) == 0) +assert(len(m1.merge_requests()) == 0) # issues issue1 = admin_project.issues.create({'title': 'my issue 1', |