Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ go 1.22
toolchain go1.22.4

require (
github.com/Masterminds/semver/v3 v3.3.1
github.com/fatih/color v1.17.0
github.com/go-chi/chi/v5 v5.1.0
github.com/go-playground/validator/v10 v10.20.0
Expand All @@ -23,7 +24,6 @@ require (
require (
github.com/AlecAivazis/survey/v2 v2.3.7 // indirect
github.com/Masterminds/goutils v1.1.1 // indirect
github.com/Masterminds/semver/v3 v3.2.1 // indirect
github.com/Masterminds/sprig/v3 v3.2.3 // indirect
github.com/bahlo/generic-list-go v0.2.0 // indirect
github.com/buger/jsonparser v1.1.1 // indirect
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ github.com/AlecAivazis/survey/v2 v2.3.7/go.mod h1:xUTIdE4KCOIjsBAE1JYsUPoCqYdZ1r
github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI=
github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
github.com/Masterminds/semver/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ=
github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0=
github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ=
github.com/Masterminds/semver/v3 v3.3.1 h1:QtNSWtVZ3nBfk8mAOu/B6v7FMJ+NHTIgUPi7rj+4nv4=
github.com/Masterminds/semver/v3 v3.3.1/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
github.com/Masterminds/sprig/v3 v3.2.3 h1:eL2fZNezLomi0uOLqjQoN6BfsDD+fyLtgbJMAj9n6YA=
github.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBaRMhvYXJNkGuM=
github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2 h1:+vx7roKuyA63nhn5WAunQHLTznkw5W8b1Xc0dNjp83s=
Expand Down
97 changes: 4 additions & 93 deletions internal/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,106 +6,22 @@ import (
"io"
"net/http"
"os"
"regexp"
"strconv"
"strings"
"time"

"github.com/mattn/go-isatty"

"github.com/platformsh/cli/internal/config"
"github.com/platformsh/cli/internal/state"
"github.com/platformsh/cli/internal/version"
)

var versionRegex = regexp.MustCompile(`^(?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)(-(?P<preRelease>.+))?$`)

// ReleaseInfo stores information about a release
type ReleaseInfo struct {
Version string `json:"tag_name"`
URL string `json:"html_url"`
PublishedAt time.Time `json:"published_at"`
}

// Version contains parsed information about a SemVer version
type Version struct {
VersionParts [3]int
PreReleaseParts []string
}

// CompareVersions and see which version is greater
func CompareVersions(a, b *Version) int {
// Compare Major, Minor and Patch versions
for i := 0; i < 3; i++ {
if a.VersionParts[i] > b.VersionParts[i] {
return 1
}
if a.VersionParts[i] < b.VersionParts[i] {
return -1
}
}

// Start comparing identifiers
for i := 0; ; i++ {
// Check that there are identifiers left
if len(a.PreReleaseParts) <= i && len(b.PreReleaseParts) <= i {
return 0
}

// Shorter takes precedence
if len(b.PreReleaseParts) <= i {
return 1
}
if len(a.PreReleaseParts) <= i {
return -1
}

aPart := a.PreReleaseParts[i]
bPart := b.PreReleaseParts[i]
aInt, aErr := strconv.Atoi(aPart)
bInt, bErr := strconv.Atoi(bPart)

// Try comparing integers first
if aErr == nil && bErr == nil {
if aInt > bInt {
return 1
}
if aInt < bInt {
return -1
}
// Integer wins string
} else if aErr == nil {
return 1
} else if bErr == nil {
return -1
// Compare strings
} else if cmp := strings.Compare(aPart, bPart); cmp != 0 {
return cmp
}
}
}

// ParseVersion from a string, returning a Version or error if it's not SemVer
func ParseVersion(version string) (*Version, error) {
if !versionRegex.MatchString(version) {
return nil, fmt.Errorf("version does not match SemVer: %s", version)
}

result := versionRegex.FindStringSubmatch(version)
major, _ := strconv.Atoi(result[versionRegex.SubexpIndex("major")])
minor, _ := strconv.Atoi(result[versionRegex.SubexpIndex("minor")])
patch, _ := strconv.Atoi(result[versionRegex.SubexpIndex("patch")])
preRelease := result[versionRegex.SubexpIndex("preRelease")]
var preReleaseParts []string
if preRelease != "" {
preReleaseParts = strings.Split(preRelease, ".")
}

return &Version{
VersionParts: [3]int{major, minor, patch},
PreReleaseParts: preReleaseParts,
}, nil
}

// CheckForUpdate checks whether this software has had a newer release on GitHub
func CheckForUpdate(cnf *config.Config, currentVersion string) (*ReleaseInfo, error) {
if !shouldCheckForUpdate(cnf) {
Expand All @@ -130,16 +46,11 @@ func CheckForUpdate(cnf *config.Config, currentVersion string) (*ReleaseInfo, er
return nil, fmt.Errorf("could not determine latest release: %w", err)
}

currentVersionParsed, err := ParseVersion(currentVersion)
cmp, err := version.Compare(releaseInfo.Version, currentVersion)
if err != nil {
return nil, err
}

latestVersionParsed, err := ParseVersion(releaseInfo.Version)
if err != nil {
return nil, err
return nil, fmt.Errorf("could not compare versions: %w", err)
}
if CompareVersions(latestVersionParsed, currentVersionParsed) == 1 {
if cmp > 0 {
return releaseInfo, nil
}

Expand Down
128 changes: 0 additions & 128 deletions internal/update_test.go

This file was deleted.

26 changes: 26 additions & 0 deletions internal/version/version.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package version

import "github.com/Masterminds/semver/v3"

// Compare parses and compares two semantic version numbers.
// It returns -1, 0 or 1, representing whether v1 is less than, equal to or greater than v2.
func Compare(v1, v2 string) (int, error) {
if v1 == v2 {
return 0, nil
}
version1, err := semver.NewVersion(v1)
if err != nil {
return 0, err
}
version2, err := semver.NewVersion(v2)
if err != nil {
return 0, err
}
return version1.Compare(version2), nil
}

// Validate tests if a version number is valid.
func Validate(v string) bool {
_, err := semver.NewVersion(v)
return err == nil
}
Loading
Loading