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 noteIterator struct {
 16	page  int
 17	index int
 18	cache []*gitlab.Note
 19}
 20
 21type labelEventIterator struct {
 22	page  int
 23	index int
 24	cache []*gitlab.LabelEvent
 25}
 26
 27type iterator struct {
 28	// gitlab api v4 client
 29	gc *gitlab.Client
 30
 31	// if since is given the iterator will query only the updated
 32	// issues after this date
 33	since time.Time
 34
 35	// project id
 36	project string
 37
 38	// number of issues and notes to query at once
 39	capacity int
 40
 41	// sticky error
 42	err error
 43
 44	// issues iterator
 45	issue *issueIterator
 46
 47	// notes iterator
 48	note *noteIterator
 49
 50	// labelEvent iterator
 51	labelEvent *labelEventIterator
 52}
 53
 54// NewIterator create a new iterator
 55func NewIterator(projectID, token string, since time.Time) *iterator {
 56	return &iterator{
 57		gc:       buildClient(token),
 58		project:  projectID,
 59		since:    since,
 60		capacity: 20,
 61		issue: &issueIterator{
 62			index: -1,
 63			page:  1,
 64		},
 65		note: &noteIterator{
 66			index: -1,
 67			page:  1,
 68		},
 69		labelEvent: &labelEventIterator{
 70			index: -1,
 71			page:  1,
 72		},
 73	}
 74}
 75
 76// Error return last encountered error
 77func (i *iterator) Error() error {
 78	return i.err
 79}
 80
 81func (i *iterator) getNextIssues() bool {
 82	sort := "asc"
 83	scope := "all"
 84	issues, _, err := i.gc.Issues.ListProjectIssues(
 85		i.project,
 86		&gitlab.ListProjectIssuesOptions{
 87			ListOptions: gitlab.ListOptions{
 88				Page:    i.issue.page,
 89				PerPage: i.capacity,
 90			},
 91			Scope:        &scope,
 92			UpdatedAfter: &i.since,
 93			Sort:         &sort,
 94		},
 95	)
 96
 97	if err != nil {
 98		i.err = err
 99		return false
100	}
101
102	// if repository doesn't have any issues
103	if len(issues) == 0 {
104		return false
105	}
106
107	i.issue.cache = issues
108	i.issue.index = 0
109	i.issue.page++
110	i.note.index = -1
111	i.note.cache = nil
112
113	return true
114}
115
116func (i *iterator) NextIssue() bool {
117	// first query
118	if i.issue.cache == nil {
119		return i.getNextIssues()
120	}
121
122	if i.err != nil {
123		return false
124	}
125
126	// move cursor index
127	if i.issue.index < min(i.capacity, len(i.issue.cache))-1 {
128		i.issue.index++
129		return true
130	}
131
132	return i.getNextIssues()
133}
134
135func (i *iterator) IssueValue() *gitlab.Issue {
136	return i.issue.cache[i.issue.index]
137}
138
139func (i *iterator) getNextNotes() bool {
140	sort := "asc"
141	order := "created_at"
142	notes, _, err := i.gc.Notes.ListIssueNotes(
143		i.project,
144		i.IssueValue().IID,
145		&gitlab.ListIssueNotesOptions{
146			ListOptions: gitlab.ListOptions{
147				Page:    i.note.page,
148				PerPage: i.capacity,
149			},
150			Sort:    &sort,
151			OrderBy: &order,
152		},
153	)
154
155	if err != nil {
156		i.err = err
157		return false
158	}
159
160	if len(notes) == 0 {
161		i.note.index = -1
162		i.note.page = 1
163		i.note.cache = nil
164		return false
165	}
166
167	i.note.cache = notes
168	i.note.page++
169	i.note.index = 0
170	return true
171}
172
173func (i *iterator) NextNote() bool {
174	if i.err != nil {
175		return false
176	}
177
178	if len(i.note.cache) == 0 {
179		return i.getNextNotes()
180	}
181
182	// move cursor index
183	if i.note.index < min(i.capacity, len(i.note.cache))-1 {
184		i.note.index++
185		return true
186	}
187
188	return i.getNextNotes()
189}
190
191func (i *iterator) NoteValue() *gitlab.Note {
192	return i.note.cache[i.note.index]
193}
194
195func (i *iterator) getNextLabelEvents() bool {
196	labelEvents, _, err := i.gc.ResourceLabelEvents.ListIssueLabelEvents(
197		i.project,
198		i.IssueValue().IID,
199		&gitlab.ListLabelEventsOptions{
200			ListOptions: gitlab.ListOptions{
201				Page:    i.labelEvent.page,
202				PerPage: i.capacity,
203			},
204		},
205	)
206
207	if err != nil {
208		i.err = err
209		return false
210	}
211
212	if len(labelEvents) == 0 {
213		i.labelEvent.page = 1
214		i.labelEvent.index = -1
215		i.labelEvent.cache = nil
216		return false
217	}
218
219	i.labelEvent.cache = labelEvents
220	i.labelEvent.page++
221	i.labelEvent.index = 0
222	return true
223}
224
225func (i *iterator) NextLabelEvent() bool {
226	if i.err != nil {
227		return false
228	}
229
230	if len(i.labelEvent.cache) == 0 {
231		return i.getNextLabelEvents()
232	}
233
234	// move cursor index
235	if i.labelEvent.index < min(i.capacity, len(i.labelEvent.cache))-1 {
236		i.labelEvent.index++
237		return true
238	}
239
240	return i.getNextLabelEvents()
241}
242
243func (i *iterator) LabelEventValue() *gitlab.LabelEvent {
244	return i.labelEvent.cache[i.labelEvent.index]
245}
246
247func min(a, b int) int {
248	if a > b {
249		return b
250	}
251
252	return a
253}