semver: add ByVersion and Sort for sorting semantic version lists
For golang/go#44969
Change-Id: I148a18b676061cd8ea481c3f5130d0792c0b5233
Reviewed-on: https://go-review.googlesource.com/c/mod/+/304151
Trust: Jay Conrod <jayconrod@google.com>
Run-TryBot: Jay Conrod <jayconrod@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Bryan C. Mills <bcmills@google.com>
diff --git a/semver/semver.go b/semver/semver.go
index 4338f35..7be398f 100644
--- a/semver/semver.go
+++ b/semver/semver.go
@@ -22,6 +22,8 @@
// as shorthands for vMAJOR.0.0 and vMAJOR.MINOR.0.
package semver
+import "sort"
+
// parsed returns the parsed form of a semantic version string.
type parsed struct {
major string
@@ -150,6 +152,24 @@
return w
}
+// ByVersion implements sort.Interface for sorting semantic version strings.
+type ByVersion []string
+
+func (vs ByVersion) Len() int { return len(vs) }
+func (vs ByVersion) Swap(i, j int) { vs[i], vs[j] = vs[j], vs[i] }
+func (vs ByVersion) Less(i, j int) bool {
+ cmp := Compare(vs[i], vs[j])
+ if cmp != 0 {
+ return cmp < 0
+ }
+ return vs[i] < vs[j]
+}
+
+// Sort sorts a list of semantic version strings using ByVersion.
+func Sort(list []string) {
+ sort.Sort(ByVersion(list))
+}
+
func parse(v string) (p parsed, ok bool) {
if v == "" || v[0] != 'v' {
p.err = "missing v prefix"
diff --git a/semver/semver_test.go b/semver/semver_test.go
index 77025a4..937e18e 100644
--- a/semver/semver_test.go
+++ b/semver/semver_test.go
@@ -5,6 +5,8 @@
package semver
import (
+ "math/rand"
+ "sort"
"strings"
"testing"
)
@@ -154,6 +156,18 @@
}
}
+func TestSort(t *testing.T) {
+ versions := make([]string, len(tests))
+ for i, test := range tests {
+ versions[i] = test.in
+ }
+ rand.Shuffle(len(versions), func(i, j int) { versions[i], versions[j] = versions[j], versions[i] })
+ Sort(versions)
+ if !sort.IsSorted(ByVersion(versions)) {
+ t.Errorf("list is not sorted:\n%s", strings.Join(versions, "\n"))
+ }
+}
+
func TestMax(t *testing.T) {
for i, ti := range tests {
for j, tj := range tests {