mirror of
https://github.com/containers/skopeo.git
synced 2025-08-11 11:22:05 +00:00
Update module github.com/Masterminds/semver/v3 to v3.4.0
Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
This commit is contained in:
parent
a4ab531365
commit
ef2375bc80
2
go.mod
2
go.mod
@ -6,7 +6,7 @@ go 1.23.3
|
||||
// Warning: Ensure the "go" and "toolchain" versions match exactly to prevent unwanted auto-updates
|
||||
|
||||
require (
|
||||
github.com/Masterminds/semver/v3 v3.3.1
|
||||
github.com/Masterminds/semver/v3 v3.4.0
|
||||
github.com/containers/common v0.63.1
|
||||
github.com/containers/image/v5 v5.35.0
|
||||
github.com/containers/ocicrypt v1.2.1
|
||||
|
4
go.sum
4
go.sum
@ -8,8 +8,8 @@ github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg6
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg=
|
||||
github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
|
||||
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/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0=
|
||||
github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
|
||||
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
|
||||
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
|
||||
github.com/Microsoft/hcsshim v0.12.9 h1:2zJy5KA+l0loz1HzEGqyNnjd3fyZA31ZBCGKacp6lLg=
|
||||
|
28
vendor/github.com/Masterminds/semver/v3/CHANGELOG.md
generated
vendored
28
vendor/github.com/Masterminds/semver/v3/CHANGELOG.md
generated
vendored
@ -1,5 +1,31 @@
|
||||
# Changelog
|
||||
|
||||
## 3.4.0 (2025-06-27)
|
||||
|
||||
### Added
|
||||
|
||||
- #268: Added property to Constraints to include prereleases for Check and Validate
|
||||
|
||||
### Changed
|
||||
|
||||
- #263: Updated Go testing for 1.24, 1.23, and 1.22
|
||||
- #269: Updated the error message handling for message case and wrapping errors
|
||||
- #266: Restore the ability to have leading 0's when parsing with NewVersion.
|
||||
Opt-out of this by setting CoerceNewVersion to false.
|
||||
|
||||
### Fixed
|
||||
|
||||
- #257: Fixed the CodeQL link (thanks @dmitris)
|
||||
- #262: Restored detailed errors when failed to parse with NewVersion. Opt-out
|
||||
of this by setting DetailedNewVersionErrors to false for faster performance.
|
||||
- #267: Handle pre-releases for an "and" group if one constraint includes them
|
||||
|
||||
## 3.3.1 (2024-11-19)
|
||||
|
||||
### Fixed
|
||||
|
||||
- #253: Fix for allowing some version that were invalid
|
||||
|
||||
## 3.3.0 (2024-08-27)
|
||||
|
||||
### Added
|
||||
@ -137,7 +163,7 @@ functions. These are described in the added and changed sections below.
|
||||
- #78: Fix unchecked error in example code (thanks @ravron)
|
||||
- #70: Fix the handling of pre-releases and the 0.0.0 release edge case
|
||||
- #97: Fixed copyright file for proper display on GitHub
|
||||
- #107: Fix handling prerelease when sorting alphanum and num
|
||||
- #107: Fix handling prerelease when sorting alphanum and num
|
||||
- #109: Fixed where Validate sometimes returns wrong message on error
|
||||
|
||||
## 1.4.2 (2018-04-10)
|
||||
|
18
vendor/github.com/Masterminds/semver/v3/README.md
generated
vendored
18
vendor/github.com/Masterminds/semver/v3/README.md
generated
vendored
@ -50,6 +50,18 @@ other versions, convert the version back into a string, and get the original
|
||||
string. Getting the original string is useful if the semantic version was coerced
|
||||
into a valid form.
|
||||
|
||||
There are package level variables that affect how `NewVersion` handles parsing.
|
||||
|
||||
- `CoerceNewVersion` is `true` by default. When set to `true` it coerces non-compliant
|
||||
versions into SemVer. For example, allowing a leading 0 in a major, minor, or patch
|
||||
part. This enables the use of CalVer in versions even when not compliant with SemVer.
|
||||
When set to `false` less coercion work is done.
|
||||
- `DetailedNewVersionErrors` provides more detailed errors. It only has an affect when
|
||||
`CoerceNewVersion` is set to `false`. When `DetailedNewVersionErrors` is set to `true`
|
||||
it can provide some more insight into why a version is invalid. Setting
|
||||
`DetailedNewVersionErrors` to `false` is faster on performance but provides less
|
||||
detailed error messages if a version fails to parse.
|
||||
|
||||
## Sorting Semantic Versions
|
||||
|
||||
A set of versions can be sorted using the `sort` package from the standard library.
|
||||
@ -160,6 +172,10 @@ means `>=1.2.3-BETA` will return `1.2.3-alpha`. What you might expect from case
|
||||
sensitivity doesn't apply here. This is due to ASCII sort ordering which is what
|
||||
the spec specifies.
|
||||
|
||||
The `Constraints` instance returned from `semver.NewConstraint()` has a property
|
||||
`IncludePrerelease` that, when set to true, will return prerelease versions when calls
|
||||
to `Check()` and `Validate()` are made.
|
||||
|
||||
### Hyphen Range Comparisons
|
||||
|
||||
There are multiple methods to handle ranges and the first is hyphens ranges.
|
||||
@ -250,7 +266,7 @@ or [create a pull request](https://github.com/Masterminds/semver/pulls).
|
||||
Security is an important consideration for this project. The project currently
|
||||
uses the following tools to help discover security issues:
|
||||
|
||||
* [CodeQL](https://github.com/Masterminds/semver)
|
||||
* [CodeQL](https://codeql.github.com)
|
||||
* [gosec](https://github.com/securego/gosec)
|
||||
* Daily Fuzz testing
|
||||
|
||||
|
127
vendor/github.com/Masterminds/semver/v3/constraints.go
generated
vendored
127
vendor/github.com/Masterminds/semver/v3/constraints.go
generated
vendored
@ -12,6 +12,13 @@ import (
|
||||
// checked against.
|
||||
type Constraints struct {
|
||||
constraints [][]*constraint
|
||||
containsPre []bool
|
||||
|
||||
// IncludePrerelease specifies if pre-releases should be included in
|
||||
// the results. Note, if a constraint range has a prerelease than
|
||||
// prereleases will be included for that AND group even if this is
|
||||
// set to false.
|
||||
IncludePrerelease bool
|
||||
}
|
||||
|
||||
// NewConstraint returns a Constraints instance that a Version instance can
|
||||
@ -22,11 +29,10 @@ func NewConstraint(c string) (*Constraints, error) {
|
||||
c = rewriteRange(c)
|
||||
|
||||
ors := strings.Split(c, "||")
|
||||
or := make([][]*constraint, len(ors))
|
||||
lenors := len(ors)
|
||||
or := make([][]*constraint, lenors)
|
||||
hasPre := make([]bool, lenors)
|
||||
for k, v := range ors {
|
||||
|
||||
// TODO: Find a way to validate and fetch all the constraints in a simpler form
|
||||
|
||||
// Validate the segment
|
||||
if !validConstraintRegex.MatchString(v) {
|
||||
return nil, fmt.Errorf("improper constraint: %s", v)
|
||||
@ -43,12 +49,22 @@ func NewConstraint(c string) (*Constraints, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// If one of the constraints has a prerelease record this.
|
||||
// This information is used when checking all in an "and"
|
||||
// group to ensure they all check for prereleases.
|
||||
if pc.con.pre != "" {
|
||||
hasPre[k] = true
|
||||
}
|
||||
|
||||
result[i] = pc
|
||||
}
|
||||
or[k] = result
|
||||
}
|
||||
|
||||
o := &Constraints{constraints: or}
|
||||
o := &Constraints{
|
||||
constraints: or,
|
||||
containsPre: hasPre,
|
||||
}
|
||||
return o, nil
|
||||
}
|
||||
|
||||
@ -57,10 +73,10 @@ func (cs Constraints) Check(v *Version) bool {
|
||||
// TODO(mattfarina): For v4 of this library consolidate the Check and Validate
|
||||
// functions as the underlying functions make that possible now.
|
||||
// loop over the ORs and check the inner ANDs
|
||||
for _, o := range cs.constraints {
|
||||
for i, o := range cs.constraints {
|
||||
joy := true
|
||||
for _, c := range o {
|
||||
if check, _ := c.check(v); !check {
|
||||
if check, _ := c.check(v, (cs.IncludePrerelease || cs.containsPre[i])); !check {
|
||||
joy = false
|
||||
break
|
||||
}
|
||||
@ -83,12 +99,12 @@ func (cs Constraints) Validate(v *Version) (bool, []error) {
|
||||
// Capture the prerelease message only once. When it happens the first time
|
||||
// this var is marked
|
||||
var prerelesase bool
|
||||
for _, o := range cs.constraints {
|
||||
for i, o := range cs.constraints {
|
||||
joy := true
|
||||
for _, c := range o {
|
||||
// Before running the check handle the case there the version is
|
||||
// a prerelease and the check is not searching for prereleases.
|
||||
if c.con.pre == "" && v.pre != "" {
|
||||
if !(cs.IncludePrerelease || cs.containsPre[i]) && v.pre != "" {
|
||||
if !prerelesase {
|
||||
em := fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v)
|
||||
e = append(e, em)
|
||||
@ -98,7 +114,7 @@ func (cs Constraints) Validate(v *Version) (bool, []error) {
|
||||
|
||||
} else {
|
||||
|
||||
if _, err := c.check(v); err != nil {
|
||||
if _, err := c.check(v, (cs.IncludePrerelease || cs.containsPre[i])); err != nil {
|
||||
e = append(e, err)
|
||||
joy = false
|
||||
}
|
||||
@ -227,8 +243,8 @@ type constraint struct {
|
||||
}
|
||||
|
||||
// Check if a version meets the constraint
|
||||
func (c *constraint) check(v *Version) (bool, error) {
|
||||
return constraintOps[c.origfunc](v, c)
|
||||
func (c *constraint) check(v *Version, includePre bool) (bool, error) {
|
||||
return constraintOps[c.origfunc](v, c, includePre)
|
||||
}
|
||||
|
||||
// String prints an individual constraint into a string
|
||||
@ -236,7 +252,7 @@ func (c *constraint) string() string {
|
||||
return c.origfunc + c.orig
|
||||
}
|
||||
|
||||
type cfunc func(v *Version, c *constraint) (bool, error)
|
||||
type cfunc func(v *Version, c *constraint, includePre bool) (bool, error)
|
||||
|
||||
func parseConstraint(c string) (*constraint, error) {
|
||||
if len(c) > 0 {
|
||||
@ -272,7 +288,7 @@ func parseConstraint(c string) (*constraint, error) {
|
||||
|
||||
// The constraintRegex should catch any regex parsing errors. So,
|
||||
// we should never get here.
|
||||
return nil, errors.New("constraint Parser Error")
|
||||
return nil, errors.New("constraint parser error")
|
||||
}
|
||||
|
||||
cs.con = con
|
||||
@ -290,7 +306,7 @@ func parseConstraint(c string) (*constraint, error) {
|
||||
|
||||
// The constraintRegex should catch any regex parsing errors. So,
|
||||
// we should never get here.
|
||||
return nil, errors.New("constraint Parser Error")
|
||||
return nil, errors.New("constraint parser error")
|
||||
}
|
||||
|
||||
cs := &constraint{
|
||||
@ -305,16 +321,14 @@ func parseConstraint(c string) (*constraint, error) {
|
||||
}
|
||||
|
||||
// Constraint functions
|
||||
func constraintNotEqual(v *Version, c *constraint) (bool, error) {
|
||||
func constraintNotEqual(v *Version, c *constraint, includePre bool) (bool, error) {
|
||||
// The existence of prereleases is checked at the group level and passed in.
|
||||
// Exit early if the version has a prerelease but those are to be ignored.
|
||||
if v.Prerelease() != "" && !includePre {
|
||||
return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v)
|
||||
}
|
||||
|
||||
if c.dirty {
|
||||
|
||||
// If there is a pre-release on the version but the constraint isn't looking
|
||||
// for them assume that pre-releases are not compatible. See issue 21 for
|
||||
// more details.
|
||||
if v.Prerelease() != "" && c.con.Prerelease() == "" {
|
||||
return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v)
|
||||
}
|
||||
|
||||
if c.con.Major() != v.Major() {
|
||||
return true, nil
|
||||
}
|
||||
@ -345,12 +359,11 @@ func constraintNotEqual(v *Version, c *constraint) (bool, error) {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func constraintGreaterThan(v *Version, c *constraint) (bool, error) {
|
||||
func constraintGreaterThan(v *Version, c *constraint, includePre bool) (bool, error) {
|
||||
|
||||
// If there is a pre-release on the version but the constraint isn't looking
|
||||
// for them assume that pre-releases are not compatible. See issue 21 for
|
||||
// more details.
|
||||
if v.Prerelease() != "" && c.con.Prerelease() == "" {
|
||||
// The existence of prereleases is checked at the group level and passed in.
|
||||
// Exit early if the version has a prerelease but those are to be ignored.
|
||||
if v.Prerelease() != "" && !includePre {
|
||||
return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v)
|
||||
}
|
||||
|
||||
@ -391,11 +404,10 @@ func constraintGreaterThan(v *Version, c *constraint) (bool, error) {
|
||||
return false, fmt.Errorf("%s is less than or equal to %s", v, c.orig)
|
||||
}
|
||||
|
||||
func constraintLessThan(v *Version, c *constraint) (bool, error) {
|
||||
// If there is a pre-release on the version but the constraint isn't looking
|
||||
// for them assume that pre-releases are not compatible. See issue 21 for
|
||||
// more details.
|
||||
if v.Prerelease() != "" && c.con.Prerelease() == "" {
|
||||
func constraintLessThan(v *Version, c *constraint, includePre bool) (bool, error) {
|
||||
// The existence of prereleases is checked at the group level and passed in.
|
||||
// Exit early if the version has a prerelease but those are to be ignored.
|
||||
if v.Prerelease() != "" && !includePre {
|
||||
return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v)
|
||||
}
|
||||
|
||||
@ -406,12 +418,11 @@ func constraintLessThan(v *Version, c *constraint) (bool, error) {
|
||||
return false, fmt.Errorf("%s is greater than or equal to %s", v, c.orig)
|
||||
}
|
||||
|
||||
func constraintGreaterThanEqual(v *Version, c *constraint) (bool, error) {
|
||||
func constraintGreaterThanEqual(v *Version, c *constraint, includePre bool) (bool, error) {
|
||||
|
||||
// If there is a pre-release on the version but the constraint isn't looking
|
||||
// for them assume that pre-releases are not compatible. See issue 21 for
|
||||
// more details.
|
||||
if v.Prerelease() != "" && c.con.Prerelease() == "" {
|
||||
// The existence of prereleases is checked at the group level and passed in.
|
||||
// Exit early if the version has a prerelease but those are to be ignored.
|
||||
if v.Prerelease() != "" && !includePre {
|
||||
return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v)
|
||||
}
|
||||
|
||||
@ -422,11 +433,10 @@ func constraintGreaterThanEqual(v *Version, c *constraint) (bool, error) {
|
||||
return false, fmt.Errorf("%s is less than %s", v, c.orig)
|
||||
}
|
||||
|
||||
func constraintLessThanEqual(v *Version, c *constraint) (bool, error) {
|
||||
// If there is a pre-release on the version but the constraint isn't looking
|
||||
// for them assume that pre-releases are not compatible. See issue 21 for
|
||||
// more details.
|
||||
if v.Prerelease() != "" && c.con.Prerelease() == "" {
|
||||
func constraintLessThanEqual(v *Version, c *constraint, includePre bool) (bool, error) {
|
||||
// The existence of prereleases is checked at the group level and passed in.
|
||||
// Exit early if the version has a prerelease but those are to be ignored.
|
||||
if v.Prerelease() != "" && !includePre {
|
||||
return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v)
|
||||
}
|
||||
|
||||
@ -455,11 +465,10 @@ func constraintLessThanEqual(v *Version, c *constraint) (bool, error) {
|
||||
// ~1.2, ~1.2.x, ~>1.2, ~>1.2.x --> >=1.2.0, <1.3.0
|
||||
// ~1.2.3, ~>1.2.3 --> >=1.2.3, <1.3.0
|
||||
// ~1.2.0, ~>1.2.0 --> >=1.2.0, <1.3.0
|
||||
func constraintTilde(v *Version, c *constraint) (bool, error) {
|
||||
// If there is a pre-release on the version but the constraint isn't looking
|
||||
// for them assume that pre-releases are not compatible. See issue 21 for
|
||||
// more details.
|
||||
if v.Prerelease() != "" && c.con.Prerelease() == "" {
|
||||
func constraintTilde(v *Version, c *constraint, includePre bool) (bool, error) {
|
||||
// The existence of prereleases is checked at the group level and passed in.
|
||||
// Exit early if the version has a prerelease but those are to be ignored.
|
||||
if v.Prerelease() != "" && !includePre {
|
||||
return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v)
|
||||
}
|
||||
|
||||
@ -487,16 +496,15 @@ func constraintTilde(v *Version, c *constraint) (bool, error) {
|
||||
|
||||
// When there is a .x (dirty) status it automatically opts in to ~. Otherwise
|
||||
// it's a straight =
|
||||
func constraintTildeOrEqual(v *Version, c *constraint) (bool, error) {
|
||||
// If there is a pre-release on the version but the constraint isn't looking
|
||||
// for them assume that pre-releases are not compatible. See issue 21 for
|
||||
// more details.
|
||||
if v.Prerelease() != "" && c.con.Prerelease() == "" {
|
||||
func constraintTildeOrEqual(v *Version, c *constraint, includePre bool) (bool, error) {
|
||||
// The existence of prereleases is checked at the group level and passed in.
|
||||
// Exit early if the version has a prerelease but those are to be ignored.
|
||||
if v.Prerelease() != "" && !includePre {
|
||||
return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v)
|
||||
}
|
||||
|
||||
if c.dirty {
|
||||
return constraintTilde(v, c)
|
||||
return constraintTilde(v, c, includePre)
|
||||
}
|
||||
|
||||
eq := v.Equal(c.con)
|
||||
@ -516,11 +524,10 @@ func constraintTildeOrEqual(v *Version, c *constraint) (bool, error) {
|
||||
// ^0.0.3 --> >=0.0.3 <0.0.4
|
||||
// ^0.0 --> >=0.0.0 <0.1.0
|
||||
// ^0 --> >=0.0.0 <1.0.0
|
||||
func constraintCaret(v *Version, c *constraint) (bool, error) {
|
||||
// If there is a pre-release on the version but the constraint isn't looking
|
||||
// for them assume that pre-releases are not compatible. See issue 21 for
|
||||
// more details.
|
||||
if v.Prerelease() != "" && c.con.Prerelease() == "" {
|
||||
func constraintCaret(v *Version, c *constraint, includePre bool) (bool, error) {
|
||||
// The existence of prereleases is checked at the group level and passed in.
|
||||
// Exit early if the version has a prerelease but those are to be ignored.
|
||||
if v.Prerelease() != "" && !includePre {
|
||||
return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v)
|
||||
}
|
||||
|
||||
|
163
vendor/github.com/Masterminds/semver/v3/version.go
generated
vendored
163
vendor/github.com/Masterminds/semver/v3/version.go
generated
vendored
@ -14,28 +14,40 @@ import (
|
||||
// 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 looseVersionRegex *regexp.Regexp
|
||||
|
||||
// CoerceNewVersion sets if leading 0's are allowd in the version part. Leading 0's are
|
||||
// not allowed in a valid semantic version. When set to true, NewVersion will coerce
|
||||
// leading 0's into a valid version.
|
||||
var CoerceNewVersion = true
|
||||
|
||||
// DetailedNewVersionErrors specifies if detailed errors are returned from the NewVersion
|
||||
// function. This is used when CoerceNewVersion is set to false. If set to false
|
||||
// ErrInvalidSemVer is returned for an invalid version. This does not apply to
|
||||
// StrictNewVersion. Setting this function to false returns errors more quickly.
|
||||
var DetailedNewVersionErrors = true
|
||||
|
||||
var (
|
||||
// ErrInvalidSemVer is returned a version is found to be invalid when
|
||||
// being parsed.
|
||||
ErrInvalidSemVer = errors.New("Invalid Semantic Version")
|
||||
ErrInvalidSemVer = errors.New("invalid semantic version")
|
||||
|
||||
// ErrEmptyString is returned when an empty string is passed in for parsing.
|
||||
ErrEmptyString = errors.New("Version string empty")
|
||||
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")
|
||||
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")
|
||||
ErrSegmentStartsZero = errors.New("version segment starts with 0")
|
||||
|
||||
// ErrInvalidMetadata is returned when the metadata is an invalid format
|
||||
ErrInvalidMetadata = errors.New("Invalid Metadata string")
|
||||
ErrInvalidMetadata = errors.New("invalid metadata string")
|
||||
|
||||
// ErrInvalidPrerelease is returned when the pre-release is an invalid format
|
||||
ErrInvalidPrerelease = errors.New("Invalid Prerelease string")
|
||||
ErrInvalidPrerelease = errors.New("invalid prerelease string")
|
||||
)
|
||||
|
||||
// semVerRegex is the regular expression used to parse a semantic version.
|
||||
@ -45,6 +57,12 @@ const semVerRegex string = `v?(0|[1-9]\d*)(?:\.(0|[1-9]\d*))?(?:\.(0|[1-9]\d*))?
|
||||
`(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?` +
|
||||
`(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?`
|
||||
|
||||
// looseSemVerRegex is a regular expression that lets invalid semver expressions through
|
||||
// with enough detail that certain errors can be checked for.
|
||||
const looseSemVerRegex 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
|
||||
@ -55,6 +73,7 @@ type Version struct {
|
||||
|
||||
func init() {
|
||||
versionRegex = regexp.MustCompile("^" + semVerRegex + "$")
|
||||
looseVersionRegex = regexp.MustCompile("^" + looseSemVerRegex + "$")
|
||||
}
|
||||
|
||||
const (
|
||||
@ -142,8 +161,27 @@ func StrictNewVersion(v string) (*Version, error) {
|
||||
// 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) {
|
||||
if CoerceNewVersion {
|
||||
return coerceNewVersion(v)
|
||||
}
|
||||
m := versionRegex.FindStringSubmatch(v)
|
||||
if m == nil {
|
||||
|
||||
// Disabling detailed errors is first so that it is in the fast path.
|
||||
if !DetailedNewVersionErrors {
|
||||
return nil, ErrInvalidSemVer
|
||||
}
|
||||
|
||||
// Check for specific errors with the semver string and return a more detailed
|
||||
// error.
|
||||
m = looseVersionRegex.FindStringSubmatch(v)
|
||||
if m == nil {
|
||||
return nil, ErrInvalidSemVer
|
||||
}
|
||||
err := validateVersion(m)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return nil, ErrInvalidSemVer
|
||||
}
|
||||
|
||||
@ -156,13 +194,13 @@ func NewVersion(v string) (*Version, error) {
|
||||
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)
|
||||
return nil, fmt.Errorf("error parsing version segment: %w", err)
|
||||
}
|
||||
|
||||
if m[2] != "" {
|
||||
sv.minor, err = strconv.ParseUint(m[2], 10, 64)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Error parsing version segment: %s", err)
|
||||
return nil, fmt.Errorf("error parsing version segment: %w", err)
|
||||
}
|
||||
} else {
|
||||
sv.minor = 0
|
||||
@ -171,7 +209,61 @@ func NewVersion(v string) (*Version, error) {
|
||||
if m[3] != "" {
|
||||
sv.patch, err = strconv.ParseUint(m[3], 10, 64)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Error parsing version segment: %s", err)
|
||||
return nil, fmt.Errorf("error parsing version segment: %w", 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
|
||||
}
|
||||
|
||||
func coerceNewVersion(v string) (*Version, error) {
|
||||
m := looseVersionRegex.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: %w", 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: %w", 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: %w", err)
|
||||
}
|
||||
} else {
|
||||
sv.patch = 0
|
||||
@ -615,7 +707,7 @@ func validatePrerelease(p string) error {
|
||||
eparts := strings.Split(p, ".")
|
||||
for _, p := range eparts {
|
||||
if p == "" {
|
||||
return ErrInvalidMetadata
|
||||
return ErrInvalidPrerelease
|
||||
} else if containsOnly(p, num) {
|
||||
if len(p) > 1 && p[0] == '0' {
|
||||
return ErrSegmentStartsZero
|
||||
@ -643,3 +735,54 @@ func validateMetadata(m string) error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// validateVersion checks for common validation issues but may not catch all errors
|
||||
func validateVersion(m []string) error {
|
||||
var err error
|
||||
var v string
|
||||
if m[1] != "" {
|
||||
if len(m[1]) > 1 && m[1][0] == '0' {
|
||||
return ErrSegmentStartsZero
|
||||
}
|
||||
_, err = strconv.ParseUint(m[1], 10, 64)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error parsing version segment: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
if m[2] != "" {
|
||||
v = strings.TrimPrefix(m[2], ".")
|
||||
if len(v) > 1 && v[0] == '0' {
|
||||
return ErrSegmentStartsZero
|
||||
}
|
||||
_, err = strconv.ParseUint(v, 10, 64)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error parsing version segment: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
if m[3] != "" {
|
||||
v = strings.TrimPrefix(m[3], ".")
|
||||
if len(v) > 1 && v[0] == '0' {
|
||||
return ErrSegmentStartsZero
|
||||
}
|
||||
_, err = strconv.ParseUint(v, 10, 64)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error parsing version segment: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
if m[5] != "" {
|
||||
if err = validatePrerelease(m[5]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if m[8] != "" {
|
||||
if err = validateMetadata(m[8]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
2
vendor/modules.txt
vendored
2
vendor/modules.txt
vendored
@ -5,7 +5,7 @@ dario.cat/mergo
|
||||
## explicit; go 1.18
|
||||
github.com/BurntSushi/toml
|
||||
github.com/BurntSushi/toml/internal
|
||||
# github.com/Masterminds/semver/v3 v3.3.1
|
||||
# github.com/Masterminds/semver/v3 v3.4.0
|
||||
## explicit; go 1.21
|
||||
github.com/Masterminds/semver/v3
|
||||
# github.com/Microsoft/go-winio v0.6.2
|
||||
|
Loading…
Reference in New Issue
Block a user