Skip to content

Commit 9f968b1

Browse files
authored
Merge pull request #16 from nicovillanueva/master
Natural-sort tags, sorting test, minimal typo
2 parents 9058632 + 0ab807d commit 9f968b1

5 files changed

Lines changed: 100 additions & 5 deletions

File tree

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.idea/
2+
.credentials
3+
.DS_Store

main.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,12 @@ func listTagsByImage(c *cli.Context) error {
168168
cli.ShowSubcommandHelp(c)
169169
}
170170
tags, err := r.ListTagsByImage(imgName)
171+
172+
compareStringNumber := func(str1, str2 string) bool {
173+
return extractNumberFromString(str1) < extractNumberFromString(str2)
174+
}
175+
Compare(compareStringNumber).Sort(tags)
176+
171177
if err != nil {
172178
return cli.NewExitError(err.Error(), 1)
173179
}
@@ -219,6 +225,10 @@ func deleteImage(c *cli.Context) error {
219225
cli.ShowSubcommandHelp(c)
220226
} else {
221227
tags, err := r.ListTagsByImage(imgName)
228+
compareStringNumber := func(str1, str2 string) bool {
229+
return extractNumberFromString(str1) < extractNumberFromString(str2)
230+
}
231+
Compare(compareStringNumber).Sort(tags)
222232
if err != nil {
223233
return cli.NewExitError(err.Error(), 1)
224234
}

registry/registry.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@ import (
44
"encoding/json"
55
"errors"
66
"fmt"
7+
"github.com/BurntSushi/toml"
78
"net/http"
89
"os"
9-
10-
"github.com/BurntSushi/toml"
1110
)
1211

1312
const ACCEPT_HEADER = "application/vnd.docker.distribution.manifest.v2+json"
13+
const CREDENTIALS_FILE = ".credentials"
1414

1515
type Registry struct {
1616
Host string `toml:"nexus_host"`
@@ -42,13 +42,13 @@ type LayerInfo struct {
4242

4343
func NewRegistry() (Registry, error) {
4444
r := Registry{}
45-
if _, err := os.Stat(".credentials"); os.IsNotExist(err) {
46-
return r, errors.New(".crendetials file not found\n")
45+
if _, err := os.Stat(CREDENTIALS_FILE); os.IsNotExist(err) {
46+
return r, errors.New(fmt.Sprintf("%s file not found\n", CREDENTIALS_FILE))
4747
} else if err != nil {
4848
return r, err
4949
}
5050

51-
if _, err := toml.DecodeFile(".credentials", &r); err != nil {
51+
if _, err := toml.DecodeFile(CREDENTIALS_FILE, &r); err != nil {
5252
return r, err
5353
}
5454
return r, nil

sorter.go

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package main
2+
3+
import (
4+
"log"
5+
"sort"
6+
"strconv"
7+
"strings"
8+
"unicode"
9+
)
10+
11+
// Almost completely ripped off https://www.socketloop.com/tutorials/golang-natural-string-sorting-example
12+
13+
type Compare func(str1, str2 string) bool
14+
15+
func (cmp Compare) Sort(strs []string) {
16+
strSort := &strSorter{
17+
strs: strs,
18+
cmp: cmp,
19+
}
20+
sort.Sort(strSort)
21+
}
22+
23+
type strSorter struct {
24+
strs []string
25+
cmp func(str1, str2 string) bool
26+
}
27+
28+
func extractNumberFromString(str string) (num int) {
29+
strSlice := make([]string, 0)
30+
for _, v := range str {
31+
if unicode.IsDigit(v) {
32+
strSlice = append(strSlice, string(v))
33+
}
34+
}
35+
36+
// If the tag was all non-digits, the strSlice would be empty (e.g., 'latest')
37+
// therefore just throw it to the end (1 << 32 is maxint)
38+
if len(strSlice) == 0 {
39+
return 1 << 32
40+
}
41+
42+
num, err := strconv.Atoi(strings.Join(strSlice, ""))
43+
if err != nil {
44+
log.Fatal(err)
45+
}
46+
return num
47+
}
48+
49+
func (s *strSorter) Len() int { return len(s.strs) }
50+
51+
func (s *strSorter) Swap(i, j int) { s.strs[i], s.strs[j] = s.strs[j], s.strs[i] }
52+
53+
func (s *strSorter) Less(i, j int) bool { return s.cmp(s.strs[i], s.strs[j]) }

sorter_test.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package main
2+
3+
import "testing"
4+
5+
func Test_SortMixed(t *testing.T) {
6+
tags := []string{"latest", "1.0.1"}
7+
8+
compareStringNumber := func(str1, str2 string) bool {
9+
return extractNumberFromString(str1) < extractNumberFromString(str2)
10+
}
11+
Compare(compareStringNumber).Sort(tags)
12+
13+
if tags[0] != "1.0.1" && tags[1] != "latest" {
14+
t.Errorf("ordering incorrect when checking mixed tags")
15+
}
16+
}
17+
18+
func Test_SortAllDigits(t *testing.T) {
19+
tags := []string{"1.2.1", "1.0.1"}
20+
21+
compareStringNumber := func(str1, str2 string) bool {
22+
return extractNumberFromString(str1) < extractNumberFromString(str2)
23+
}
24+
Compare(compareStringNumber).Sort(tags)
25+
26+
if tags[0] != "1.0.1" && tags[1] != "1.2.1" {
27+
t.Errorf("ordering incorrect in all digits tags")
28+
}
29+
}

0 commit comments

Comments
 (0)