diff options
author | Michael Muré <batolettre@gmail.com> | 2020-03-28 21:09:36 +0100 |
---|---|---|
committer | Michael Muré <batolettre@gmail.com> | 2020-03-28 21:23:18 +0100 |
commit | f4ca533fe10f7fa893e1953f8c8d9ed3e783486c (patch) | |
tree | f9fdaff8aa02f723acc3a4492d46655d63cbff5a /bridge/gitlab/iterator.go | |
parent | 38b42bc867f8f352908ba81334bec86b001e8fac (diff) | |
download | git-bug-f4ca533fe10f7fa893e1953f8c8d9ed3e783486c.tar.gz |
gitlab: refactor the iterator, fix bugs
Notably, properly reset sub iterators when changing to the next issue
Diffstat (limited to 'bridge/gitlab/iterator.go')
-rw-r--r-- | bridge/gitlab/iterator.go | 288 |
1 files changed, 0 insertions, 288 deletions
diff --git a/bridge/gitlab/iterator.go b/bridge/gitlab/iterator.go deleted file mode 100644 index 07f9cce9..00000000 --- a/bridge/gitlab/iterator.go +++ /dev/null @@ -1,288 +0,0 @@ -package gitlab - -import ( - "context" - "sort" - "time" - - "github.com/xanzy/go-gitlab" -) - -type issueIterator struct { - page int - index int - cache []*gitlab.Issue -} - -type noteIterator struct { - page int - index int - cache []*gitlab.Note -} - -// Since Gitlab does not return the label events items in the correct order -// we need to sort the list our selfs and stop relying on the pagination model -// #BecauseGitlab -type labelEventIterator struct { - index int - cache []*gitlab.LabelEvent -} - -func (l *labelEventIterator) Len() int { - return len(l.cache) -} - -func (l *labelEventIterator) Swap(i, j int) { - l.cache[i], l.cache[j] = l.cache[j], l.cache[i] -} - -func (l *labelEventIterator) Less(i, j int) bool { - return l.cache[i].ID < l.cache[j].ID -} - -type iterator struct { - // gitlab api v4 client - gc *gitlab.Client - - // if since is given the iterator will query only the issues - // updated after this date - since time.Time - - // project id - project string - - // number of issues and notes to query at once - capacity int - - // shared context - ctx context.Context - - // sticky error - err error - - // issues iterator - issue *issueIterator - - // notes iterator - note *noteIterator - - // labelEvent iterator - labelEvent *labelEventIterator -} - -// NewIterator create a new iterator -func NewIterator(ctx context.Context, client *gitlab.Client, capacity int, projectID string, since time.Time) *iterator { - return &iterator{ - gc: client, - project: projectID, - since: since, - capacity: capacity, - ctx: ctx, - issue: &issueIterator{ - index: -1, - page: 1, - }, - note: ¬eIterator{ - index: -1, - page: 1, - }, - labelEvent: &labelEventIterator{ - index: -1, - }, - } -} - -// Error return last encountered error -func (i *iterator) Error() error { - return i.err -} - -func (i *iterator) getNextIssues() bool { - ctx, cancel := context.WithTimeout(i.ctx, defaultTimeout) - defer cancel() - - issues, _, err := i.gc.Issues.ListProjectIssues( - i.project, - &gitlab.ListProjectIssuesOptions{ - ListOptions: gitlab.ListOptions{ - Page: i.issue.page, - PerPage: i.capacity, - }, - Scope: gitlab.String("all"), - UpdatedAfter: &i.since, - Sort: gitlab.String("asc"), - }, - gitlab.WithContext(ctx), - ) - - if err != nil { - i.err = err - return false - } - - // if repository doesn't have any issues - if len(issues) == 0 { - return false - } - - i.issue.cache = issues - i.issue.index = 0 - i.issue.page++ - i.note.index = -1 - i.note.cache = nil - - return true -} - -func (i *iterator) NextIssue() bool { - if i.err != nil { - return false - } - - if i.ctx.Err() != nil { - return false - } - - // first query - if i.issue.cache == nil { - return i.getNextIssues() - } - - // move cursor index - if i.issue.index < len(i.issue.cache)-1 { - i.issue.index++ - return true - } - - return i.getNextIssues() -} - -func (i *iterator) IssueValue() *gitlab.Issue { - return i.issue.cache[i.issue.index] -} - -func (i *iterator) getNextNotes() bool { - ctx, cancel := context.WithTimeout(i.ctx, defaultTimeout) - defer cancel() - - notes, _, err := i.gc.Notes.ListIssueNotes( - i.project, - i.IssueValue().IID, - &gitlab.ListIssueNotesOptions{ - ListOptions: gitlab.ListOptions{ - Page: i.note.page, - PerPage: i.capacity, - }, - Sort: gitlab.String("asc"), - OrderBy: gitlab.String("created_at"), - }, - gitlab.WithContext(ctx), - ) - - if err != nil { - i.err = err - return false - } - - if len(notes) == 0 { - i.note.index = -1 - i.note.page = 1 - i.note.cache = nil - return false - } - - i.note.cache = notes - i.note.page++ - i.note.index = 0 - return true -} - -func (i *iterator) NextNote() bool { - if i.err != nil { - return false - } - - if i.ctx.Err() != nil { - return false - } - - if len(i.note.cache) == 0 { - return i.getNextNotes() - } - - // move cursor index - if i.note.index < len(i.note.cache)-1 { - i.note.index++ - return true - } - - return i.getNextNotes() -} - -func (i *iterator) NoteValue() *gitlab.Note { - return i.note.cache[i.note.index] -} - -func (i *iterator) getLabelEvents() bool { - ctx, cancel := context.WithTimeout(i.ctx, defaultTimeout) - defer cancel() - - // since order is not garanteed we should query all label events - // and sort them by ID - page := 1 - hasNextPage := true - for hasNextPage { - labelEvents, _, err := i.gc.ResourceLabelEvents.ListIssueLabelEvents( - i.project, - i.IssueValue().IID, - &gitlab.ListLabelEventsOptions{ - ListOptions: gitlab.ListOptions{ - Page: page, - PerPage: i.capacity, - }, - }, - gitlab.WithContext(ctx), - ) - if err != nil { - i.err = err - return false - } - - page++ - hasNextPage = len(labelEvents) != 0 - i.labelEvent.cache = append(i.labelEvent.cache, labelEvents...) - } - - i.labelEvent.index = 0 - sort.Sort(i.labelEvent) - - // if the label events list is empty return false - return len(i.labelEvent.cache) != 0 -} - -// because Gitlab -func (i *iterator) NextLabelEvent() bool { - if i.err != nil { - return false - } - - if i.ctx.Err() != nil { - return false - } - - if len(i.labelEvent.cache) == 0 { - return i.getLabelEvents() - } - - // move cursor index - if i.labelEvent.index < len(i.labelEvent.cache)-1 { - i.labelEvent.index++ - return true - } - - return false -} - -func (i *iterator) LabelEventValue() *gitlab.LabelEvent { - return i.labelEvent.cache[i.labelEvent.index] -} |