diff options
Diffstat (limited to 'vendor/github.com/Masterminds/semver/v3/version.go')
-rw-r--r-- | vendor/github.com/Masterminds/semver/v3/version.go | 639 |
1 files changed, 0 insertions, 639 deletions
diff --git a/vendor/github.com/Masterminds/semver/v3/version.go b/vendor/github.com/Masterminds/semver/v3/version.go deleted file mode 100644 index 7c4bed334..000000000 --- a/vendor/github.com/Masterminds/semver/v3/version.go +++ /dev/null @@ -1,639 +0,0 @@ -package semver - -import ( - "bytes" - "database/sql/driver" - "encoding/json" - "errors" - "fmt" - "regexp" - "strconv" - "strings" -) - -// The compiled version of the regex created at init() is cached here so it -// only needs to be created once. -var versionRegex *regexp.Regexp - -var ( - // ErrInvalidSemVer is returned a version is found to be invalid when - // being parsed. - ErrInvalidSemVer = errors.New("Invalid Semantic Version") - - // ErrEmptyString is returned when an empty string is passed in for parsing. - ErrEmptyString = errors.New("Version string empty") - - // ErrInvalidCharacters is returned when invalid characters are found as - // part of a version - ErrInvalidCharacters = errors.New("Invalid characters in version") - - // ErrSegmentStartsZero is returned when a version segment starts with 0. - // This is invalid in SemVer. - ErrSegmentStartsZero = errors.New("Version segment starts with 0") - - // ErrInvalidMetadata is returned when the metadata is an invalid format - ErrInvalidMetadata = errors.New("Invalid Metadata string") - - // ErrInvalidPrerelease is returned when the pre-release is an invalid format - ErrInvalidPrerelease = errors.New("Invalid Prerelease string") -) - -// semVerRegex is the regular expression used to parse a semantic version. -const semVerRegex string = `v?([0-9]+)(\.[0-9]+)?(\.[0-9]+)?` + - `(-([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?` + - `(\+([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?` - -// Version represents a single semantic version. -type Version struct { - major, minor, patch uint64 - pre string - metadata string - original string -} - -func init() { - versionRegex = regexp.MustCompile("^" + semVerRegex + "$") -} - -const ( - num string = "0123456789" - allowed string = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-" + num -) - -// StrictNewVersion parses a given version and returns an instance of Version or -// an error if unable to parse the version. Only parses valid semantic versions. -// Performs checking that can find errors within the version. -// If you want to coerce a version such as 1 or 1.2 and parse it as the 1.x -// releases of semver did, use the NewVersion() function. -func StrictNewVersion(v string) (*Version, error) { - // Parsing here does not use RegEx in order to increase performance and reduce - // allocations. - - if len(v) == 0 { - return nil, ErrEmptyString - } - - // Split the parts into [0]major, [1]minor, and [2]patch,prerelease,build - parts := strings.SplitN(v, ".", 3) - if len(parts) != 3 { - return nil, ErrInvalidSemVer - } - - sv := &Version{ - original: v, - } - - // check for prerelease or build metadata - var extra []string - if strings.ContainsAny(parts[2], "-+") { - // Start with the build metadata first as it needs to be on the right - extra = strings.SplitN(parts[2], "+", 2) - if len(extra) > 1 { - // build metadata found - sv.metadata = extra[1] - parts[2] = extra[0] - } - - extra = strings.SplitN(parts[2], "-", 2) - if len(extra) > 1 { - // prerelease found - sv.pre = extra[1] - parts[2] = extra[0] - } - } - - // Validate the number segments are valid. This includes only having positive - // numbers and no leading 0's. - for _, p := range parts { - if !containsOnly(p, num) { - return nil, ErrInvalidCharacters - } - - if len(p) > 1 && p[0] == '0' { - return nil, ErrSegmentStartsZero - } - } - - // Extract the major, minor, and patch elements onto the returned Version - var err error - sv.major, err = strconv.ParseUint(parts[0], 10, 64) - if err != nil { - return nil, err - } - - sv.minor, err = strconv.ParseUint(parts[1], 10, 64) - if err != nil { - return nil, err - } - - sv.patch, err = strconv.ParseUint(parts[2], 10, 64) - if err != nil { - return nil, err - } - - // No prerelease or build metadata found so returning now as a fastpath. - if sv.pre == "" && sv.metadata == "" { - return sv, nil - } - - if sv.pre != "" { - if err = validatePrerelease(sv.pre); err != nil { - return nil, err - } - } - - if sv.metadata != "" { - if err = validateMetadata(sv.metadata); err != nil { - return nil, err - } - } - - return sv, nil -} - -// NewVersion parses a given version and returns an instance of Version or -// an error if unable to parse the version. If the version is SemVer-ish it -// attempts to convert it to SemVer. If you want to validate it was a strict -// semantic version at parse time see StrictNewVersion(). -func NewVersion(v string) (*Version, error) { - m := versionRegex.FindStringSubmatch(v) - if m == nil { - return nil, ErrInvalidSemVer - } - - sv := &Version{ - metadata: m[8], - pre: m[5], - original: v, - } - - var err error - sv.major, err = strconv.ParseUint(m[1], 10, 64) - if err != nil { - return nil, fmt.Errorf("Error parsing version segment: %s", err) - } - - if m[2] != "" { - sv.minor, err = strconv.ParseUint(strings.TrimPrefix(m[2], "."), 10, 64) - if err != nil { - return nil, fmt.Errorf("Error parsing version segment: %s", err) - } - } else { - sv.minor = 0 - } - - if m[3] != "" { - sv.patch, err = strconv.ParseUint(strings.TrimPrefix(m[3], "."), 10, 64) - if err != nil { - return nil, fmt.Errorf("Error parsing version segment: %s", err) - } - } else { - sv.patch = 0 - } - - // Perform some basic due diligence on the extra parts to ensure they are - // valid. - - if sv.pre != "" { - if err = validatePrerelease(sv.pre); err != nil { - return nil, err - } - } - - if sv.metadata != "" { - if err = validateMetadata(sv.metadata); err != nil { - return nil, err - } - } - - return sv, nil -} - -// New creates a new instance of Version with each of the parts passed in as -// arguments instead of parsing a version string. -func New(major, minor, patch uint64, pre, metadata string) *Version { - v := Version{ - major: major, - minor: minor, - patch: patch, - pre: pre, - metadata: metadata, - original: "", - } - - v.original = v.String() - - return &v -} - -// MustParse parses a given version and panics on error. -func MustParse(v string) *Version { - sv, err := NewVersion(v) - if err != nil { - panic(err) - } - return sv -} - -// String converts a Version object to a string. -// Note, if the original version contained a leading v this version will not. -// See the Original() method to retrieve the original value. Semantic Versions -// don't contain a leading v per the spec. Instead it's optional on -// implementation. -func (v Version) String() string { - var buf bytes.Buffer - - fmt.Fprintf(&buf, "%d.%d.%d", v.major, v.minor, v.patch) - 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 value passed in to be parsed. -func (v *Version) Original() string { - return v.original -} - -// Major returns the major version. -func (v Version) Major() uint64 { - return v.major -} - -// Minor returns the minor version. -func (v Version) Minor() uint64 { - return v.minor -} - -// Patch returns the patch version. -func (v Version) Patch() uint64 { - return v.patch -} - -// Prerelease returns the pre-release version. -func (v Version) Prerelease() string { - return v.pre -} - -// Metadata returns the metadata on the version. -func (v Version) Metadata() string { - return v.metadata -} - -// originalVPrefix returns the original 'v' prefix if any. -func (v Version) originalVPrefix() string { - // Note, only lowercase v is supported as a prefix by the parser. - if v.original != "" && v.original[:1] == "v" { - return v.original[:1] - } - return "" -} - -// IncPatch produces the next patch version. -// If the current version does not have prerelease/metadata information, -// it unsets metadata and prerelease values, increments patch number. -// If the current version has any of prerelease or metadata information, -// it unsets both values and keeps current patch value -func (v Version) IncPatch() Version { - vNext := v - // according to http://semver.org/#spec-item-9 - // Pre-release versions have a lower precedence than the associated normal version. - // according to http://semver.org/#spec-item-10 - // Build metadata SHOULD be ignored when determining version precedence. - if v.pre != "" { - vNext.metadata = "" - vNext.pre = "" - } else { - vNext.metadata = "" - vNext.pre = "" - vNext.patch = v.patch + 1 - } - vNext.original = v.originalVPrefix() + "" + vNext.String() - return vNext -} - -// IncMinor produces the next minor version. -// Sets patch to 0. -// Increments minor number. -// Unsets metadata. -// Unsets prerelease status. -func (v Version) IncMinor() Version { - vNext := v - vNext.metadata = "" - vNext.pre = "" - vNext.patch = 0 - vNext.minor = v.minor + 1 - vNext.original = v.originalVPrefix() + "" + vNext.String() - return vNext -} - -// IncMajor produces the next major version. -// Sets patch to 0. -// Sets minor to 0. -// Increments major number. -// Unsets metadata. -// Unsets prerelease status. -func (v Version) IncMajor() Version { - vNext := v - vNext.metadata = "" - vNext.pre = "" - vNext.patch = 0 - vNext.minor = 0 - vNext.major = v.major + 1 - vNext.original = v.originalVPrefix() + "" + vNext.String() - return vNext -} - -// SetPrerelease defines the prerelease value. -// Value must not include the required 'hyphen' prefix. -func (v Version) SetPrerelease(prerelease string) (Version, error) { - vNext := v - if len(prerelease) > 0 { - if err := validatePrerelease(prerelease); err != nil { - return vNext, err - } - } - vNext.pre = prerelease - vNext.original = v.originalVPrefix() + "" + vNext.String() - return vNext, nil -} - -// SetMetadata defines metadata value. -// Value must not include the required 'plus' prefix. -func (v Version) SetMetadata(metadata string) (Version, error) { - vNext := v - if len(metadata) > 0 { - if err := validateMetadata(metadata); err != nil { - return vNext, err - } - } - vNext.metadata = metadata - vNext.original = v.originalVPrefix() + "" + vNext.String() - return vNext, nil -} - -// LessThan tests if one version is less than another one. -func (v *Version) LessThan(o *Version) bool { - return v.Compare(o) < 0 -} - -// GreaterThan tests if one version is greater than another one. -func (v *Version) GreaterThan(o *Version) bool { - return v.Compare(o) > 0 -} - -// Equal tests if two versions are equal to each other. -// Note, versions can be equal with different metadata since metadata -// is not considered part of the comparable version. -func (v *Version) Equal(o *Version) bool { - return v.Compare(o) == 0 -} - -// Compare compares this version to another one. It returns -1, 0, or 1 if -// the version smaller, equal, or larger than the other version. -// -// Versions are compared by X.Y.Z. Build metadata is ignored. Prerelease is -// lower than the version without a prerelease. Compare always takes into account -// prereleases. If you want to work with ranges using typical range syntaxes that -// skip prereleases if the range is not looking for them use constraints. -func (v *Version) Compare(o *Version) int { - // Compare the major, minor, and patch version for differences. If a - // difference is found return the comparison. - if d := compareSegment(v.Major(), o.Major()); d != 0 { - return d - } - if d := compareSegment(v.Minor(), o.Minor()); d != 0 { - return d - } - if d := compareSegment(v.Patch(), o.Patch()); d != 0 { - return d - } - - // At this point the major, minor, and patch versions are the same. - ps := v.pre - po := o.Prerelease() - - if ps == "" && po == "" { - return 0 - } - if ps == "" { - return 1 - } - if po == "" { - return -1 - } - - return comparePrerelease(ps, po) -} - -// UnmarshalJSON implements JSON.Unmarshaler interface. -func (v *Version) UnmarshalJSON(b []byte) error { - var s string - if err := json.Unmarshal(b, &s); err != nil { - return err - } - temp, err := NewVersion(s) - if err != nil { - return err - } - v.major = temp.major - v.minor = temp.minor - v.patch = temp.patch - v.pre = temp.pre - v.metadata = temp.metadata - v.original = temp.original - return nil -} - -// MarshalJSON implements JSON.Marshaler interface. -func (v Version) MarshalJSON() ([]byte, error) { - return json.Marshal(v.String()) -} - -// UnmarshalText implements the encoding.TextUnmarshaler interface. -func (v *Version) UnmarshalText(text []byte) error { - temp, err := NewVersion(string(text)) - if err != nil { - return err - } - - *v = *temp - - return nil -} - -// MarshalText implements the encoding.TextMarshaler interface. -func (v Version) MarshalText() ([]byte, error) { - return []byte(v.String()), nil -} - -// Scan implements the SQL.Scanner interface. -func (v *Version) Scan(value interface{}) error { - var s string - s, _ = value.(string) - temp, err := NewVersion(s) - if err != nil { - return err - } - v.major = temp.major - v.minor = temp.minor - v.patch = temp.patch - v.pre = temp.pre - v.metadata = temp.metadata - v.original = temp.original - return nil -} - -// Value implements the Driver.Valuer interface. -func (v Version) Value() (driver.Value, error) { - return v.String(), nil -} - -func compareSegment(v, o uint64) int { - if v < o { - return -1 - } - if v > o { - return 1 - } - - return 0 -} - -func comparePrerelease(v, o string) int { - // split the prelease versions by their part. The separator, per the spec, - // is a . - sparts := strings.Split(v, ".") - oparts := strings.Split(o, ".") - - // Find the longer length of the parts to know how many loop iterations to - // go through. - slen := len(sparts) - olen := len(oparts) - - l := slen - if olen > slen { - l = olen - } - - // Iterate over each part of the prereleases to compare the differences. - for i := 0; i < l; i++ { - // Since the lentgh of the parts can be different we need to create - // a placeholder. This is to avoid out of bounds issues. - stemp := "" - if i < slen { - stemp = sparts[i] - } - - otemp := "" - if i < olen { - otemp = oparts[i] - } - - d := comparePrePart(stemp, otemp) - if d != 0 { - return d - } - } - - // Reaching here means two versions are of equal value but have different - // metadata (the part following a +). They are not identical in string form - // but the version comparison finds them to be equal. - return 0 -} - -func comparePrePart(s, o string) int { - // Fastpath if they are equal - if s == o { - return 0 - } - - // When s or o are empty we can use the other in an attempt to determine - // the response. - if s == "" { - if o != "" { - return -1 - } - return 1 - } - - if o == "" { - if s != "" { - return 1 - } - return -1 - } - - // When comparing strings "99" is greater than "103". To handle - // cases like this we need to detect numbers and compare them. According - // to the semver spec, numbers are always positive. If there is a - at the - // start like -99 this is to be evaluated as an alphanum. numbers always - // have precedence over alphanum. Parsing as Uints because negative numbers - // are ignored. - - oi, n1 := strconv.ParseUint(o, 10, 64) - si, n2 := strconv.ParseUint(s, 10, 64) - - // The case where both are strings compare the strings - if n1 != nil && n2 != nil { - if s > o { - return 1 - } - return -1 - } else if n1 != nil { - // o is a string and s is a number - return -1 - } else if n2 != nil { - // s is a string and o is a number - return 1 - } - // Both are numbers - if si > oi { - return 1 - } - return -1 -} - -// Like strings.ContainsAny but does an only instead of any. -func containsOnly(s string, comp string) bool { - return strings.IndexFunc(s, func(r rune) bool { - return !strings.ContainsRune(comp, r) - }) == -1 -} - -// From the spec, "Identifiers MUST comprise only -// ASCII alphanumerics and hyphen [0-9A-Za-z-]. Identifiers MUST NOT be empty. -// Numeric identifiers MUST NOT include leading zeroes.". These segments can -// be dot separated. -func validatePrerelease(p string) error { - eparts := strings.Split(p, ".") - for _, p := range eparts { - if containsOnly(p, num) { - if len(p) > 1 && p[0] == '0' { - return ErrSegmentStartsZero - } - } else if !containsOnly(p, allowed) { - return ErrInvalidPrerelease - } - } - - return nil -} - -// From the spec, "Build metadata MAY be denoted by -// appending a plus sign and a series of dot separated identifiers immediately -// following the patch or pre-release version. Identifiers MUST comprise only -// ASCII alphanumerics and hyphen [0-9A-Za-z-]. Identifiers MUST NOT be empty." -func validateMetadata(m string) error { - eparts := strings.Split(m, ".") - for _, p := range eparts { - if !containsOnly(p, allowed) { - return ErrInvalidMetadata - } - } - return nil -} |