mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-09-14 13:45:06 +00:00
Add tolerant parse option to semver
This commit is contained in:
@@ -42,6 +42,16 @@ import (
|
|||||||
// semver('Three') // error
|
// semver('Three') // error
|
||||||
// semver('Mi') // error
|
// semver('Mi') // error
|
||||||
//
|
//
|
||||||
|
// semver(<string>, <bool>) <Semver>
|
||||||
|
//
|
||||||
|
// Examples:
|
||||||
|
//
|
||||||
|
// semver('1.0.0') // returns a Semver
|
||||||
|
// semver('0.1.0-alpha.1') // returns a Semver
|
||||||
|
// semver('200K') // error
|
||||||
|
// semver('Three') // error
|
||||||
|
// semver('Mi') // error
|
||||||
|
//
|
||||||
// isSemver
|
// isSemver
|
||||||
//
|
//
|
||||||
// Returns true if a string is a valid Semver. isSemver returns true if and
|
// Returns true if a string is a valid Semver. isSemver returns true if and
|
||||||
@@ -84,13 +94,27 @@ import (
|
|||||||
// semver("1.2.3").compareTo(semver("2.0.0")) // returns -1
|
// semver("1.2.3").compareTo(semver("2.0.0")) // returns -1
|
||||||
// semver("1.2.3").compareTo(semver("0.1.2")) // returns 1
|
// semver("1.2.3").compareTo(semver("0.1.2")) // returns 1
|
||||||
|
|
||||||
func SemverLib() cel.EnvOption {
|
func SemverLib(options ...SemverOption) cel.EnvOption {
|
||||||
|
semverLib := &semverLibType{}
|
||||||
|
for _, o := range options {
|
||||||
|
semverLib = o(semverLib)
|
||||||
|
}
|
||||||
return cel.Lib(semverLib)
|
return cel.Lib(semverLib)
|
||||||
}
|
}
|
||||||
|
|
||||||
var semverLib = &semverLibType{}
|
type semverLibType struct {
|
||||||
|
version uint32
|
||||||
|
}
|
||||||
|
|
||||||
type semverLibType struct{}
|
// StringsOption is a functional interface for configuring the strings library.
|
||||||
|
type SemverOption func(*semverLibType) *semverLibType
|
||||||
|
|
||||||
|
func SemverVersion(version uint32) SemverOption {
|
||||||
|
return func(lib *semverLibType) *semverLibType {
|
||||||
|
lib.version = version
|
||||||
|
return lib
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (*semverLibType) LibraryName() string {
|
func (*semverLibType) LibraryName() string {
|
||||||
return "kubernetes.Semver"
|
return "kubernetes.Semver"
|
||||||
@@ -100,8 +124,8 @@ func (*semverLibType) Types() []*cel.Type {
|
|||||||
return []*cel.Type{apiservercel.SemverType}
|
return []*cel.Type{apiservercel.SemverType}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*semverLibType) declarations() map[string][]cel.FunctionOpt {
|
func (lib *semverLibType) declarations() map[string][]cel.FunctionOpt {
|
||||||
return map[string][]cel.FunctionOpt{
|
fnOpts := map[string][]cel.FunctionOpt{
|
||||||
"semver": {
|
"semver": {
|
||||||
cel.Overload("string_to_semver", []*cel.Type{cel.StringType}, apiservercel.SemverType, cel.UnaryBinding((stringToSemver))),
|
cel.Overload("string_to_semver", []*cel.Type{cel.StringType}, apiservercel.SemverType, cel.UnaryBinding((stringToSemver))),
|
||||||
},
|
},
|
||||||
@@ -127,6 +151,11 @@ func (*semverLibType) declarations() map[string][]cel.FunctionOpt {
|
|||||||
cel.MemberOverload("semver_patch", []*cel.Type{apiservercel.SemverType}, cel.IntType, cel.UnaryBinding(semverPatch)),
|
cel.MemberOverload("semver_patch", []*cel.Type{apiservercel.SemverType}, cel.IntType, cel.UnaryBinding(semverPatch)),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
if lib.version >= 1 {
|
||||||
|
fnOpts["semver"] = append(fnOpts["semver"], cel.Overload("string_bool_to_semver", []*cel.Type{cel.StringType, cel.BoolType}, apiservercel.SemverType, cel.BinaryBinding((stringToSemverTolerant))))
|
||||||
|
fnOpts["isSemver"] = append(fnOpts["isSemver"], cel.Overload("is_semver_string_bool", []*cel.Type{cel.StringType, cel.BoolType}, cel.BoolType, cel.BinaryBinding(isSemverTolerant)))
|
||||||
|
}
|
||||||
|
return fnOpts
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *semverLibType) CompileOptions() []cel.EnvOption {
|
func (s *semverLibType) CompileOptions() []cel.EnvOption {
|
||||||
@@ -144,16 +173,29 @@ func (*semverLibType) ProgramOptions() []cel.ProgramOption {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func isSemver(arg ref.Val) ref.Val {
|
func isSemver(arg ref.Val) ref.Val {
|
||||||
|
return isSemverTolerant(arg, types.Bool(false))
|
||||||
|
}
|
||||||
|
func isSemverTolerant(arg ref.Val, tolerantArg ref.Val) ref.Val {
|
||||||
str, ok := arg.Value().(string)
|
str, ok := arg.Value().(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return types.MaybeNoSuchOverloadErr(arg)
|
return types.MaybeNoSuchOverloadErr(arg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tolerant, ok := tolerantArg.Value().(bool)
|
||||||
|
if !ok {
|
||||||
|
return types.MaybeNoSuchOverloadErr(arg)
|
||||||
|
}
|
||||||
|
|
||||||
// Using semver/v4 here is okay because this function isn't
|
// Using semver/v4 here is okay because this function isn't
|
||||||
// used to validate the Kubernetes API. In the CEL base library
|
// used to validate the Kubernetes API. In the CEL base library
|
||||||
// we would have to use the regular expression from
|
// we would have to use the regular expression from
|
||||||
// pkg/apis/resource/structured/namedresources/validation/validation.go.
|
// pkg/apis/resource/structured/namedresources/validation/validation.go.
|
||||||
_, err := semver.Parse(str)
|
var err error
|
||||||
|
if tolerant {
|
||||||
|
_, err = semver.ParseTolerant(str)
|
||||||
|
} else {
|
||||||
|
_, err = semver.Parse(str)
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return types.Bool(false)
|
return types.Bool(false)
|
||||||
}
|
}
|
||||||
@@ -162,17 +204,31 @@ func isSemver(arg ref.Val) ref.Val {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func stringToSemver(arg ref.Val) ref.Val {
|
func stringToSemver(arg ref.Val) ref.Val {
|
||||||
|
return stringToSemverTolerant(arg, types.Bool(false))
|
||||||
|
}
|
||||||
|
func stringToSemverTolerant(arg ref.Val, tolerantArg ref.Val) ref.Val {
|
||||||
str, ok := arg.Value().(string)
|
str, ok := arg.Value().(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return types.MaybeNoSuchOverloadErr(arg)
|
return types.MaybeNoSuchOverloadErr(arg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tolerant, ok := tolerantArg.Value().(bool)
|
||||||
|
if !ok {
|
||||||
|
return types.MaybeNoSuchOverloadErr(arg)
|
||||||
|
}
|
||||||
|
|
||||||
// Using semver/v4 here is okay because this function isn't
|
// Using semver/v4 here is okay because this function isn't
|
||||||
// used to validate the Kubernetes API. In the CEL base library
|
// used to validate the Kubernetes API. In the CEL base library
|
||||||
// we would have to use the regular expression from
|
// we would have to use the regular expression from
|
||||||
// pkg/apis/resource/structured/namedresources/validation/validation.go
|
// pkg/apis/resource/structured/namedresources/validation/validation.go
|
||||||
// first before parsing.
|
// first before parsing.
|
||||||
v, err := semver.Parse(str)
|
var err error
|
||||||
|
var v semver.Version
|
||||||
|
if tolerant {
|
||||||
|
v, err = semver.ParseTolerant(str)
|
||||||
|
} else {
|
||||||
|
v, err = semver.Parse(str)
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return types.WrapErr(err)
|
return types.WrapErr(err)
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user