Skip to content
This repository has been archived by the owner on Aug 6, 2021. It is now read-only.

Commit

Permalink
Merge pull request #98 from thepwagner/semver-helpers
Browse files Browse the repository at this point in the history
semver helpers
  • Loading branch information
thepwagner authored Jul 2, 2021
2 parents b749e72 + 3cd7114 commit 17edc6c
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 0 deletions.
52 changes: 52 additions & 0 deletions version/semver.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package version

import (
"fmt"
"sort"
"strings"

"golang.org/x/mod/semver"
)

// Semverish coerces semver-ish strings to semver, or returns the empty string
func Semverish(s string) string {
if v := isValidWithV(s); v != "" {
return v
}

dots := strings.Split(s, ".")
if len(dots) > 3 {
normal := strings.Join(dots[:3], ".") + "-" + strings.Join(dots[3:], ".")
if v := isValidWithV(normal); v != "" {
return v
}
}

return ""
}

func isValidWithV(s string) string {
if semver.IsValid(s) {
return s
}

if vt := fmt.Sprintf("v%s", s); semver.IsValid(vt) {
return vt
}
return ""
}

// SemverSort is an descending sort of semver-ish version strings. The latest version is at index 0.
func SemverSort(versions []string) []string {
sort.Slice(versions, func(i, j int) bool {
// Prefer strict semver ordering:
if c := semver.Compare(Semverish(versions[i]), Semverish(versions[j])); c > 0 {
return true
} else if c < 0 {
return false
}
// Failing that, prefer the most specific version:
return strings.Count(versions[i], ".") > strings.Count(versions[j], ".")
})
return versions
}
51 changes: 51 additions & 0 deletions version/semver_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package version_test

import (
"testing"

"github.com/stretchr/testify/assert"
"github.com/thepwagner/action-update/version"
)

func TestSemverish(t *testing.T) {
tests := map[string]string{
"v1": "v1",
"1": "v1",
"1.0": "v1.0",
"1.0.0": "v1.0.0",
"1.0.0.0": "v1.0.0-0",
"1.0.0-beta": "v1.0.0-beta",
"1.0.0.beta": "v1.0.0-beta",
}
for in, expected := range tests {
t.Run(in, func(t *testing.T) {
assert.Equal(t, expected, version.Semverish(in))
})
}
}

func TestSemverSort(t *testing.T) {
tests := map[string]struct {
in []string
expected []string
}{
"semver": {
in: []string{"v3", "v1", "v2"},
expected: []string{"v3", "v2", "v1"},
},
"by specificity": {
in: []string{"v1.0", "v1", "v1.0.0"},
expected: []string{"v1.0.0", "v1.0", "v1"},
},
"semver-ish": {
in: []string{"3.0.3", "1.0.1", "2.0.2"},
expected: []string{"3.0.3", "2.0.2", "1.0.1"},
},
}

for lbl, tc := range tests {
t.Run(lbl, func(t *testing.T) {
assert.Equal(t, tc.expected, version.SemverSort(tc.in))
})
}
}

0 comments on commit 17edc6c

Please sign in to comment.