Skip to content

Commit

Permalink
fix: ensure deterministic results for SortBySemVer() (#559)
Browse files Browse the repository at this point in the history
Signed-off-by: Kent <kent.rancourt@gmail.com>
  • Loading branch information
krancour committed Jun 8, 2023
1 parent e372237 commit d1b92e9
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 4 deletions.
31 changes: 31 additions & 0 deletions pkg/tag/semver.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package tag

import "github.com/Masterminds/semver"

// semverCollection is a replacement for semver.Collection that breaks version
// comparison ties through a lexical comparison of the original version strings.
// Using this, instead of semver.Collection, when sorting will yield
// deterministic results that semver.Collection will not yield.
type semverCollection []*semver.Version

// Len returns the length of a collection. The number of Version instances
// on the slice.
func (s semverCollection) Len() int {
return len(s)
}

// Less is needed for the sort interface to compare two Version objects on the
// slice. If checks if one is less than the other.
func (s semverCollection) Less(i, j int) bool {
comp := s[i].Compare(s[j])
if comp != 0 {
return comp < 0
}
return s[i].Original() < s[j].Original()
}

// Swap is needed for the sort interface to replace the Version objects
// at two different positions in the slice.
func (s semverCollection) Swap(i, j int) {
s[i], s[j] = s[j], s[i]
}
2 changes: 1 addition & 1 deletion pkg/tag/tag.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ func (il ImageTagList) SortBySemVer() SortableImageTagList {
}
svl = append(svl, svi)
}
sort.Sort(semver.Collection(svl))
sort.Sort(semverCollection(svl))
for _, svi := range svl {
sil = append(sil, NewImageTag(svi.Original(), *il.items[svi.Original()].TagDate, il.items[svi.Original()].TagDigest))
}
Expand Down
7 changes: 4 additions & 3 deletions pkg/tag/tag_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ func Test_SortableImageTagList(t *testing.T) {
})

t.Run("Sort by semver", func(t *testing.T) {
names := []string{"v2.0.2", "v1.0", "v1.0.1", "v2.0.3", "v2.0"}
names := []string{"v2.0.2", "v1.0", "v2.0.0", "v1.0.1", "v2.0.3", "v2.0"}
il := NewImageTagList()
for _, name := range names {
tag := NewImageTag(name, time.Now(), "")
Expand All @@ -117,8 +117,9 @@ func Test_SortableImageTagList(t *testing.T) {
assert.Equal(t, "v1.0", sil[0].TagName)
assert.Equal(t, "v1.0.1", sil[1].TagName)
assert.Equal(t, "v2.0", sil[2].TagName)
assert.Equal(t, "v2.0.2", sil[3].TagName)
assert.Equal(t, "v2.0.3", sil[4].TagName)
assert.Equal(t, "v2.0.0", sil[3].TagName)
assert.Equal(t, "v2.0.2", sil[4].TagName)
assert.Equal(t, "v2.0.3", sil[5].TagName)
})

t.Run("Sort by date", func(t *testing.T) {
Expand Down

0 comments on commit d1b92e9

Please sign in to comment.