Skip to content

Commit

Permalink
DNM: Use funtional tags for options
Browse files Browse the repository at this point in the history
This defines a parser for tags which takes a single Go-style identifier
argument (but leaves room for better parsing).

DO NOT MERGE: Since this changes gengo, it would need to be vendored.
  • Loading branch information
thockin committed Dec 18, 2024
1 parent 31b3778 commit 0fecd2d
Show file tree
Hide file tree
Showing 4 changed files with 456 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,13 @@ var localSchemeBuilder = testscheme.New()
type T1 struct {
TypeMeta int

// +k8s:ifOptionEnabled=FeatureX=+k8s:validateFalse="field T1.S1"
// +k8s:ifOptionEnabled(FeatureX)=+k8s:validateFalse="field T1.S1"
S1 string `json:"s1"`

// +k8s:ifOptionDisabled=FeatureX=+k8s:validateFalse="field T1.S2"
// +k8s:ifOptionDisabled(FeatureX)=+k8s:validateFalse="field T1.S2"
S2 string `json:"s2"`

// +k8s:ifOptionEnabled=FeatureX=+k8s:validateFalse="field T1.S3.FeatureX"
// +k8s:ifOptionDisabled=FeatureY=+k8s:validateFalse="field T1.S3.FeatureY"
// +k8s:ifOptionEnabled(FeatureX)=+k8s:validateFalse="field T1.S3.FeatureX"
// +k8s:ifOptionDisabled(FeatureY)=+k8s:validateFalse="field T1.S3.FeatureY"
S3 string `json:"s3"`
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ package validators

import (
"fmt"
"strings"

"k8s.io/gengo/v2"
"k8s.io/gengo/v2/types"
Expand All @@ -42,14 +41,20 @@ const (
)

func (o optionDeclarativeValidator) ExtractValidations(t *types.Type, comments []string) (Validations, error) {
enabledTagValues, hasEnabledTags := gengo.ExtractCommentTags("+", comments)[ifOptionEnabledTag]
disabledTagValues, hasDisabledTags := gengo.ExtractCommentTags("+", comments)[ifOptionDisabledTag]
tags, err := gengo.ExtractFunctionalCommentTags("+", []string{ifOptionEnabledTag, ifOptionDisabledTag}, comments)
if err != nil {
return Validations{}, err
}

enabledTags, hasEnabledTags := tags[ifOptionEnabledTag]
disabledTags, hasDisabledTags := tags[ifOptionDisabledTag]
if !hasEnabledTags && !hasDisabledTags {
return Validations{}, nil
}

var functions []FunctionGen
var variables []VariableGen
for _, v := range enabledTagValues {
for _, v := range enabledTags {
optionName, validations, err := o.parseIfOptionsTag(t, v)
if err != nil {
return Validations{}, err
Expand All @@ -59,7 +64,7 @@ func (o optionDeclarativeValidator) ExtractValidations(t *types.Type, comments [
}
variables = append(variables, validations.Variables...)
}
for _, v := range disabledTagValues {
for _, v := range disabledTags {
optionName, validations, err := o.parseIfOptionsTag(t, v)
if err != nil {
return Validations{}, err
Expand All @@ -75,18 +80,15 @@ func (o optionDeclarativeValidator) ExtractValidations(t *types.Type, comments [
}, nil
}

func (o optionDeclarativeValidator) parseIfOptionsTag(t *types.Type, tagValue string) (string, Validations, error) {
parts := strings.SplitN(tagValue, "=", 2)
if len(parts) != 2 {
return "", Validations{}, fmt.Errorf("invalid value %q for option %q", tagValue, parts[0])
func (o optionDeclarativeValidator) parseIfOptionsTag(t *types.Type, tag gengo.Tag) (string, Validations, error) {
if len(tag.Args) != 1 {
return "", Validations{}, fmt.Errorf("tag %q requires 1 argument", tag.Name)
}
optionName := parts[0]
embeddedValidation := parts[1]
validations, err := o.cfg.EmbedValidator.ExtractValidations(t, []string{embeddedValidation})
validations, err := o.cfg.EmbedValidator.ExtractValidations(t, []string{tag.Value})
if err != nil {
return "", Validations{}, err
}
return optionName, validations, nil
return tag.Args[0], validations, nil
}

func (optionDeclarativeValidator) Docs() []TagDoc {
Expand Down
198 changes: 198 additions & 0 deletions vendor/k8s.io/gengo/v2/comments.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 0fecd2d

Please sign in to comment.