Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for iterations #1353

Merged
merged 4 commits into from Feb 10, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 4 additions & 0 deletions gitlab.go
Expand Up @@ -131,6 +131,7 @@ type Client struct {
GroupCluster *GroupClustersService
GroupImportExport *GroupImportExportService
GroupIssueBoards *GroupIssueBoardsService
GroupIterations *GroupIterationsService
GroupLabels *GroupLabelsService
GroupMembers *GroupMembersService
GroupMilestones *GroupMilestonesService
Expand Down Expand Up @@ -167,6 +168,7 @@ type Client struct {
ProjectAccessTokens *ProjectAccessTokensService
ProjectCluster *ProjectClustersService
ProjectImportExport *ProjectImportExportService
ProjectIterations *ProjectIterationsService
ProjectMembers *ProjectMembersService
ProjectMirrors *ProjectMirrorService
ProjectSnippets *ProjectSnippetsService
Expand Down Expand Up @@ -325,6 +327,7 @@ func newClient(options ...ClientOptionFunc) (*Client, error) {
c.GroupCluster = &GroupClustersService{client: c}
c.GroupImportExport = &GroupImportExportService{client: c}
c.GroupIssueBoards = &GroupIssueBoardsService{client: c}
c.GroupIterations = &GroupIterationsService{client: c}
c.GroupLabels = &GroupLabelsService{client: c}
c.GroupMembers = &GroupMembersService{client: c}
c.GroupMilestones = &GroupMilestonesService{client: c}
Expand Down Expand Up @@ -361,6 +364,7 @@ func newClient(options ...ClientOptionFunc) (*Client, error) {
c.ProjectAccessTokens = &ProjectAccessTokensService{client: c}
c.ProjectCluster = &ProjectClustersService{client: c}
c.ProjectImportExport = &ProjectImportExportService{client: c}
c.ProjectIterations = &ProjectIterationsService{client: c}
c.ProjectMembers = &ProjectMembersService{client: c}
c.ProjectMirrors = &ProjectMirrorService{client: c}
c.ProjectSnippets = &ProjectSnippetsService{client: c}
Expand Down
90 changes: 90 additions & 0 deletions group_iterations.go
@@ -0,0 +1,90 @@
//
// Copyright 2022, Daniel Steinke
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

package gitlab

import (
"fmt"
"net/http"
"time"
)

// IterationsAPI handles communication with the iterations related methods
// of the GitLab API
//
// GitLab API docs: https://docs.gitlab.com/ee/api/group_iterations.html
type GroupIterationsService struct {
client *Client
}

// GroupInteration represents a GitLab iteration.
//
// GitLab API docs: https://docs.gitlab.com/ee/api/group_iterations.html
type GroupIteration struct {
ID int `json:"id"`
IID int `json:"iid"`
Sequence int `json:"sequence"`
GroupID int `json:"group_id"`
Title string `json:"title"`
Description string `json:"description"`
State int `json:"state"`
CreatedAt *time.Time `json:"created_at"`
UpdatedAt *time.Time `json:"updated_at"`
DueDate *ISOTime `json:"due_date"`
StartDate *ISOTime `json:"start_date"`
WebURL string `json:"web_url"`
}

func (i GroupIteration) String() string {
return Stringify(i)
}

// ListGroupIterationsOptions contains the available ListGroupIterations()
// options
//
// GitLab API docs:
// https://docs.gitlab.com/ee/api/group_iterations.html#list-group-iterations
type ListGroupIterationsOptions struct {
ListOptions
State *string `url:"state,omitempty" json:"state,omitempty"`
Search *string `url:"search,omitempty" json:"search,omitempty"`
IncludeAncestors *bool `url:"include_ancestors,omitempty" json:"include_ancestors,omitempty"`
}

// ListGroupIterations returns a list of group iterations.
//
// GitLab API docs:
// https://docs.gitlab.com/ee/api/group_iterations.html#list-group-iterations
func (s *GroupIterationsService) ListGroupIterations(gid interface{}, opt *ListGroupIterationsOptions, options ...RequestOptionFunc) ([]*GroupIteration, *Response, error) {
group, err := parseID(gid)
if err != nil {
return nil, nil, err
}
u := fmt.Sprintf("groups/%s/iterations", PathEscape(group))

req, err := s.client.NewRequest(http.MethodGet, u, opt, options)
if err != nil {
return nil, nil, err
}

var gis []*GroupIteration
resp, err := s.client.Do(req, &gis)
if err != nil {
return nil, nil, err
}

return gis, resp, err
}
49 changes: 49 additions & 0 deletions group_iterations_test.go
@@ -0,0 +1,49 @@
package gitlab

import (
"fmt"
"net/http"
"reflect"
"testing"
)

func TestListGroupIterations(t *testing.T) {
mux, server, client := setup(t)
defer teardown(server)

mux.HandleFunc("/api/v4/groups/5/iterations",
func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, http.MethodGet)
fmt.Fprintf(w, `[
{
"id": 53,
"iid": 13,
"sequence": 1,
"group_id": 5,
"title": "Iteration II",
"description": "Ipsum Lorem ipsum",
"state": 2,
"web_url": "http://gitlab.example.com/groups/my-group/-/iterations/13"
}
]`)
})

iterations, _, err := client.GroupIterations.ListGroupIterations(5, &ListGroupIterationsOptions{})
if err != nil {
t.Errorf("GroupIterations.ListGroupIterations returned error: %v", err)
}

want := []*GroupIteration{{
ID: 53,
IID: 13,
Sequence: 1,
GroupID: 5,
Title: "Iteration II",
Description: "Ipsum Lorem ipsum",
State: 2,
WebURL: "http://gitlab.example.com/groups/my-group/-/iterations/13",
}}
if !reflect.DeepEqual(want, iterations) {
t.Errorf("GroupIterations.ListGroupIterations returned %+v, want %+v", iterations, want)
}
}
90 changes: 90 additions & 0 deletions project_iterations.go
@@ -0,0 +1,90 @@
//
// Copyright 2022, Daniel Steinke
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

package gitlab

import (
"fmt"
"net/http"
"time"
)

// IterationsAPI handles communication with the project iterations related
// methods of the GitLab API
//
// GitLab API docs: https://docs.gitlab.com/ee/api/iterations.html
type ProjectIterationsService struct {
client *Client
}

// ProjectIteration represents a GitLab project iteration.
//
// GitLab API docs: https://docs.gitlab.com/ee/api/iterations.html
type ProjectIteration struct {
ID int `json:"id"`
IID int `json:"iid"`
Sequence int `json:"sequence"`
GroupID int `json:"group_id"`
Title string `json:"title"`
Description string `json:"description"`
State int `json:"state"`
CreatedAt *time.Time `json:"created_at"`
UpdatedAt *time.Time `json:"updated_at"`
DueDate *ISOTime `json:"due_date"`
StartDate *ISOTime `json:"start_date"`
WebURL string `json:"web_url"`
}

func (i ProjectIteration) String() string {
return Stringify(i)
}

// ListProjectIterationsOptions contains the available ListProjectIterations()
// options
//
// GitLab API docs:
// https://docs.gitlab.com/ee/api/group_iterations.html#list-project-iterations
type ListProjectIterationsOptions struct {
ListOptions
State *string `url:"state,omitempty" json:"state,omitempty"`
Search *string `url:"search,omitempty" json:"search,omitempty"`
IncludeAncestors *bool `url:"include_ancestors,omitempty" json:"include_ancestors,omitempty"`
}

// ListProjectIterations returns a list of projects iterations.
//
// GitLab API docs:
// https://docs.gitlab.com/ee/api/group_iterations.html#list-project-iterations
func (i *ProjectIterationsService) ListProjectIterations(pid interface{}, opt *ListProjectIterationsOptions, options ...RequestOptionFunc) ([]*ProjectIteration, *Response, error) {
project, err := parseID(pid)
if err != nil {
return nil, nil, err
}
u := fmt.Sprintf("projects/%s/iterations", PathEscape(project))

req, err := i.client.NewRequest(http.MethodGet, u, opt, options)
if err != nil {
return nil, nil, err
}

var pis []*ProjectIteration
resp, err := i.client.Do(req, &pis)
if err != nil {
return nil, resp, err
}

return pis, resp, err
}
49 changes: 49 additions & 0 deletions project_iterations_test.go
@@ -0,0 +1,49 @@
package gitlab

import (
"fmt"
"net/http"
"reflect"
"testing"
)

func TestListProjectIterations(t *testing.T) {
mux, server, client := setup(t)
defer teardown(server)

mux.HandleFunc("/api/v4/projects/42/iterations",
func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, http.MethodGet)
fmt.Fprintf(w, `[
{
"id": 53,
"iid": 13,
"sequence": 1,
"group_id": 5,
"title": "Iteration II",
"description": "Ipsum Lorem ipsum",
"state": 2,
"web_url": "http://gitlab.example.com/groups/my-group/-/iterations/13"
}
]`)
})

iterations, _, err := client.ProjectIterations.ListProjectIterations(42, &ListProjectIterationsOptions{})
if err != nil {
t.Errorf("GroupIterations.ListGroupIterations returned error: %v", err)
}

want := []*ProjectIteration{{
ID: 53,
IID: 13,
Sequence: 1,
GroupID: 5,
Title: "Iteration II",
Description: "Ipsum Lorem ipsum",
State: 2,
WebURL: "http://gitlab.example.com/groups/my-group/-/iterations/13",
}}
if !reflect.DeepEqual(want, iterations) {
t.Errorf("ProjectIterations.ListProjectIterations returned %+v, want %+v", iterations, want)
}
}
16 changes: 16 additions & 0 deletions testdata/list_group_iterations.json
@@ -0,0 +1,16 @@
[
{
"id": 53,
"iid": 13,
"sequence": 1,
"group_id": 5,
"title": "Iteration II",
"description": "Ipsum Lorem ipsum",
"state": 2,
"created_at": "2020-01-27T05:07:12.573Z",
"updated_at": "2020-01-27T05:07:12.573Z",
"due_date": "2020-02-01",
"start_date": "2020-02-14",
"web_url": "http://gitlab.example.com/groups/my-group/-/iterations/13"
}
]