iterator.go

  1package gitlab
  2
  3import (
  4	"time"
  5
  6	"github.com/xanzy/go-gitlab"
  7)
  8
  9type issueIterator struct {
 10	page  int
 11	index int
 12	cache []*gitlab.Issue
 13}
 14
 15type commentIterator struct {
 16	page  int
 17	index int
 18	cache []*gitlab.Note
 19}
 20
 21type iterator struct {
 22	// gitlab api v4 client
 23	gc *gitlab.Client
 24
 25	// if since is given the iterator will query only the updated
 26	// issues after this date
 27	since time.Time
 28
 29	// project id
 30	project string
 31
 32	// number of issues and notes to query at once
 33	capacity int
 34
 35	// sticky error
 36	err error
 37
 38	// issues iterator
 39	issue *issueIterator
 40
 41	// comments iterator
 42	comment *commentIterator
 43}
 44
 45// NewIterator create a new iterator
 46func NewIterator(projectID, token string, capacity int, since time.Time) *iterator {
 47	return &iterator{
 48		gc:       buildClient(token),
 49		project:  projectID,
 50		since:    since,
 51		capacity: capacity,
 52		issue: &issueIterator{
 53			index: -1,
 54			page:  1,
 55		},
 56		comment: &commentIterator{
 57			index: -1,
 58			page:  1,
 59		},
 60	}
 61}
 62
 63// Error return last encountered error
 64func (i *iterator) Error() error {
 65	return i.err
 66}
 67
 68func (i *iterator) getIssues() ([]*gitlab.Issue, error) {
 69	scope := "all"
 70	issues, _, err := i.gc.Issues.ListProjectIssues(
 71		i.project,
 72		&gitlab.ListProjectIssuesOptions{
 73			ListOptions: gitlab.ListOptions{
 74				Page:    i.issue.page,
 75				PerPage: i.capacity,
 76			},
 77			Scope:        &scope,
 78			UpdatedAfter: &i.since,
 79		},
 80	)
 81
 82	return issues, err
 83}
 84
 85func (i *iterator) NextIssue() bool {
 86	// first query
 87	if i.issue.cache == nil {
 88		issues, err := i.getIssues()
 89		if err != nil {
 90			i.err = err
 91			return false
 92		}
 93
 94		// if repository doesn't have any issues
 95		if len(issues) == 0 {
 96			return false
 97		}
 98
 99		i.issue.cache = issues
100		i.issue.index++
101		return true
102	}
103
104	if i.err != nil {
105		return false
106	}
107
108	// move cursor index
109	if i.issue.index < min(i.capacity, len(i.issue.cache))-1 {
110		i.issue.index++
111		return true
112	}
113
114	// query next issues
115	issues, err := i.getIssues()
116	if err != nil {
117		i.err = err
118		return false
119	}
120
121	// no more issues to query
122	if len(issues) == 0 {
123		return false
124	}
125
126	i.issue.page++
127	i.issue.index = 0
128	i.comment.index = 0
129	i.issue.cache = issues
130
131	return true
132}
133
134func (i *iterator) IssueValue() *gitlab.Issue {
135	return i.issue.cache[i.issue.index]
136}
137
138func (i *iterator) getComments() ([]*gitlab.Note, error) {
139	notes, _, err := i.gc.Notes.ListIssueNotes(
140		i.project,
141		i.IssueValue().IID,
142		&gitlab.ListIssueNotesOptions{
143			ListOptions: gitlab.ListOptions{
144				Page:    i.issue.page,
145				PerPage: i.capacity,
146			},
147		},
148	)
149
150	return notes, err
151}
152
153func (i *iterator) getNextComments() bool {
154	return false
155}
156
157func (i *iterator) NextComment() bool {
158	if i.err != nil {
159		return false
160	}
161
162	if len(i.comment.cache) == 0 {
163		// query next issues
164		comments, err := i.getComments()
165		if err != nil {
166			i.err = err
167			return false
168		}
169
170		if len(comments) == 0 {
171			i.comment.index = 0
172			i.comment.page = 1
173			return false
174		}
175
176		i.comment.cache = comments
177		i.comment.page++
178		i.comment.index = 0
179
180		return true
181	}
182
183	// move cursor index
184	if i.comment.index < min(i.capacity, len(i.comment.cache))-1 {
185		i.comment.index++
186		return true
187	}
188
189	// query next issues
190	comments, err := i.getComments()
191	if err != nil {
192		i.err = err
193		return false
194	}
195
196	if len(comments) == 0 {
197		i.comment.index = 0
198		i.comment.page = 1
199		return false
200	}
201
202	i.comment.cache = comments
203	i.comment.page++
204	i.comment.index = 0
205
206	return false
207}
208
209func (i *iterator) CommentValue() *gitlab.Note {
210	return i.comment.cache[i.comment.index]
211}
212
213func min(a, b int) int {
214	if a > b {
215		return b
216	}
217
218	return a
219}