labelEvent.go

  1package iterator
  2
  3import (
  4	"context"
  5	"sort"
  6
  7	"github.com/xanzy/go-gitlab"
  8)
  9
 10// Since Gitlab does not return the label events items in the correct order
 11// we need to sort the list ourselves and stop relying on the pagination model
 12// #BecauseGitlab
 13type labelEventIterator struct {
 14	issue int
 15	index int
 16	cache []*gitlab.LabelEvent
 17}
 18
 19func newLabelEventIterator() *labelEventIterator {
 20	lei := &labelEventIterator{}
 21	lei.Reset(-1)
 22	return lei
 23}
 24
 25func (lei *labelEventIterator) Next(ctx context.Context, conf config) (bool, error) {
 26	// first query
 27	if lei.cache == nil {
 28		return lei.getNext(ctx, conf)
 29	}
 30
 31	// move cursor index
 32	if lei.index < len(lei.cache)-1 {
 33		lei.index++
 34		return true, nil
 35	}
 36
 37	return false, nil
 38}
 39
 40func (lei *labelEventIterator) Value() *gitlab.LabelEvent {
 41	return lei.cache[lei.index]
 42}
 43
 44func (lei *labelEventIterator) getNext(ctx context.Context, conf config) (bool, error) {
 45	ctx, cancel := context.WithTimeout(ctx, conf.timeout)
 46	defer cancel()
 47
 48	// since order is not guaranteed we should query all label events
 49	// and sort them by ID
 50	page := 1
 51	for {
 52		labelEvents, resp, err := conf.gc.ResourceLabelEvents.ListIssueLabelEvents(
 53			conf.project,
 54			lei.issue,
 55			&gitlab.ListLabelEventsOptions{
 56				ListOptions: gitlab.ListOptions{
 57					Page:    page,
 58					PerPage: conf.capacity,
 59				},
 60			},
 61			gitlab.WithContext(ctx),
 62		)
 63		if err != nil {
 64			lei.Reset(-1)
 65			return false, err
 66		}
 67
 68		if len(labelEvents) == 0 {
 69			break
 70		}
 71
 72		lei.cache = append(lei.cache, labelEvents...)
 73
 74		if resp.TotalPages == page {
 75			break
 76		}
 77
 78		page++
 79	}
 80
 81	sort.Sort(lei)
 82	lei.index = 0
 83
 84	return len(lei.cache) > 0, nil
 85}
 86
 87func (lei *labelEventIterator) Reset(issue int) {
 88	lei.issue = issue
 89	lei.index = -1
 90	lei.cache = nil
 91}
 92
 93// ORDERING
 94
 95func (lei *labelEventIterator) Len() int {
 96	return len(lei.cache)
 97}
 98
 99func (lei *labelEventIterator) Swap(i, j int) {
100	lei.cache[i], lei.cache[j] = lei.cache[j], lei.cache[i]
101}
102
103func (lei *labelEventIterator) Less(i, j int) bool {
104	return lei.cache[i].ID < lei.cache[j].ID
105}