diff --git a/staging/src/k8s.io/code-generator/cmd/client-gen/generators/client_generator.go b/staging/src/k8s.io/code-generator/cmd/client-gen/generators/client_generator.go index c8fa01a8ecd..c81e358db95 100644 --- a/staging/src/k8s.io/code-generator/cmd/client-gen/generators/client_generator.go +++ b/staging/src/k8s.io/code-generator/cmd/client-gen/generators/client_generator.go @@ -29,6 +29,7 @@ import ( "k8s.io/code-generator/cmd/client-gen/generators/util" clientgentypes "k8s.io/code-generator/cmd/client-gen/types" codegennamer "k8s.io/code-generator/pkg/namer" + genutil "k8s.io/code-generator/pkg/util" "k8s.io/gengo/v2" "k8s.io/gengo/v2/generator" "k8s.io/gengo/v2/namer" @@ -275,14 +276,18 @@ NextGroup: // first field (somegroup) as the name of the group in Go code, e.g. as the func name in a clientset. // // If the first field of the groupName is not unique within the clientset, use "// +groupName=unique -func applyGroupOverrides(universe types.Universe, args *args.Args) { +func applyGroupOverrides(universe types.Universe, args *args.Args) error { // Create a map from "old GV" to "new GV" so we know what changes we need to make. changes := make(map[clientgentypes.GroupVersion]clientgentypes.GroupVersion) for gv, inputDir := range args.GroupVersionPackages() { p := universe.Package(inputDir) - if override := gengo.ExtractCommentTags("+", p.Comments)["groupName"]; override != nil { + override, err := genutil.ExtractCommentTagsWithoutArguments("+", []string{"groupName"}, p.Comments) + if err != nil { + return fmt.Errorf("cannot extract groupName tags: %w", err) + } + if override["groupName"] != nil { newGV := clientgentypes.GroupVersion{ - Group: clientgentypes.Group(override[0]), + Group: clientgentypes.Group(override["groupName"][0]), Version: gv.Version, } changes[gv] = newGV @@ -310,6 +315,7 @@ func applyGroupOverrides(universe types.Universe, args *args.Args) { } } args.Groups = newGroups + return nil } // Because we try to assemble inputs from an input-base and a set of @@ -353,7 +359,9 @@ func GetTargets(context *generator.Context, args *args.Args) []generator.Target if err := sanitizePackagePaths(context, args); err != nil { klog.Fatalf("cannot sanitize inputs: %v", err) } - applyGroupOverrides(context.Universe, args) + if err := applyGroupOverrides(context.Universe, args); err != nil { + klog.Fatalf("cannot apply group overrides: %v", err) + } gvToTypes := map[clientgentypes.GroupVersion][]*types.Type{} groupGoNames := make(map[clientgentypes.GroupVersion]string) @@ -363,8 +371,12 @@ func GetTargets(context *generator.Context, args *args.Args) []generator.Target // If there's a comment of the form "// +groupGoName=SomeUniqueShortName", use that as // the Go group identifier in CamelCase. It defaults groupGoNames[gv] = namer.IC(strings.Split(gv.Group.NonEmpty(), ".")[0]) - if override := gengo.ExtractCommentTags("+", p.Comments)["groupGoName"]; override != nil { - groupGoNames[gv] = namer.IC(override[0]) + override, err := genutil.ExtractCommentTagsWithoutArguments("+", []string{"groupGoName"}, p.Comments) + if err != nil { + klog.Fatalf("cannot extract groupGoName tags: %v", err) + } + if override["groupGoName"] != nil { + groupGoNames[gv] = namer.IC(override["groupGoName"][0]) } for n, t := range p.Types { diff --git a/staging/src/k8s.io/code-generator/cmd/deepcopy-gen/generators/deepcopy.go b/staging/src/k8s.io/code-generator/cmd/deepcopy-gen/generators/deepcopy.go index 259f1731525..0d86cd39cbb 100644 --- a/staging/src/k8s.io/code-generator/cmd/deepcopy-gen/generators/deepcopy.go +++ b/staging/src/k8s.io/code-generator/cmd/deepcopy-gen/generators/deepcopy.go @@ -54,21 +54,24 @@ func extractEnabledTypeTag(t *types.Type) *enabledTagValue { } func extractEnabledTag(comments []string) *enabledTagValue { - tagVals := gengo.ExtractCommentTags("+", comments)[tagEnabledName] - if tagVals == nil { + tags, err := genutil.ExtractCommentTagsWithoutArguments("+", []string{tagEnabledName}, comments) + if err != nil { + klog.Fatalf("Error extracting %s tags: %v", tagEnabledName, err) + } + if tags[tagEnabledName] == nil { // No match for the tag. return nil } // If there are multiple values, abort. - if len(tagVals) > 1 { - klog.Fatalf("Found %d %s tags: %q", len(tagVals), tagEnabledName, tagVals) + if len(tags[tagEnabledName]) > 1 { + klog.Fatalf("Found %d %s tags: %q", len(tags[tagEnabledName]), tagEnabledName, tags[tagEnabledName]) } // If we got here we are returning something. tag := &enabledTagValue{} // Get the primary value. - parts := strings.Split(tagVals[0], ",") + parts := strings.Split(tags[tagEnabledName][0], ",") if len(parts) >= 1 { tag.value = parts[0] } @@ -452,8 +455,11 @@ func (g *genDeepCopy) needsGeneration(t *types.Type) bool { func extractInterfacesTag(t *types.Type) []string { var result []string comments := append(append([]string{}, t.SecondClosestCommentLines...), t.CommentLines...) - values := gengo.ExtractCommentTags("+", comments)[interfacesTagName] - for _, v := range values { + tags, err := genutil.ExtractCommentTagsWithoutArguments("+", []string{interfacesTagName}, comments) + if err != nil { + klog.Fatalf("Error extracting %s tags: %v", interfacesTagName, err) + } + for _, v := range tags[interfacesTagName] { if len(v) == 0 { continue } diff --git a/staging/src/k8s.io/code-generator/cmd/defaulter-gen/generators/defaulter.go b/staging/src/k8s.io/code-generator/cmd/defaulter-gen/generators/defaulter.go index 82e1cdd2070..2379117c584 100644 --- a/staging/src/k8s.io/code-generator/cmd/defaulter-gen/generators/defaulter.go +++ b/staging/src/k8s.io/code-generator/cmd/defaulter-gen/generators/defaulter.go @@ -28,6 +28,7 @@ import ( "strings" "k8s.io/code-generator/cmd/defaulter-gen/args" + genutil "k8s.io/code-generator/pkg/util" "k8s.io/gengo/v2" "k8s.io/gengo/v2/generator" "k8s.io/gengo/v2/namer" @@ -64,24 +65,40 @@ const tagName = "k8s:defaulter-gen" const inputTagName = "k8s:defaulter-gen-input" const defaultTagName = "default" -func extractDefaultTag(comments []string) []string { - return gengo.ExtractCommentTags("+", comments)[defaultTagName] -} - -func extractTag(comments []string) []string { - return gengo.ExtractCommentTags("+", comments)[tagName] -} - -func extractInputTag(comments []string) []string { - return gengo.ExtractCommentTags("+", comments)[inputTagName] -} - -func checkTag(comments []string, require ...string) bool { - values := gengo.ExtractCommentTags("+", comments)[tagName] - if len(require) == 0 { - return len(values) == 1 && values[0] == "" +func extractDefaultTag(comments []string) ([]string, error) { + tags, err := genutil.ExtractCommentTagsWithoutArguments("+", []string{defaultTagName}, comments) + if err != nil { + return nil, err } - return reflect.DeepEqual(values, require) + return tags[defaultTagName], nil +} + +func extractTag(comments []string) ([]string, error) { + tags, err := genutil.ExtractCommentTagsWithoutArguments("+", []string{tagName}, comments) + if err != nil { + return nil, err + } + return tags[tagName], nil +} + +func extractInputTag(comments []string) ([]string, error) { + tags, err := genutil.ExtractCommentTagsWithoutArguments("+", []string{inputTagName}, comments) + if err != nil { + return nil, err + } + return tags[inputTagName], nil +} + +func checkTag(comments []string, require ...string) (bool, error) { + tags, err := genutil.ExtractCommentTagsWithoutArguments("+", []string{tagName}, comments) + if err != nil { + return false, err + } + + if len(require) == 0 { + return len(tags[tagName]) == 1 && tags[tagName][0] == "", nil + } + return reflect.DeepEqual(tags[tagName], require), nil } func defaultFnNamer() *namer.NameStrategy { @@ -246,7 +263,10 @@ func GetTargets(context *generator.Context, args *args.Args) []generator.Target pkg := context.Universe[i] // if the types are not in the same package where the defaulter functions to be generated - inputTags := extractInputTag(pkg.Comments) + inputTags, err := extractInputTag(pkg.Comments) + if err != nil { + panic(fmt.Sprintf("error extracting input tag: %v", err)) + } if len(inputTags) > 1 { panic(fmt.Sprintf("there may only be one input tag, got %#v", inputTags)) } @@ -310,7 +330,10 @@ func GetTargets(context *generator.Context, args *args.Args) []generator.Target getManualDefaultingFunctions(context, context.Universe[pp], existingDefaulters) } - typesWith := extractTag(pkg.Comments) + typesWith, err := extractTag(pkg.Comments) + if err != nil { + klog.Fatalf("Error extracting %s tag: %v", tagName, err) + } shouldCreateObjectDefaulterFn := func(t *types.Type) bool { if defaults, ok := existingDefaulters[t]; ok && defaults.object != nil { // A default generator is defined @@ -322,11 +345,19 @@ func GetTargets(context *generator.Context, args *args.Args) []generator.Target return false } // opt-out - if checkTag(t.SecondClosestCommentLines, "false") { + optOut, err := checkTag(t.SecondClosestCommentLines, "false") + if err != nil { + klog.Fatalf("Error extracting %s tags: %v", tagName, err) + } + if optOut { return false } // opt-in - if checkTag(t.SecondClosestCommentLines, "true") { + optIn, err := checkTag(t.SecondClosestCommentLines, "true") + if err != nil { + klog.Fatalf("Error extracting %s tags: %v", tagName, err) + } + if optIn { return true } // For every k8s:defaulter-gen tag at the package level, interpret the value as a @@ -497,13 +528,16 @@ func getPointerElementPath(t *types.Type) []*types.Type { } // getNestedDefault returns the first default value when resolving alias types -func getNestedDefault(t *types.Type) string { +func getNestedDefault(t *types.Type) (string, error) { var prev *types.Type for prev != t { prev = t - defaultMap := extractDefaultTag(t.CommentLines) + defaultMap, err := extractDefaultTag(t.CommentLines) + if err != nil { + return "", err + } if len(defaultMap) == 1 && defaultMap[0] != "" { - return defaultMap[0] + return defaultMap[0], nil } if t.Kind == types.Alias { t = t.Underlying @@ -511,7 +545,7 @@ func getNestedDefault(t *types.Type) string { t = t.Elem } } - return "" + return "", nil } var refRE = regexp.MustCompile(`^ref\((?P[^"]+)\)$`) @@ -538,7 +572,11 @@ func parseSymbolReference(s, sourcePackage string) (types.Name, bool) { } func populateDefaultValue(node *callNode, t *types.Type, tags string, commentLines []string, commentPackage string) *callNode { - defaultMap := extractDefaultTag(commentLines) + defaultMap, err := extractDefaultTag(commentLines) + if err != nil { + klog.Fatalf("Error extracting default tag: %v", err) + } + var defaultString string if len(defaultMap) == 1 { defaultString = defaultMap[0] @@ -548,7 +586,10 @@ func populateDefaultValue(node *callNode, t *types.Type, tags string, commentLin baseT, depth := resolveTypeAndDepth(t) if depth > 0 && defaultString == "" { - defaultString = getNestedDefault(t) + defaultString, err = getNestedDefault(t) + if err != nil { + klog.Fatalf("Error extracting nested default tag: %v", err) + } } if len(defaultString) == 0 { @@ -622,7 +663,11 @@ func (c *callTreeForType) build(t *types.Type, root bool) *callNode { parent.call = append(parent.call, defaults.base) // if the base function indicates it "covers" (it already includes defaulters) // we can halt recursion - if checkTag(defaults.base.CommentLines, "covers") { + isCovers, err := checkTag(defaults.base.CommentLines, "covers") + if err != nil { + klog.Fatalf("error extracting %s tag: %v", tagName, err) + } + if isCovers { klog.V(6).Infof("the defaulter %s indicates it covers all sub generators", t.Name) return parent } diff --git a/staging/src/k8s.io/code-generator/cmd/go-to-protobuf/protobuf/generator.go b/staging/src/k8s.io/code-generator/cmd/go-to-protobuf/protobuf/generator.go index c9eadd812f8..c92c7cec028 100644 --- a/staging/src/k8s.io/code-generator/cmd/go-to-protobuf/protobuf/generator.go +++ b/staging/src/k8s.io/code-generator/cmd/go-to-protobuf/protobuf/generator.go @@ -25,6 +25,7 @@ import ( "strconv" "strings" + genutil "k8s.io/code-generator/pkg/util" "k8s.io/gengo/v2" "k8s.io/gengo/v2/generator" "k8s.io/gengo/v2/namer" @@ -80,17 +81,20 @@ func (g *genProtoIDL) Namers(c *generator.Context) namer.NameSystems { // Filter ignores types that are identified as not exportable. func (g *genProtoIDL) Filter(c *generator.Context, t *types.Type) bool { - tagVals := gengo.ExtractCommentTags("+", t.CommentLines)["protobuf"] - if tagVals != nil { - if tagVals[0] == "false" { + tags, err := genutil.ExtractCommentTagsWithoutArguments("+", []string{"protobuf"}, t.CommentLines) + if err != nil { + klog.Fatalf(`Error extracting tag "protobuf": %v`, err) + } + if tags["protobuf"] != nil { + if tags["protobuf"][0] == "false" { // Type specified "false". return false } - if tagVals[0] == "true" { + if tags["protobuf"][0] == "true" { // Type specified "true". return true } - klog.Fatalf(`Comment tag "protobuf" must be true or false, found: %q`, tagVals[0]) + klog.Fatalf(`Comment tag "protobuf" must be true or false, found: %q`, tags["protobuf"][0]) } if !g.generateAll { // We're not generating everything. diff --git a/staging/src/k8s.io/code-generator/cmd/informer-gen/generators/targets.go b/staging/src/k8s.io/code-generator/cmd/informer-gen/generators/targets.go index 2e886d4e00c..cdba8e83563 100644 --- a/staging/src/k8s.io/code-generator/cmd/informer-gen/generators/targets.go +++ b/staging/src/k8s.io/code-generator/cmd/informer-gen/generators/targets.go @@ -144,15 +144,23 @@ func GetTargets(context *generator.Context, args *args.Args) []generator.Target // If there's a comment of the form "// +groupName=somegroup" or // "// +groupName=somegroup.foo.bar.io", use the first field (somegroup) as the name of the // group when generating. - if override := gengo.ExtractCommentTags("+", p.Comments)["groupName"]; override != nil { - gv.Group = clientgentypes.Group(override[0]) + override, err := genutil.ExtractCommentTagsWithoutArguments("+", []string{"groupName"}, p.Comments) + if err != nil { + klog.Fatalf("error extracting groupName tags: %v", err) + } + if override["groupName"] != nil { + gv.Group = clientgentypes.Group(override["groupName"][0]) } // If there's a comment of the form "// +groupGoName=SomeUniqueShortName", use that as // the Go group identifier in CamelCase. It defaults groupGoNames[groupPackageName] = namer.IC(strings.Split(gv.Group.NonEmpty(), ".")[0]) - if override := gengo.ExtractCommentTags("+", p.Comments)["groupGoName"]; override != nil { - groupGoNames[groupPackageName] = namer.IC(override[0]) + override, err = genutil.ExtractCommentTagsWithoutArguments("+", []string{"groupGoName"}, p.Comments) + if err != nil { + klog.Fatalf("error extracting groupGoName tags: %v", err) + } + if override["groupGoName"] != nil { + groupGoNames[groupPackageName] = namer.IC(override["groupGoName"][0]) } var typesToGenerate []*types.Type diff --git a/staging/src/k8s.io/code-generator/cmd/lister-gen/generators/lister.go b/staging/src/k8s.io/code-generator/cmd/lister-gen/generators/lister.go index a5beb2a7f18..3a28115fa5b 100644 --- a/staging/src/k8s.io/code-generator/cmd/lister-gen/generators/lister.go +++ b/staging/src/k8s.io/code-generator/cmd/lister-gen/generators/lister.go @@ -26,6 +26,7 @@ import ( "k8s.io/code-generator/cmd/client-gen/generators/util" clientgentypes "k8s.io/code-generator/cmd/client-gen/types" "k8s.io/code-generator/cmd/lister-gen/args" + genutil "k8s.io/code-generator/pkg/util" "k8s.io/gengo/v2" "k8s.io/gengo/v2/generator" "k8s.io/gengo/v2/namer" @@ -101,8 +102,12 @@ func GetTargets(context *generator.Context, args *args.Args) []generator.Target // If there's a comment of the form "// +groupName=somegroup" or // "// +groupName=somegroup.foo.bar.io", use the first field (somegroup) as the name of the // group when generating. - if override := gengo.ExtractCommentTags("+", p.Comments)["groupName"]; override != nil { - gv.Group = clientgentypes.Group(strings.SplitN(override[0], ".", 2)[0]) + override, err := genutil.ExtractCommentTagsWithoutArguments("+", []string{"groupName"}, p.Comments) + if err != nil { + klog.Fatalf("error extracting groupName tags: %v", err) + } + if override["groupName"] != nil { + gv.Group = clientgentypes.Group(strings.SplitN(override["groupName"][0], ".", 2)[0]) } var typesToGenerate []*types.Type diff --git a/staging/src/k8s.io/code-generator/cmd/prerelease-lifecycle-gen/prerelease-lifecycle-generators/status.go b/staging/src/k8s.io/code-generator/cmd/prerelease-lifecycle-gen/prerelease-lifecycle-generators/status.go index 086b9c75388..580bfc68c65 100644 --- a/staging/src/k8s.io/code-generator/cmd/prerelease-lifecycle-gen/prerelease-lifecycle-generators/status.go +++ b/staging/src/k8s.io/code-generator/cmd/prerelease-lifecycle-gen/prerelease-lifecycle-generators/status.go @@ -137,21 +137,24 @@ func extractReplacementTag(t *types.Type) (group, version, kind string, hasRepla } func extractTag(tagName string, comments []string) *tagValue { - tagVals := gengo.ExtractCommentTags("+", comments)[tagName] - if tagVals == nil { + tags, err := genutil.ExtractCommentTagsWithoutArguments("+", []string{tagName}, comments) + if err != nil { + klog.Fatalf("Error extracting %s tags: %v", tagName, err) + } + if tags[tagName] == nil { // No match for the tag. return nil } // If there are multiple values, abort. - if len(tagVals) > 1 { - klog.Fatalf("Found %d %s tags: %q", len(tagVals), tagName, tagVals) + if len(tags[tagName]) > 1 { + klog.Fatalf("Found %d %s tags: %q", len(tags[tagName]), tagName, tags[tagName]) } // If we got here we are returning something. tag := &tagValue{} // Get the primary value. - parts := strings.Split(tagVals[0], ",") + parts := strings.Split(tags[tagName][0], ",") if len(parts) >= 1 { tag.value = parts[0] } diff --git a/staging/src/k8s.io/code-generator/cmd/register-gen/generators/targets.go b/staging/src/k8s.io/code-generator/cmd/register-gen/generators/targets.go index 952e276f7b5..ac465f91bbc 100644 --- a/staging/src/k8s.io/code-generator/cmd/register-gen/generators/targets.go +++ b/staging/src/k8s.io/code-generator/cmd/register-gen/generators/targets.go @@ -26,6 +26,7 @@ import ( clientgentypes "k8s.io/code-generator/cmd/client-gen/types" "k8s.io/code-generator/cmd/register-gen/args" + genutil "k8s.io/code-generator/pkg/util" "k8s.io/gengo/v2" "k8s.io/gengo/v2/generator" "k8s.io/gengo/v2/namer" @@ -83,8 +84,13 @@ func GetTargets(context *generator.Context, args *args.Args) []generator.Target // if there is a comment of the form "// +groupName=somegroup" or "// +groupName=somegroup.foo.bar.io", // extract the fully qualified API group name from it and overwrite the group inferred from the package path - if override := gengo.ExtractCommentTags("+", pkg.Comments)["groupName"]; override != nil { - groupName := override[0] + override, err := genutil.ExtractCommentTagsWithoutArguments("+", []string{"groupName"}, pkg.Comments) + if err != nil { + klog.Errorf("error extracting groupName tags: %v", err) + continue + } + if override["groupName"] != nil { + groupName := override["groupName"][0] klog.V(5).Infof("overriding the group name with = %s", groupName) gv.Group = clientgentypes.Group(groupName) }