Refactoring: make snapshot sorting non-intrusive to collection contents. #168

This commit is contained in:
Andrey Smirnov
2015-01-22 22:01:00 +03:00
parent 7c3629337c
commit d828732307
5 changed files with 75 additions and 55 deletions
+26 -26
View File
@@ -2,10 +2,10 @@ package api
import ( import (
"fmt" "fmt"
"sort"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/smira/aptly/deb" "github.com/smira/aptly/deb"
"github.com/smira/aptly/query" "github.com/smira/aptly/query"
"sort"
) )
// GET /api/snapshots // GET /api/snapshots
@@ -16,12 +16,12 @@ func apiSnapshotsList(c *gin.Context) {
collection.RLock() collection.RLock()
defer collection.RUnlock() defer collection.RUnlock()
if SortMethodString != "" { if SortMethodString == "" {
collection.Sort(SortMethodString) SortMethodString = "name"
} }
result := []*deb.Snapshot{} result := []*deb.Snapshot{}
collection.ForEach(func(snapshot *deb.Snapshot) error { collection.ForEachSorted(SortMethodString, func(snapshot *deb.Snapshot) error {
result = append(result, snapshot) result = append(result, snapshot)
return nil return nil
}) })
@@ -32,14 +32,14 @@ func apiSnapshotsList(c *gin.Context) {
// POST /api/mirrors/:name/snapshots/ // POST /api/mirrors/:name/snapshots/
func apiSnapshotsCreateFromMirror(c *gin.Context) { func apiSnapshotsCreateFromMirror(c *gin.Context) {
var ( var (
err error err error
repo *deb.RemoteRepo repo *deb.RemoteRepo
snapshot *deb.Snapshot snapshot *deb.Snapshot
) )
var b struct { var b struct {
Name string `binding:"required"` Name string `binding:"required"`
Description string Description string
} }
if !c.Bind(&b) { if !c.Bind(&b) {
@@ -94,15 +94,15 @@ func apiSnapshotsCreateFromMirror(c *gin.Context) {
// POST /api/snapshots // POST /api/snapshots
func apiSnapshotsCreate(c *gin.Context) { func apiSnapshotsCreate(c *gin.Context) {
var ( var (
err error err error
snapshot *deb.Snapshot snapshot *deb.Snapshot
) )
var b struct { var b struct {
Name string `binding:"required"` Name string `binding:"required"`
Description string Description string
SourceIDs []string SourceIDs []string
PackageRefs []string PackageRefs []string
} }
if !c.Bind(&b) { if !c.Bind(&b) {
@@ -110,7 +110,7 @@ func apiSnapshotsCreate(c *gin.Context) {
} }
if b.Description == "" { if b.Description == "" {
if len(b.SourceIDs) + len(b.PackageRefs) == 0 { if len(b.SourceIDs)+len(b.PackageRefs) == 0 {
b.Description = "Created as empty" b.Description = "Created as empty"
} }
} }
@@ -119,23 +119,23 @@ func apiSnapshotsCreate(c *gin.Context) {
snapshotCollection.Lock() snapshotCollection.Lock()
defer snapshotCollection.Unlock() defer snapshotCollection.Unlock()
sources := make([]*deb.Snapshot, len(b.SourceIDs)) sources := make([]*deb.Snapshot, len(b.SourceIDs))
for i := 0; i < len(b.SourceIDs); i++ { for i := 0; i < len(b.SourceIDs); i++ {
sources[i], err = snapshotCollection.ByUUID(b.SourceIDs[i]) sources[i], err = snapshotCollection.ByUUID(b.SourceIDs[i])
if err != nil { if err != nil {
c.Fail(404, err) c.Fail(404, err)
return return
} }
err = snapshotCollection.LoadComplete(sources[i]) err = snapshotCollection.LoadComplete(sources[i])
if err != nil { if err != nil {
c.Fail(500, err) c.Fail(500, err)
return return
} }
} }
packageRefs := make([][]byte, len(b.PackageRefs)) packageRefs := make([][]byte, len(b.PackageRefs))
for i, ref := range b.PackageRefs { for i, ref := range b.PackageRefs {
packageRefs[i] = []byte(ref) packageRefs[i] = []byte(ref)
} }
@@ -155,14 +155,14 @@ func apiSnapshotsCreate(c *gin.Context) {
// POST /api/repos/:name/snapshots/:snapname // POST /api/repos/:name/snapshots/:snapname
func apiSnapshotsCreateFromRepository(c *gin.Context) { func apiSnapshotsCreateFromRepository(c *gin.Context) {
var ( var (
err error err error
repo *deb.LocalRepo repo *deb.LocalRepo
snapshot *deb.Snapshot snapshot *deb.Snapshot
) )
var b struct { var b struct {
Name string `binding:"required"` Name string `binding:"required"`
Description string Description string
} }
if !c.Bind(&b) { if !c.Bind(&b) {
+6 -3
View File
@@ -17,10 +17,9 @@ func aptlySnapshotList(cmd *commander.Command, args []string) error {
sortMethodString := cmd.Flag.Lookup("sort").Value.Get().(string) sortMethodString := cmd.Flag.Lookup("sort").Value.Get().(string)
collection := context.CollectionFactory().SnapshotCollection() collection := context.CollectionFactory().SnapshotCollection()
collection.Sort(sortMethodString)
if raw { if raw {
collection.ForEach(func(snapshot *deb.Snapshot) error { collection.ForEachSorted(sortMethodString, func(snapshot *deb.Snapshot) error {
fmt.Printf("%s\n", snapshot.Name) fmt.Printf("%s\n", snapshot.Name)
return nil return nil
}) })
@@ -28,11 +27,15 @@ func aptlySnapshotList(cmd *commander.Command, args []string) error {
if collection.Len() > 0 { if collection.Len() > 0 {
fmt.Printf("List of snapshots:\n") fmt.Printf("List of snapshots:\n")
collection.ForEach(func(snapshot *deb.Snapshot) error { err = collection.ForEachSorted(sortMethodString, func(snapshot *deb.Snapshot) error {
fmt.Printf(" * %s\n", snapshot.String()) fmt.Printf(" * %s\n", snapshot.String())
return nil return nil
}) })
if err != nil {
return err
}
fmt.Printf("\nTo get more information about snapshot, run `aptly snapshot show <name>`.\n") fmt.Printf("\nTo get more information about snapshot, run `aptly snapshot show <name>`.\n")
} else { } else {
fmt.Printf("\nNo snapshots found, create one with `aptly snapshot create...`.\n") fmt.Printf("\nNo snapshots found, create one with `aptly snapshot create...`.\n")
+39 -26
View File
@@ -297,6 +297,22 @@ func (collection *SnapshotCollection) ForEach(handler func(*Snapshot) error) err
return err return err
} }
func (collection *SnapshotCollection) ForEachSorted(sortMethod string, handler func(*Snapshot) error) error {
sorter, err := newSnapshotSorter(sortMethod, collection)
if err != nil {
return err
}
for _, i := range sorter.list {
err = handler(collection.list[i])
if err != nil {
return err
}
}
return nil
}
// Len returns number of snapshots in collection // Len returns number of snapshots in collection
// ForEach runs method for each snapshot // ForEach runs method for each snapshot
func (collection *SnapshotCollection) Len() int { func (collection *SnapshotCollection) Len() int {
@@ -335,51 +351,48 @@ const (
SortTime SortTime
) )
type snapshotListToSort struct { type snapshotSorter struct {
list []*Snapshot list []int
collection *SnapshotCollection
sortMethod int sortMethod int
} }
func parseSortMethod(sortMethod string) (int, error) { func newSnapshotSorter(sortMethod string, collection *SnapshotCollection) (*snapshotSorter, error) {
s := &snapshotSorter{collection: collection}
switch sortMethod { switch sortMethod {
case "time", "Time": case "time", "Time":
return SortTime, nil s.sortMethod = SortTime
case "name", "Name": case "name", "Name":
return SortName, nil s.sortMethod = SortName
default:
return nil, fmt.Errorf("sorting method \"%s\" unknown", sortMethod)
} }
return -1, fmt.Errorf("sorting method \"%s\" unknown", sortMethod) s.list = make([]int, len(collection.list))
for i := range s.list {
s.list[i] = i
}
sort.Sort(s)
return s, nil
} }
func (s snapshotListToSort) Swap(i, j int) { func (s *snapshotSorter) Swap(i, j int) {
s.list[i], s.list[j] = s.list[j], s.list[i] s.list[i], s.list[j] = s.list[j], s.list[i]
} }
func (s snapshotListToSort) Less(i, j int) bool { func (s *snapshotSorter) Less(i, j int) bool {
switch s.sortMethod { switch s.sortMethod {
case SortName: case SortName:
return s.list[i].Name < s.list[j].Name return s.collection.list[s.list[i]].Name < s.collection.list[s.list[j]].Name
case SortTime: case SortTime:
return s.list[i].CreatedAt.Before(s.list[j].CreatedAt) return s.collection.list[s.list[i]].CreatedAt.Before(s.collection.list[s.list[j]].CreatedAt)
} }
panic("unknown sort method") panic("unknown sort method")
} }
func (s snapshotListToSort) Len() int { func (s *snapshotSorter) Len() int {
return len(s.list) return len(s.list)
} }
func (collection *SnapshotCollection) Sort(sortMethodString string) error {
var err error
snapshotsToSort := &snapshotListToSort{}
snapshotsToSort.list = collection.list
snapshotsToSort.sortMethod, err = parseSortMethod(sortMethodString)
if err != nil {
return err
}
sort.Sort(snapshotsToSort)
collection.list = snapshotsToSort.list
return err
}
@@ -1 +1,2 @@
List of snapshots:
ERROR: sorting method "planet" unknown ERROR: sorting method "planet" unknown
+3
View File
@@ -87,5 +87,8 @@ class ListSnapshot7Test(BaseTest):
""" """
list snapshots: wrong parameter sort list snapshots: wrong parameter sort
""" """
fixtureCmds = [
"aptly snapshot create empty empty"
]
runCmd = "aptly -sort=planet snapshot list" runCmd = "aptly -sort=planet snapshot list"
expectedCode = 1 expectedCode = 1