[Vendor] Switch go-version lib (#12719)
* vendor: switch from "mcuadros/go-version" to "hashicorp/go-version" * Adapt P1 * simplify * fix lint * adapt * fix lint & rm old code * no deadlock * rm RWMutex and check GoVersion only 1-time * Copyright header Co-authored-by: techknowlogick <techknowlogick@gitea.io>
This commit is contained in:
parent
9fdb4f887b
commit
bc11caff94
35 changed files with 1134 additions and 966 deletions
384
vendor/github.com/hashicorp/go-version/version.go
generated
vendored
Normal file
384
vendor/github.com/hashicorp/go-version/version.go
generated
vendored
Normal file
|
@ -0,0 +1,384 @@
|
|||
package version
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// The compiled regular expression used to test the validity of a version.
|
||||
var (
|
||||
versionRegexp *regexp.Regexp
|
||||
semverRegexp *regexp.Regexp
|
||||
)
|
||||
|
||||
// The raw regular expression string used for testing the validity
|
||||
// of a version.
|
||||
const (
|
||||
VersionRegexpRaw string = `v?([0-9]+(\.[0-9]+)*?)` +
|
||||
`(-([0-9]+[0-9A-Za-z\-~]*(\.[0-9A-Za-z\-~]+)*)|(-?([A-Za-z\-~]+[0-9A-Za-z\-~]*(\.[0-9A-Za-z\-~]+)*)))?` +
|
||||
`(\+([0-9A-Za-z\-~]+(\.[0-9A-Za-z\-~]+)*))?` +
|
||||
`?`
|
||||
|
||||
// SemverRegexpRaw requires a separator between version and prerelease
|
||||
SemverRegexpRaw string = `v?([0-9]+(\.[0-9]+)*?)` +
|
||||
`(-([0-9]+[0-9A-Za-z\-~]*(\.[0-9A-Za-z\-~]+)*)|(-([A-Za-z\-~]+[0-9A-Za-z\-~]*(\.[0-9A-Za-z\-~]+)*)))?` +
|
||||
`(\+([0-9A-Za-z\-~]+(\.[0-9A-Za-z\-~]+)*))?` +
|
||||
`?`
|
||||
)
|
||||
|
||||
// Version represents a single version.
|
||||
type Version struct {
|
||||
metadata string
|
||||
pre string
|
||||
segments []int64
|
||||
si int
|
||||
original string
|
||||
}
|
||||
|
||||
func init() {
|
||||
versionRegexp = regexp.MustCompile("^" + VersionRegexpRaw + "$")
|
||||
semverRegexp = regexp.MustCompile("^" + SemverRegexpRaw + "$")
|
||||
}
|
||||
|
||||
// NewVersion parses the given version and returns a new
|
||||
// Version.
|
||||
func NewVersion(v string) (*Version, error) {
|
||||
return newVersion(v, versionRegexp)
|
||||
}
|
||||
|
||||
// NewSemver parses the given version and returns a new
|
||||
// Version that adheres strictly to SemVer specs
|
||||
// https://semver.org/
|
||||
func NewSemver(v string) (*Version, error) {
|
||||
return newVersion(v, semverRegexp)
|
||||
}
|
||||
|
||||
func newVersion(v string, pattern *regexp.Regexp) (*Version, error) {
|
||||
matches := pattern.FindStringSubmatch(v)
|
||||
if matches == nil {
|
||||
return nil, fmt.Errorf("Malformed version: %s", v)
|
||||
}
|
||||
segmentsStr := strings.Split(matches[1], ".")
|
||||
segments := make([]int64, len(segmentsStr))
|
||||
si := 0
|
||||
for i, str := range segmentsStr {
|
||||
val, err := strconv.ParseInt(str, 10, 64)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf(
|
||||
"Error parsing version: %s", err)
|
||||
}
|
||||
|
||||
segments[i] = int64(val)
|
||||
si++
|
||||
}
|
||||
|
||||
// Even though we could support more than three segments, if we
|
||||
// got less than three, pad it with 0s. This is to cover the basic
|
||||
// default usecase of semver, which is MAJOR.MINOR.PATCH at the minimum
|
||||
for i := len(segments); i < 3; i++ {
|
||||
segments = append(segments, 0)
|
||||
}
|
||||
|
||||
pre := matches[7]
|
||||
if pre == "" {
|
||||
pre = matches[4]
|
||||
}
|
||||
|
||||
return &Version{
|
||||
metadata: matches[10],
|
||||
pre: pre,
|
||||
segments: segments,
|
||||
si: si,
|
||||
original: v,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Must is a helper that wraps a call to a function returning (*Version, error)
|
||||
// and panics if error is non-nil.
|
||||
func Must(v *Version, err error) *Version {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return v
|
||||
}
|
||||
|
||||
// Compare compares this version to another version. This
|
||||
// returns -1, 0, or 1 if this version is smaller, equal,
|
||||
// or larger than the other version, respectively.
|
||||
//
|
||||
// If you want boolean results, use the LessThan, Equal,
|
||||
// GreaterThan, GreaterThanOrEqual or LessThanOrEqual methods.
|
||||
func (v *Version) Compare(other *Version) int {
|
||||
// A quick, efficient equality check
|
||||
if v.String() == other.String() {
|
||||
return 0
|
||||
}
|
||||
|
||||
segmentsSelf := v.Segments64()
|
||||
segmentsOther := other.Segments64()
|
||||
|
||||
// If the segments are the same, we must compare on prerelease info
|
||||
if reflect.DeepEqual(segmentsSelf, segmentsOther) {
|
||||
preSelf := v.Prerelease()
|
||||
preOther := other.Prerelease()
|
||||
if preSelf == "" && preOther == "" {
|
||||
return 0
|
||||
}
|
||||
if preSelf == "" {
|
||||
return 1
|
||||
}
|
||||
if preOther == "" {
|
||||
return -1
|
||||
}
|
||||
|
||||
return comparePrereleases(preSelf, preOther)
|
||||
}
|
||||
|
||||
// Get the highest specificity (hS), or if they're equal, just use segmentSelf length
|
||||
lenSelf := len(segmentsSelf)
|
||||
lenOther := len(segmentsOther)
|
||||
hS := lenSelf
|
||||
if lenSelf < lenOther {
|
||||
hS = lenOther
|
||||
}
|
||||
// Compare the segments
|
||||
// Because a constraint could have more/less specificity than the version it's
|
||||
// checking, we need to account for a lopsided or jagged comparison
|
||||
for i := 0; i < hS; i++ {
|
||||
if i > lenSelf-1 {
|
||||
// This means Self had the lower specificity
|
||||
// Check to see if the remaining segments in Other are all zeros
|
||||
if !allZero(segmentsOther[i:]) {
|
||||
// if not, it means that Other has to be greater than Self
|
||||
return -1
|
||||
}
|
||||
break
|
||||
} else if i > lenOther-1 {
|
||||
// this means Other had the lower specificity
|
||||
// Check to see if the remaining segments in Self are all zeros -
|
||||
if !allZero(segmentsSelf[i:]) {
|
||||
//if not, it means that Self has to be greater than Other
|
||||
return 1
|
||||
}
|
||||
break
|
||||
}
|
||||
lhs := segmentsSelf[i]
|
||||
rhs := segmentsOther[i]
|
||||
if lhs == rhs {
|
||||
continue
|
||||
} else if lhs < rhs {
|
||||
return -1
|
||||
}
|
||||
// Otherwis, rhs was > lhs, they're not equal
|
||||
return 1
|
||||
}
|
||||
|
||||
// if we got this far, they're equal
|
||||
return 0
|
||||
}
|
||||
|
||||
func allZero(segs []int64) bool {
|
||||
for _, s := range segs {
|
||||
if s != 0 {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func comparePart(preSelf string, preOther string) int {
|
||||
if preSelf == preOther {
|
||||
return 0
|
||||
}
|
||||
|
||||
var selfInt int64
|
||||
selfNumeric := true
|
||||
selfInt, err := strconv.ParseInt(preSelf, 10, 64)
|
||||
if err != nil {
|
||||
selfNumeric = false
|
||||
}
|
||||
|
||||
var otherInt int64
|
||||
otherNumeric := true
|
||||
otherInt, err = strconv.ParseInt(preOther, 10, 64)
|
||||
if err != nil {
|
||||
otherNumeric = false
|
||||
}
|
||||
|
||||
// if a part is empty, we use the other to decide
|
||||
if preSelf == "" {
|
||||
if otherNumeric {
|
||||
return -1
|
||||
}
|
||||
return 1
|
||||
}
|
||||
|
||||
if preOther == "" {
|
||||
if selfNumeric {
|
||||
return 1
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
if selfNumeric && !otherNumeric {
|
||||
return -1
|
||||
} else if !selfNumeric && otherNumeric {
|
||||
return 1
|
||||
} else if !selfNumeric && !otherNumeric && preSelf > preOther {
|
||||
return 1
|
||||
} else if selfInt > otherInt {
|
||||
return 1
|
||||
}
|
||||
|
||||
return -1
|
||||
}
|
||||
|
||||
func comparePrereleases(v string, other string) int {
|
||||
// the same pre release!
|
||||
if v == other {
|
||||
return 0
|
||||
}
|
||||
|
||||
// split both pre releases for analyse their parts
|
||||
selfPreReleaseMeta := strings.Split(v, ".")
|
||||
otherPreReleaseMeta := strings.Split(other, ".")
|
||||
|
||||
selfPreReleaseLen := len(selfPreReleaseMeta)
|
||||
otherPreReleaseLen := len(otherPreReleaseMeta)
|
||||
|
||||
biggestLen := otherPreReleaseLen
|
||||
if selfPreReleaseLen > otherPreReleaseLen {
|
||||
biggestLen = selfPreReleaseLen
|
||||
}
|
||||
|
||||
// loop for parts to find the first difference
|
||||
for i := 0; i < biggestLen; i = i + 1 {
|
||||
partSelfPre := ""
|
||||
if i < selfPreReleaseLen {
|
||||
partSelfPre = selfPreReleaseMeta[i]
|
||||
}
|
||||
|
||||
partOtherPre := ""
|
||||
if i < otherPreReleaseLen {
|
||||
partOtherPre = otherPreReleaseMeta[i]
|
||||
}
|
||||
|
||||
compare := comparePart(partSelfPre, partOtherPre)
|
||||
// if parts are equals, continue the loop
|
||||
if compare != 0 {
|
||||
return compare
|
||||
}
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
// Equal tests if two versions are equal.
|
||||
func (v *Version) Equal(o *Version) bool {
|
||||
if v == nil || o == nil {
|
||||
return v == o
|
||||
}
|
||||
|
||||
return v.Compare(o) == 0
|
||||
}
|
||||
|
||||
// GreaterThan tests if this version is greater than another version.
|
||||
func (v *Version) GreaterThan(o *Version) bool {
|
||||
return v.Compare(o) > 0
|
||||
}
|
||||
|
||||
// GreaterThanOrEqual tests if this version is greater than or equal to another version.
|
||||
func (v *Version) GreaterThanOrEqual(o *Version) bool {
|
||||
return v.Compare(o) >= 0
|
||||
}
|
||||
|
||||
// LessThan tests if this version is less than another version.
|
||||
func (v *Version) LessThan(o *Version) bool {
|
||||
return v.Compare(o) < 0
|
||||
}
|
||||
|
||||
// LessThanOrEqual tests if this version is less than or equal to another version.
|
||||
func (v *Version) LessThanOrEqual(o *Version) bool {
|
||||
return v.Compare(o) <= 0
|
||||
}
|
||||
|
||||
// Metadata returns any metadata that was part of the version
|
||||
// string.
|
||||
//
|
||||
// Metadata is anything that comes after the "+" in the version.
|
||||
// For example, with "1.2.3+beta", the metadata is "beta".
|
||||
func (v *Version) Metadata() string {
|
||||
return v.metadata
|
||||
}
|
||||
|
||||
// Prerelease returns any prerelease data that is part of the version,
|
||||
// or blank if there is no prerelease data.
|
||||
//
|
||||
// Prerelease information is anything that comes after the "-" in the
|
||||
// version (but before any metadata). For example, with "1.2.3-beta",
|
||||
// the prerelease information is "beta".
|
||||
func (v *Version) Prerelease() string {
|
||||
return v.pre
|
||||
}
|
||||
|
||||
// Segments returns the numeric segments of the version as a slice of ints.
|
||||
//
|
||||
// This excludes any metadata or pre-release information. For example,
|
||||
// for a version "1.2.3-beta", segments will return a slice of
|
||||
// 1, 2, 3.
|
||||
func (v *Version) Segments() []int {
|
||||
segmentSlice := make([]int, len(v.segments))
|
||||
for i, v := range v.segments {
|
||||
segmentSlice[i] = int(v)
|
||||
}
|
||||
return segmentSlice
|
||||
}
|
||||
|
||||
// Segments64 returns the numeric segments of the version as a slice of int64s.
|
||||
//
|
||||
// This excludes any metadata or pre-release information. For example,
|
||||
// for a version "1.2.3-beta", segments will return a slice of
|
||||
// 1, 2, 3.
|
||||
func (v *Version) Segments64() []int64 {
|
||||
result := make([]int64, len(v.segments))
|
||||
copy(result, v.segments)
|
||||
return result
|
||||
}
|
||||
|
||||
// String returns the full version string included pre-release
|
||||
// and metadata information.
|
||||
//
|
||||
// This value is rebuilt according to the parsed segments and other
|
||||
// information. Therefore, ambiguities in the version string such as
|
||||
// prefixed zeroes (1.04.0 => 1.4.0), `v` prefix (v1.0.0 => 1.0.0), and
|
||||
// missing parts (1.0 => 1.0.0) will be made into a canonicalized form
|
||||
// as shown in the parenthesized examples.
|
||||
func (v *Version) String() string {
|
||||
var buf bytes.Buffer
|
||||
fmtParts := make([]string, len(v.segments))
|
||||
for i, s := range v.segments {
|
||||
// We can ignore err here since we've pre-parsed the values in segments
|
||||
str := strconv.FormatInt(s, 10)
|
||||
fmtParts[i] = str
|
||||
}
|
||||
fmt.Fprintf(&buf, strings.Join(fmtParts, "."))
|
||||
if v.pre != "" {
|
||||
fmt.Fprintf(&buf, "-%s", v.pre)
|
||||
}
|
||||
if v.metadata != "" {
|
||||
fmt.Fprintf(&buf, "+%s", v.metadata)
|
||||
}
|
||||
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
// Original returns the original parsed version as-is, including any
|
||||
// potential whitespace, `v` prefix, etc.
|
||||
func (v *Version) Original() string {
|
||||
return v.original
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue