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/labelEvent.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/labelEvent.go')
-rw-r--r-- | bridge/gitlab/iterator/labelEvent.go | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/bridge/gitlab/iterator/labelEvent.go b/bridge/gitlab/iterator/labelEvent.go new file mode 100644 index 00000000..7ee2604b --- /dev/null +++ b/bridge/gitlab/iterator/labelEvent.go @@ -0,0 +1,99 @@ +package iterator + +import ( + "context" + "sort" + + "github.com/xanzy/go-gitlab" +) + +// Since Gitlab does not return the label events items in the correct order +// we need to sort the list ourselves and stop relying on the pagination model +// #BecauseGitlab +type labelEventIterator struct { + issue int + index int + cache []*gitlab.LabelEvent +} + +func newLabelEventIterator() *labelEventIterator { + lei := &labelEventIterator{} + lei.Reset(-1) + return lei +} + +func (lei *labelEventIterator) Next(ctx context.Context, conf config) (bool, error) { + // first query + if lei.cache == nil { + return lei.getNext(ctx, conf) + } + + // move cursor index + if lei.index < len(lei.cache)-1 { + lei.index++ + return true, nil + } + + return false, nil +} + +func (lei *labelEventIterator) Value() *gitlab.LabelEvent { + return lei.cache[lei.index] +} + +func (lei *labelEventIterator) getNext(ctx context.Context, conf config) (bool, error) { + ctx, cancel := context.WithTimeout(ctx, conf.timeout) + defer cancel() + + // since order is not guaranteed we should query all label events + // and sort them by ID + page := 1 + for { + labelEvents, _, err := conf.gc.ResourceLabelEvents.ListIssueLabelEvents( + conf.project, + lei.issue, + &gitlab.ListLabelEventsOptions{ + ListOptions: gitlab.ListOptions{ + Page: page, + PerPage: conf.capacity, + }, + }, + gitlab.WithContext(ctx), + ) + if err != nil { + lei.Reset(-1) + return false, err + } + + if len(labelEvents) == 0 { + break + } + lei.cache = append(lei.cache, labelEvents...) + page++ + } + + sort.Sort(lei) + lei.index = 0 + + return len(lei.cache) > 0, nil +} + +func (lei *labelEventIterator) Reset(issue int) { + lei.issue = issue + lei.index = -1 + lei.cache = nil +} + +// ORDERING + +func (lei *labelEventIterator) Len() int { + return len(lei.cache) +} + +func (lei *labelEventIterator) Swap(i, j int) { + lei.cache[i], lei.cache[j] = lei.cache[j], lei.cache[i] +} + +func (lei *labelEventIterator) Less(i, j int) bool { + return lei.cache[i].ID < lei.cache[j].ID +} |