61 lines
1.9 KiB
Go
61 lines
1.9 KiB
Go
package engineversion
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
|
|
"golang.org/x/mod/semver"
|
|
)
|
|
|
|
// ParseSemver normalises version into the canonical "vMAJOR.MINOR.PATCH"
|
|
// form expected by `golang.org/x/mod/semver` and reports a wrapped
|
|
// ErrInvalidSemver when the resulting string is not a valid full semver.
|
|
//
|
|
// Whitespace is trimmed; a missing leading "v" is added before the
|
|
// validity check so callers may pass either "1.2.3" or "v1.2.3". The
|
|
// stripped base must carry exactly three dot-separated numeric
|
|
// components — `golang.org/x/mod/semver` accepts shortened forms such
|
|
// as "v1" or "v1.2", but the engine-version registry requires the full
|
|
// triple, so this function rejects anything narrower.
|
|
func ParseSemver(version string) (string, error) {
|
|
candidate := strings.TrimSpace(version)
|
|
if candidate == "" {
|
|
return "", fmt.Errorf("%w: empty", ErrInvalidSemver)
|
|
}
|
|
if !strings.HasPrefix(candidate, "v") {
|
|
candidate = "v" + candidate
|
|
}
|
|
if !semver.IsValid(candidate) {
|
|
return "", fmt.Errorf("%w: %q", ErrInvalidSemver, version)
|
|
}
|
|
|
|
base := candidate
|
|
if i := strings.IndexAny(base, "-+"); i >= 0 {
|
|
base = base[:i]
|
|
}
|
|
if strings.Count(base, ".") != 2 {
|
|
return "", fmt.Errorf(
|
|
"%w: %q (need vMAJOR.MINOR.PATCH)",
|
|
ErrInvalidSemver, version,
|
|
)
|
|
}
|
|
return candidate, nil
|
|
}
|
|
|
|
// IsPatchUpgrade reports whether next is a same-major.minor upgrade of
|
|
// current. Both inputs are parsed through ParseSemver so callers may
|
|
// pass either bare or `v`-prefixed forms. A wrapped ErrInvalidSemver is
|
|
// returned when either argument fails to parse; the boolean result is
|
|
// undefined in that case.
|
|
func IsPatchUpgrade(current, next string) (bool, error) {
|
|
curr, err := ParseSemver(current)
|
|
if err != nil {
|
|
return false, fmt.Errorf("current: %w", err)
|
|
}
|
|
nxt, err := ParseSemver(next)
|
|
if err != nil {
|
|
return false, fmt.Errorf("next: %w", err)
|
|
}
|
|
return semver.MajorMinor(curr) == semver.MajorMinor(nxt), nil
|
|
}
|