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 issues
 32	// updated 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	issues, _, err := i.gc.Issues.ListProjectIssues(
 83		i.project,
 84		&gitlab.ListProjectIssuesOptions{
 85			ListOptions: gitlab.ListOptions{
 86				Page:    i.issue.page,
 87				PerPage: i.capacity,
 88			},
 89			Scope:        gitlab.String("all"),
 90			UpdatedAfter: &i.since,
 91			Sort:         gitlab.String("asc"),
 92		},
 93	)
 94
 95	if err != nil {
 96		i.err = err
 97		return false
 98	}
 99
100	// if repository doesn't have any issues
101	if len(issues) == 0 {
102		return false
103	}
104
105	i.issue.cache = issues
106	i.issue.index = 0
107	i.issue.page++
108	i.note.index = -1
109	i.note.cache = nil
110
111	return true
112}
113
114func (i *iterator) NextIssue() bool {
115	if i.err != nil {
116		return false
117	}
118
119	// first query
120	if i.issue.cache == nil {
121		return i.getNextIssues()
122	}
123
124	// move cursor index
125	if i.issue.index < len(i.issue.cache)-1 {
126		i.issue.index++
127		return true
128	}
129
130	return i.getNextIssues()
131}
132
133func (i *iterator) IssueValue() *gitlab.Issue {
134	return i.issue.cache[i.issue.index]
135}
136
137func (i *iterator) getNextNotes() bool {
138	notes, _, err := i.gc.Notes.ListIssueNotes(
139		i.project,
140		i.IssueValue().IID,
141		&gitlab.ListIssueNotesOptions{
142			ListOptions: gitlab.ListOptions{
143				Page:    i.note.page,
144				PerPage: i.capacity,
145			},
146			Sort:    gitlab.String("asc"),
147			OrderBy: gitlab.String("created_at"),
148		},
149	)
150
151	if err != nil {
152		i.err = err
153		return false
154	}
155
156	if len(notes) == 0 {
157		i.note.index = -1
158		i.note.page = 1
159		i.note.cache = nil
160		return false
161	}
162
163	i.note.cache = notes
164	i.note.page++
165	i.note.index = 0
166	return true
167}
168
169func (i *iterator) NextNote() bool {
170	if i.err != nil {
171		return false
172	}
173
174	if len(i.note.cache) == 0 {
175		return i.getNextNotes()
176	}
177
178	// move cursor index
179	if i.note.index < len(i.note.cache)-1 {
180		i.note.index++
181		return true
182	}
183
184	return i.getNextNotes()
185}
186
187func (i *iterator) NoteValue() *gitlab.Note {
188	return i.note.cache[i.note.index]
189}
190
191func (i *iterator) getNextLabelEvents() bool {
192	labelEvents, _, err := i.gc.ResourceLabelEvents.ListIssueLabelEvents(
193		i.project,
194		i.IssueValue().IID,
195		&gitlab.ListLabelEventsOptions{
196			ListOptions: gitlab.ListOptions{
197				Page:    i.labelEvent.page,
198				PerPage: i.capacity,
199			},
200		},
201	)
202
203	if err != nil {
204		i.err = err
205		return false
206	}
207
208	if len(labelEvents) == 0 {
209		i.labelEvent.page = 1
210		i.labelEvent.index = -1
211		i.labelEvent.cache = nil
212		return false
213	}
214
215	i.labelEvent.cache = labelEvents
216	i.labelEvent.page++
217	i.labelEvent.index = 0
218	return true
219}
220
221func (i *iterator) NextLabelEvent() bool {
222	if i.err != nil {
223		return false
224	}
225
226	if len(i.labelEvent.cache) == 0 {
227		return i.getNextLabelEvents()
228	}
229
230	// move cursor index
231	if i.labelEvent.index < len(i.labelEvent.cache)-1 {
232		i.labelEvent.index++
233		return true
234	}
235
236	return i.getNextLabelEvents()
237}
238
239func (i *iterator) LabelEventValue() *gitlab.LabelEvent {
240	return i.labelEvent.cache[i.labelEvent.index]
241}