cache: provide a generic bug sorting function

Michael Muré created

Change summary

cache/repo_cache.go       | 67 ++++++------------------------------
cache/sorting.go          | 73 +++++++++++++++++++++++++++++++++++++++++
commands/ls.go            |  2 
graphql/resolvers/repo.go |  3 +
termui/bug_table.go       |  6 --
5 files changed, 89 insertions(+), 62 deletions(-)

Detailed changes

cache/repo_cache.go 🔗

@@ -8,7 +8,6 @@ import (
 	"io/ioutil"
 	"os"
 	"path"
-	"sort"
 	"strconv"
 	"strings"
 
@@ -154,6 +153,18 @@ func (c *RepoCache) buildAllExcerpt() {
 	}
 }
 
+func (c *RepoCache) allExcerpt() []BugExcerpt {
+	result := make([]BugExcerpt, len(c.excerpts))
+
+	i := 0
+	for _, val := range c.excerpts {
+		result[i] = val
+		i++
+	}
+
+	return result
+}
+
 func (c *RepoCache) ResolveBug(id string) (*BugCache, error) {
 	cached, ok := c.bugs[id]
 	if ok {
@@ -204,60 +215,6 @@ func (c *RepoCache) ResolveBugPrefix(prefix string) (*BugCache, error) {
 	return cached, nil
 }
 
-func (c *RepoCache) AllBugOrderById() []string {
-	result := make([]string, len(c.excerpts))
-
-	i := 0
-	for key := range c.excerpts {
-		result[i] = key
-		i++
-	}
-
-	sort.Strings(result)
-
-	return result
-}
-
-func (c *RepoCache) AllBugsOrderByEdit() []string {
-	excerpts := make([]BugExcerpt, len(c.excerpts))
-
-	i := 0
-	for _, val := range c.excerpts {
-		excerpts[i] = val
-		i++
-	}
-
-	sort.Sort(BugsByEditTime(excerpts))
-
-	result := make([]string, len(excerpts))
-
-	for i, val := range excerpts {
-		result[i] = val.Id
-	}
-
-	return result
-}
-
-func (c *RepoCache) AllBugsOrderByCreation() []string {
-	excerpts := make([]BugExcerpt, len(c.excerpts))
-
-	i := 0
-	for _, val := range c.excerpts {
-		excerpts[i] = val
-		i++
-	}
-
-	sort.Sort(BugsByCreationTime(excerpts))
-
-	result := make([]string, len(excerpts))
-
-	for i, val := range excerpts {
-		result[i] = val.Id
-	}
-
-	return result
-}
-
 // ClearAllBugs clear all bugs kept in memory
 func (c *RepoCache) ClearAllBugs() {
 	c.bugs = make(map[string]*BugCache)

cache/sorting.go 🔗

@@ -0,0 +1,73 @@
+package cache
+
+import "sort"
+
+type OrderBy int
+
+const (
+	_ OrderBy = iota
+	OrderById
+	OrderByCreation
+	OrderByEdit
+)
+
+type OrderDirection int
+
+const (
+	_ OrderDirection = iota
+	OrderAscending
+	OrderDescending
+)
+
+func (c *RepoCache) AllBugsId(order OrderBy, direction OrderDirection) []string {
+	if order == OrderById {
+		return c.orderIds(direction)
+	}
+
+	excerpts := c.allExcerpt()
+
+	var sorter sort.Interface
+
+	switch order {
+	case OrderByCreation:
+		sorter = BugsByCreationTime(excerpts)
+	case OrderByEdit:
+		sorter = BugsByEditTime(excerpts)
+	default:
+		panic("missing sort type")
+	}
+
+	if direction == OrderDescending {
+		sorter = sort.Reverse(sorter)
+	}
+
+	sort.Sort(sorter)
+
+	result := make([]string, len(excerpts))
+
+	for i, val := range excerpts {
+		result[i] = val.Id
+	}
+
+	return result
+}
+
+func (c *RepoCache) orderIds(direction OrderDirection) []string {
+	result := make([]string, len(c.excerpts))
+
+	i := 0
+	for key := range c.excerpts {
+		result[i] = key
+		i++
+	}
+
+	var sorter sort.Interface = sort.StringSlice(result)
+
+	if direction == OrderDescending {
+		sorter = sort.Reverse(sorter)
+	}
+
+	sort.Sort(sorter)
+
+	return result
+}

commands/ls.go 🔗

@@ -15,7 +15,7 @@ func runLsBug(cmd *cobra.Command, args []string) error {
 		return err
 	}
 
-	allIds := backend.AllBugsOrderByCreation()
+	allIds := backend.AllBugsId(cache.OrderByCreation, cache.OrderAscending)
 
 	for _, id := range allIds {
 		b, err := backend.ResolveBug(id)

graphql/resolvers/repo.go 🔗

@@ -4,6 +4,7 @@ import (
 	"context"
 
 	"github.com/MichaelMure/git-bug/bug"
+	"github.com/MichaelMure/git-bug/cache"
 	"github.com/MichaelMure/git-bug/graphql/connections"
 	"github.com/MichaelMure/git-bug/graphql/models"
 )
@@ -19,7 +20,7 @@ func (repoResolver) AllBugs(ctx context.Context, obj *models.Repository, after *
 	}
 
 	// Simply pass a []string with the ids to the pagination algorithm
-	source := obj.Repo.AllBugOrderById()
+	source := obj.Repo.AllBugsId(cache.OrderByCreation, cache.OrderAscending)
 
 	// The edger create a custom edge holding just the id
 	edger := func(id string, offset int) connections.Edge {

termui/bug_table.go 🔗

@@ -212,7 +212,7 @@ func (bt *bugTable) disable(g *gocui.Gui) error {
 }
 
 func (bt *bugTable) paginate(max int) error {
-	bt.allIds = bt.repo.AllBugsOrderByCreation()
+	bt.allIds = bt.repo.AllBugsId(cache.OrderByCreation, cache.OrderAscending)
 
 	return bt.doPaginate(max)
 }
@@ -355,8 +355,6 @@ func (bt *bugTable) cursorClamp(v *gocui.View) error {
 func (bt *bugTable) nextPage(g *gocui.Gui, v *gocui.View) error {
 	_, max := v.Size()
 
-	bt.allIds = bt.repo.AllBugsOrderByCreation()
-
 	if bt.pageCursor+max >= len(bt.allIds) {
 		return nil
 	}
@@ -369,8 +367,6 @@ func (bt *bugTable) nextPage(g *gocui.Gui, v *gocui.View) error {
 func (bt *bugTable) previousPage(g *gocui.Gui, v *gocui.View) error {
 	_, max := v.Size()
 
-	bt.allIds = bt.repo.AllBugsOrderByCreation()
-
 	bt.pageCursor = maxInt(0, bt.pageCursor-max)
 
 	return bt.doPaginate(max)