From 903549cadf40ede3771053781eb6e9fd31aaa64e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20Mur=C3=A9?= <batolettre@gmail.com>
Date: Sat, 4 Apr 2020 11:59:53 +0200
Subject: [PATCH] gitlab: fix iterator (paginate with first index 1) and avoid
 the trailing API call

---
 bridge/gitlab/iterator/issue.go      | 20 +++++++++++++++-----
 bridge/gitlab/iterator/labelEvent.go |  8 +++++++-
 bridge/gitlab/iterator/note.go       | 22 ++++++++++++++++------
 3 files changed, 38 insertions(+), 12 deletions(-)

diff --git a/bridge/gitlab/iterator/issue.go b/bridge/gitlab/iterator/issue.go
index a6bcebf1..9361b496 100644
--- a/bridge/gitlab/iterator/issue.go
+++ b/bridge/gitlab/iterator/issue.go
@@ -7,9 +7,10 @@ import (
 )
 
 type issueIterator struct {
-	page  int
-	index int
-	cache []*gitlab.Issue
+	page     int
+	lastPage bool
+	index    int
+	cache    []*gitlab.Issue
 }
 
 func newIssueIterator() *issueIterator {
@@ -38,10 +39,14 @@ func (ii *issueIterator) Value() *gitlab.Issue {
 }
 
 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, _, err := conf.gc.Issues.ListProjectIssues(
+	issues, resp, err := conf.gc.Issues.ListProjectIssues(
 		conf.project,
 		&gitlab.ListProjectIssuesOptions{
 			ListOptions: gitlab.ListOptions{
@@ -60,6 +65,10 @@ func (ii *issueIterator) getNext(ctx context.Context, conf config) (bool, error)
 		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
@@ -74,6 +83,7 @@ func (ii *issueIterator) getNext(ctx context.Context, conf config) (bool, error)
 
 func (ii *issueIterator) Reset() {
 	ii.index = -1
-	ii.page = -1
+	ii.page = 1
+	ii.lastPage = false
 	ii.cache = nil
 }
diff --git a/bridge/gitlab/iterator/labelEvent.go b/bridge/gitlab/iterator/labelEvent.go
index 7ee2604b..812e6646 100644
--- a/bridge/gitlab/iterator/labelEvent.go
+++ b/bridge/gitlab/iterator/labelEvent.go
@@ -49,7 +49,7 @@ func (lei *labelEventIterator) getNext(ctx context.Context, conf config) (bool,
 	// and sort them by ID
 	page := 1
 	for {
-		labelEvents, _, err := conf.gc.ResourceLabelEvents.ListIssueLabelEvents(
+		labelEvents, resp, err := conf.gc.ResourceLabelEvents.ListIssueLabelEvents(
 			conf.project,
 			lei.issue,
 			&gitlab.ListLabelEventsOptions{
@@ -68,7 +68,13 @@ func (lei *labelEventIterator) getNext(ctx context.Context, conf config) (bool,
 		if len(labelEvents) == 0 {
 			break
 		}
+
 		lei.cache = append(lei.cache, labelEvents...)
+
+		if resp.TotalPages == page {
+			break
+		}
+
 		page++
 	}
 
diff --git a/bridge/gitlab/iterator/note.go b/bridge/gitlab/iterator/note.go
index 486ca94e..a1e0544c 100644
--- a/bridge/gitlab/iterator/note.go
+++ b/bridge/gitlab/iterator/note.go
@@ -7,10 +7,11 @@ import (
 )
 
 type noteIterator struct {
-	issue int
-	page  int
-	index int
-	cache []*gitlab.Note
+	issue    int
+	page     int
+	lastPage bool
+	index    int
+	cache    []*gitlab.Note
 }
 
 func newNoteIterator() *noteIterator {
@@ -39,10 +40,14 @@ func (in *noteIterator) Value() *gitlab.Note {
 }
 
 func (in *noteIterator) getNext(ctx context.Context, conf config) (bool, error) {
+	if in.lastPage {
+		return false, nil
+	}
+
 	ctx, cancel := context.WithTimeout(ctx, conf.timeout)
 	defer cancel()
 
-	notes, _, err := conf.gc.Notes.ListIssueNotes(
+	notes, resp, err := conf.gc.Notes.ListIssueNotes(
 		conf.project,
 		in.issue,
 		&gitlab.ListIssueNotesOptions{
@@ -61,6 +66,10 @@ func (in *noteIterator) getNext(ctx context.Context, conf config) (bool, error)
 		return false, err
 	}
 
+	if resp.TotalPages == in.page {
+		in.lastPage = true
+	}
+
 	if len(notes) == 0 {
 		return false, nil
 	}
@@ -75,6 +84,7 @@ func (in *noteIterator) getNext(ctx context.Context, conf config) (bool, error)
 func (in *noteIterator) Reset(issue int) {
 	in.issue = issue
 	in.index = -1
-	in.page = -1
+	in.page = 1
+	in.lastPage = false
 	in.cache = nil
 }
-- 
GitLab