From e974fbbc2c614b45f72b56c6c5d9be8874df89cb Mon Sep 17 00:00:00 2001 From: Ian Fijolek Date: Fri, 13 Jan 2023 15:03:24 -0800 Subject: [PATCH] Add sorting for prefixed semver Strips non-numeric prefixes when checking semver. This also adds a secondary layer to the sort whereby identical semvers are sorted relative to eachother lexigraphically. This will ensure a more stable sort for non-versioned tags (eg. `latest` or `edge`) as well as multiple variants tagged with the same number. (eg `1.0.0-alpine` compared to `1.0.0-ubuntu`). Fixes #758 --- pkg/registry/tags_sort.go | 15 +++++++++++---- pkg/registry/tags_test.go | 10 ++++++++++ 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/pkg/registry/tags_sort.go b/pkg/registry/tags_sort.go index 184e743e..2cd0c62b 100644 --- a/pkg/registry/tags_sort.go +++ b/pkg/registry/tags_sort.go @@ -4,6 +4,7 @@ import ( "fmt" "sort" "strings" + "unicode" "golang.org/x/mod/semver" ) @@ -22,9 +23,9 @@ func SortTags(tags []string, sortTag SortTag) []string { return tags case SortTagSemver: semverIsh := func(s string) string { - if semver.IsValid(s) { - return s - } + s = strings.TrimLeftFunc(s, func(r rune) bool { + return !unicode.IsNumber(r) + }) if vt := fmt.Sprintf("v%s", s); semver.IsValid(vt) { return vt } @@ -36,7 +37,13 @@ func SortTags(tags []string, sortTag SortTag) []string { } else if c < 0 { return false } - return strings.Count(tags[i], ".") > strings.Count(tags[j], ".") + if c := strings.Count(tags[i], ".") - strings.Count(tags[j], "."); c > 0 { + return true + } else if c < 0 { + return false + } + + return strings.Compare(tags[i], tags[j]) < 0 }) return tags default: diff --git a/pkg/registry/tags_test.go b/pkg/registry/tags_test.go index 943ae21a..a077bd7b 100644 --- a/pkg/registry/tags_test.go +++ b/pkg/registry/tags_test.go @@ -60,6 +60,8 @@ func TestTagsSort(t *testing.T) { "4.8.0", "4.8.1", "4.9.0", + "ubuntu-5.0", + "alpine-5.0", "edge", "latest", } @@ -103,6 +105,8 @@ func TestTagsSort(t *testing.T) { "4.8.0", "4.8.1", "4.9.0", + "ubuntu-5.0", + "alpine-5.0", "edge", "latest", }, @@ -141,16 +145,20 @@ func TestTagsSort(t *testing.T) { "4.8.0", "4.8.1", "4.9.0", + "alpine-5.0", "edge", "latest", + "ubuntu-5.0", }, }, { name: "sort reverse", sortTag: registry.SortTagReverse, expected: []string{ + "ubuntu-5.0", "latest", "edge", + "alpine-5.0", "4.9.0", "4.8.1", "4.8.0", @@ -187,6 +195,8 @@ func TestTagsSort(t *testing.T) { name: "sort semver", sortTag: registry.SortTagSemver, expected: []string{ + "alpine-5.0", + "ubuntu-5.0", "4.21.0", "4.21", "4.20.1",