aboutsummaryrefslogtreecommitdiffstats
path: root/bridge/gitlab/iterator/labelEvent.go
diff options
context:
space:
mode:
authorMichael Muré <batolettre@gmail.com>2020-03-28 21:09:36 +0100
committerMichael Muré <batolettre@gmail.com>2020-03-28 21:23:18 +0100
commitf4ca533fe10f7fa893e1953f8c8d9ed3e783486c (patch)
treef9fdaff8aa02f723acc3a4492d46655d63cbff5a /bridge/gitlab/iterator/labelEvent.go
parent38b42bc867f8f352908ba81334bec86b001e8fac (diff)
downloadgit-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.go99
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
+}