summaryrefslogtreecommitdiff
path: root/vendor/github.com/Masterminds/semver/v3/version.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/Masterminds/semver/v3/version.go')
-rw-r--r--vendor/github.com/Masterminds/semver/v3/version.go639
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
-}