package iterator import ( "context" "github.com/xanzy/go-gitlab" ) type issueIterator struct { page int lastPage bool index int cache []*gitlab.Issue } func newIssueIterator() *issueIterator { ii := &issueIterator{} ii.Reset() return ii } func (ii *issueIterator) Next(ctx context.Context, conf config) (bool, error) { // first query if ii.cache == nil { return ii.getNext(ctx, conf) } // move cursor index if ii.index < len(ii.cache)-1 { ii.index++ return true, nil } return ii.getNext(ctx, conf) } func (ii *issueIterator) Value() *gitlab.Issue { return ii.cache[ii.index] } func (ii *issueIterator) getNext(ctx context.Context, conf config) (bool, error) { if ii.lastPage { return false, nil } ctx, cancel := context.WithTimeout(ctx, conf.timeout) defer cancel() issues, resp, err := conf.gc.Issues.ListProjectIssues( conf.project, &gitlab.ListProjectIssuesOptions{ ListOptions: gitlab.ListOptions{ Page: ii.page, PerPage: conf.capacity, }, Scope: gitlab.String("all"), UpdatedAfter: &conf.since, Sort: gitlab.String("asc"), }, gitlab.WithContext(ctx), ) if err != nil { ii.Reset() return false, err } if resp.TotalPages == ii.page { ii.lastPage = true } // if repository doesn't have any issues if len(issues) == 0 { return false, nil } ii.cache = issues ii.index = 0 ii.page++ return true, nil } func (ii *issueIterator) Reset() { ii.index = -1 ii.page = 1 ii.lastPage = false ii.cache = nil }