1package iterator
2
3import (
4 "context"
5
6 "github.com/xanzy/go-gitlab"
7)
8
9type issueIterator struct {
10 page int
11 lastPage bool
12 index int
13 cache []*gitlab.Issue
14}
15
16func newIssueIterator() *issueIterator {
17 ii := &issueIterator{}
18 ii.Reset()
19 return ii
20}
21
22func (ii *issueIterator) Next(ctx context.Context, conf config) (bool, error) {
23 // first query
24 if ii.cache == nil {
25 return ii.getNext(ctx, conf)
26 }
27
28 // move cursor index
29 if ii.index < len(ii.cache)-1 {
30 ii.index++
31 return true, nil
32 }
33
34 return ii.getNext(ctx, conf)
35}
36
37func (ii *issueIterator) Value() *gitlab.Issue {
38 return ii.cache[ii.index]
39}
40
41func (ii *issueIterator) getNext(ctx context.Context, conf config) (bool, error) {
42 if ii.lastPage {
43 return false, nil
44 }
45
46 ctx, cancel := context.WithTimeout(ctx, conf.timeout)
47 defer cancel()
48
49 issues, resp, err := conf.gc.Issues.ListProjectIssues(
50 conf.project,
51 &gitlab.ListProjectIssuesOptions{
52 ListOptions: gitlab.ListOptions{
53 Page: ii.page,
54 PerPage: conf.capacity,
55 },
56 Scope: gitlab.String("all"),
57 UpdatedAfter: &conf.since,
58 Sort: gitlab.String("asc"),
59 },
60 gitlab.WithContext(ctx),
61 )
62
63 if err != nil {
64 ii.Reset()
65 return false, err
66 }
67
68 if resp.TotalPages == ii.page {
69 ii.lastPage = true
70 }
71
72 // if repository doesn't have any issues
73 if len(issues) == 0 {
74 return false, nil
75 }
76
77 ii.cache = issues
78 ii.index = 0
79 ii.page++
80
81 return true, nil
82}
83
84func (ii *issueIterator) Reset() {
85 ii.index = -1
86 ii.page = 1
87 ii.lastPage = false
88 ii.cache = nil
89}