Skip to content

Commit

Permalink
Improve sorting Github release tags to handle empty string; no version
Browse files Browse the repository at this point in the history
  • Loading branch information
ivanfetch committed Dec 30, 2022
1 parent b34e95c commit 9718f35
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 27 deletions.
19 changes: 9 additions & 10 deletions github.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import (
"path/filepath"
"regexp"
"runtime"
"sort"
"strings"
)

Expand Down Expand Up @@ -132,21 +131,21 @@ func (g GithubReleases) MatchTagFromPartialVersion(pv string) (tag string, found
tags[i] = j.TagName
}
}
sort.Strings(tags)
sortedTags := sortVersions(tags)
LCPV := strings.ToLower(pv)
// Iterate the Github release tags backwards.
for i := len(tags) - 1; i >= 0; i-- {
LCThisTag := strings.ToLower(tags[i])
for i := len(sortedTags) - 1; i >= 0; i-- {
LCThisTag := strings.ToLower(sortedTags[i])
if strings.HasPrefix(LCThisTag, LCPV) || strings.HasPrefix(LCThisTag, "v"+LCPV) {
debugLog.Printf("matched tag %q for partial version %s\n", tags[i], pv)
return tags[i], true
debugLog.Printf("matched tag %q for partial version %s\n", sortedTags[i], pv)
return sortedTags[i], true
}
}
// Try matching with extraneous text removed from the beginning of the tag,
// like tags that include the repo or release name.
var stripPrefixRE *regexp.Regexp = regexp.MustCompile(`^[a-zA-Z-_]+(v?\d+\..*)`)
for i := len(tags) - 1; i >= 0; i-- {
LCThisTag := strings.ToLower(tags[i])
for i := len(sortedTags) - 1; i >= 0; i-- {
LCThisTag := strings.ToLower(sortedTags[i])
strippedMatches := stripPrefixRE.FindStringSubmatch(LCThisTag)
if strippedMatches == nil || len(strippedMatches) < 2 {
debugLog.Printf("cannot strip extraneous text from tag %q\n", LCThisTag)
Expand All @@ -155,8 +154,8 @@ func (g GithubReleases) MatchTagFromPartialVersion(pv string) (tag string, found
strippedTag := strippedMatches[1]
debugLog.Printf("the stripped tag is %q", strippedTag)
if strings.HasPrefix(strippedTag, LCPV) || strings.HasPrefix(strippedTag, "v"+LCPV) {
debugLog.Printf("matched tag %q after stripping prefix %q, for partial version %s\n", tags[i], strippedTag, pv)
return tags[i], true
debugLog.Printf("matched tag %q after stripping prefix %q, for partial version %s\n", sortedTags[i], strippedTag, pv)
return sortedTags[i], true
}
}
debugLog.Printf("no partial match for %s\n", pv)
Expand Down
4 changes: 4 additions & 0 deletions github_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ func TestGithubMatchTagFromPartialVersion(t *testing.T) {
ReleaseName: "1.0.2",
TagName: "1.0.2",
},
{
ReleaseName: "release with no version",
TagName: "",
},
{
ReleaseName: "1.0.3-rc1",
TagName: "1.0.3-rc1",
Expand Down
19 changes: 2 additions & 17 deletions toolmanaged.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ import (
"path/filepath"
"sort"
"strings"

hashicorpversion "github.com/hashicorp/go-version"
)

// managedTool represents a tool that JKL has already installed.
Expand Down Expand Up @@ -138,21 +136,8 @@ func (t managedTool) listInstalledVersions() (versions []string, found bool, err
if !found {
return nil, false, nil
}
sortedVersions := make([]*hashicorpversion.Version, len(versions))
for i, v := range versions {
hv, err := hashicorpversion.NewVersion(v)
if err != nil {
debugLog.Printf("using string-sort while listing installed versions - the version %q can't be converted to a version, probably because it starts with extraneous text", v)
sort.Strings(versions)
return versions, true, nil
}
sortedVersions[i] = hv
}
sort.Sort(hashicorpversion.Collection(sortedVersions))
for i, v := range sortedVersions { // reorder the original version strings by hashicorpversion.Version order
versions[i] = v.Original()
}
return versions, true, nil
sortedVersions := sortVersions(versions)
return sortedVersions, true, nil
}

// latestInstalledVersion returns the latest version number that is installed
Expand Down
30 changes: 30 additions & 0 deletions util.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ import (
"io/fs"
"os"
"path/filepath"
"sort"
"strings"

hashicorpversion "github.com/hashicorp/go-version"
)

// stringContainsOneOfLowerCase reports the first substring contained in s, returning
Expand Down Expand Up @@ -215,3 +218,30 @@ func getAliasesForOperatingSystem(OS string) []string {
}
return OSAliases[strings.ToLower(OS)]
}

// SortVersions returns the slice of strings sorted as semver version numbers.
// Any empty strings are replaced with version 0.0.0 before being sorted, to
// retain the size of the slice.
func sortVersions(versions []string) []string {
debugLog.Printf("sorting %d versions: %v", len(versions), versions)
sortedVersions := make([]*hashicorpversion.Version, len(versions))
for i, v := range versions {
if v == "" {
debugLog.Printf("WARNING: the version at index %d is an empty string, using 0.0.0 instead", i)
v = "0.0.0"
}
hv, err := hashicorpversion.NewVersion(v)
if err != nil {
debugLog.Printf("using string-sort while listing installed versions - the version %q can't be converted to a version, probably because it starts with extraneous text: %v", v, err)
sort.Strings(versions)
return versions
}
sortedVersions[i] = hv
}
sort.Sort(hashicorpversion.Collection(sortedVersions))
for i, v := range sortedVersions { // reorder the original version strings by hashicorpversion.Version order
versions[i] = v.Original()
}
debugLog.Printf("sorted versions are: %v", versions)
return versions
}

0 comments on commit 9718f35

Please sign in to comment.