Skip to content

Commit 63e8cd8

Browse files
Merge pull request #137230 from lalitc375/support-subresource
Convert {is,supports}SubResource to modern tag parsing Kubernetes-commit: fe943aff0ce4be7f2fc93c3e8c1e2b34e5044513
2 parents ee7689f + 8537c25 commit 63e8cd8

5 files changed

Lines changed: 51 additions & 29 deletions

File tree

cmd/validation-gen/output_tests/tags/supported_resources/issubresource/doc.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ var localSchemeBuilder = testscheme.New()
2828

2929
// Root resource is supported by default
3030

31-
// +k8s:isSubresource=/scale
31+
// +k8s:isSubresource="/scale"
3232

3333
// T1 is a test type
3434
type T1 struct {

cmd/validation-gen/output_tests/tags/supported_resources/subresource/doc.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,9 @@ var localSchemeBuilder = testscheme.New()
2828

2929
// Root resource is supported by default
3030

31-
// +k8s:supportsSubresource=/status
32-
// +k8s:supportsSubresource=/scale
33-
// +k8s:supportsSubresource=/x/y
31+
// +k8s:supportsSubresource="/status"
32+
// +k8s:supportsSubresource="/scale"
33+
// +k8s:supportsSubresource="/x/y"
3434

3535
// T1 is a test type
3636
type T1 struct {

cmd/validation-gen/targets.go

Lines changed: 44 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@ import (
3535

3636
// These are the comment tags that carry parameters for validation generation.
3737
const (
38-
tagName = "k8s:validation-gen"
39-
inputTagName = "k8s:validation-gen-input"
38+
mainTagName = "k8s:validation-gen" // defines which types to generate validation for
39+
inputTagName = "k8s:validation-gen-input" // indicates that input types are in a different package
4040
schemeRegistryTagName = "k8s:validation-gen-scheme-registry" // defaults to k8s.io/apimachinery/pkg.runtime.Scheme
4141
testFixtureTagName = "k8s:validation-gen-test-fixture" // if set, generate go test files for test fixtures. Supported values: "validateFalse".
4242

@@ -55,12 +55,31 @@ var (
5555
listMetaType = types.Name{Package: metav1Pkg, Name: "ListMeta"}
5656
)
5757

58-
func extractTag(comments []string) ([]string, bool) {
59-
tags, err := gengo.ExtractFunctionStyleCommentTags("+", []string{tagName}, comments)
58+
// extractAndParseTag extracts all the values for a given tag, according to the
59+
// tag grammar.
60+
func extractAndParseTag(tagName string, comments []string) ([]codetags.Tag, error) {
61+
extracted := codetags.Extract("+", comments)
62+
var tags []codetags.Tag
63+
for key, lines := range extracted {
64+
if key != tagName {
65+
continue
66+
}
67+
t, err := codetags.ParseAll(lines)
68+
if err != nil {
69+
return nil, fmt.Errorf("failed to parse tags: %w: %s", err, lines)
70+
}
71+
tags = append(tags, t...)
72+
}
73+
return tags, nil
74+
}
75+
76+
func extractMainTag(comments []string) ([]string, bool) {
77+
// TODO: convert to extractAndParseTag() and update all callers to use quoted values
78+
tags, err := gengo.ExtractFunctionStyleCommentTags("+", []string{mainTagName}, comments)
6079
if err != nil {
6180
klog.Fatalf("Failed to extract tags: %v", err)
6281
}
63-
values, found := tags[tagName]
82+
values, found := tags[mainTagName]
6483
if !found || len(values) == 0 {
6584
return nil, false
6685
}
@@ -73,6 +92,7 @@ func extractTag(comments []string) ([]string, bool) {
7392
}
7493

7594
func extractInputTag(comments []string) []string {
95+
// TODO: convert to extractAndParseTag() and update all callers to use quoted values
7696
tags, err := gengo.ExtractFunctionStyleCommentTags("+", []string{inputTagName}, comments)
7797
if err != nil {
7898
klog.Fatalf("Failed to extract input tags: %v", err)
@@ -89,12 +109,14 @@ func extractInputTag(comments []string) []string {
89109
return result
90110
}
91111

92-
func checkTag(comments []string, require ...string) bool {
93-
tags, err := gengo.ExtractFunctionStyleCommentTags("+", []string{tagName}, comments)
112+
// TODO: this can just accept a single bool
113+
func checkMainTag(comments []string, require ...string) bool {
114+
// TODO: convert to extractAndParseTag() and update all callers to use quoted values
115+
tags, err := gengo.ExtractFunctionStyleCommentTags("+", []string{mainTagName}, comments)
94116
if err != nil {
95117
klog.Fatalf("Failed to extract tags: %v", err)
96118
}
97-
values, found := tags[tagName]
119+
values, found := tags[mainTagName]
98120
if !found {
99121
return false
100122
}
@@ -112,6 +134,7 @@ func checkTag(comments []string, require ...string) bool {
112134
}
113135

114136
func schemeRegistryTag(pkg *types.Package) types.Name {
137+
// TODO: convert to extractAndParseTag() and update all callers to use quoted values
115138
tags, err := gengo.ExtractFunctionStyleCommentTags("+", []string{schemeRegistryTagName}, pkg.Comments)
116139
if err != nil {
117140
klog.Fatalf("Failed to extract scheme registry tags: %v", err)
@@ -130,34 +153,32 @@ func isSubresourceTag(t *types.Type) (string, bool) {
130153
var comments []string
131154
comments = append(comments, t.SecondClosestCommentLines...)
132155
comments = append(comments, t.CommentLines...)
133-
tags, err := gengo.ExtractFunctionStyleCommentTags("+", []string{isSubresourceTagName}, comments)
156+
tags, err := extractAndParseTag(isSubresourceTagName, comments)
134157
if err != nil {
135158
klog.Fatalf("Failed to extract isSubresource tags: %v", err)
136159
}
137-
values, found := tags[isSubresourceTagName]
138-
if !found || len(values) == 0 {
160+
if len(tags) == 0 {
139161
return "", false
140162
}
141-
if len(values) > 1 {
163+
if len(tags) > 1 {
142164
panic(fmt.Sprintf("Type %q contains more than one usage of %q", t.Name.String(), isSubresourceTagName))
143165
}
144-
return values[0].Value, true
166+
return tags[0].Value, true
145167
}
146168

147169
func supportedSubresourceTags(t *types.Type) sets.Set[string] {
148170
var comments []string
149171
comments = append(comments, t.SecondClosestCommentLines...)
150172
comments = append(comments, t.CommentLines...)
151-
tags, err := gengo.ExtractFunctionStyleCommentTags("+", []string{supportsSubresourceTagName}, comments)
173+
tags, err := extractAndParseTag(supportsSubresourceTagName, comments)
152174
if err != nil {
153175
klog.Fatalf("Failed to extract supportedSubresource tags: %v", err)
154176
}
155-
values, found := tags[supportsSubresourceTagName]
156-
if !found || len(values) == 0 {
177+
if len(tags) == 0 {
157178
return sets.New[string]()
158179
}
159180
subresources := sets.New[string]()
160-
for _, tag := range values {
181+
for _, tag := range tags {
161182
subresources.Insert(tag.Value)
162183
}
163184
return subresources
@@ -167,6 +188,7 @@ var testFixtureTagValues = sets.New("validateFalse")
167188

168189
func testFixtureTag(pkg *types.Package) sets.Set[string] {
169190
result := sets.New[string]()
191+
// TODO: convert to extractAndParseTag() and update all callers to use quoted values
170192
tags, err := gengo.ExtractFunctionStyleCommentTags("+", []string{testFixtureTagName}, pkg.Comments)
171193
if err != nil {
172194
klog.Fatalf("Failed to extract test fixture tags: %v", err)
@@ -305,21 +327,21 @@ func GetTargets(context *generator.Context, args *Args) []generator.Target {
305327

306328
schemeRegistry := schemeRegistryTag(pkg)
307329

308-
typesWith, found := extractTag(pkg.Comments)
330+
typesWith, found := extractMainTag(pkg.Comments)
309331
if !found {
310-
klog.V(2).InfoS(" did not find required tag", "tag", tagName)
332+
klog.V(2).InfoS(" did not find required tag", "tag", mainTagName)
311333
continue
312334
}
313335
if len(typesWith) == 1 && typesWith[0] == "" {
314-
klog.Fatalf("found package tag %q with no value", tagName)
336+
klog.Fatalf("found package tag %q with no value", mainTagName)
315337
}
316338
shouldCreateObjectValidationFn := func(t *types.Type) bool {
317339
// opt-out
318-
if checkTag(t.SecondClosestCommentLines, "false") {
340+
if checkMainTag(t.SecondClosestCommentLines, "false") {
319341
return false
320342
}
321343
// opt-in
322-
if checkTag(t.SecondClosestCommentLines, "true") {
344+
if checkMainTag(t.SecondClosestCommentLines, "true") {
323345
return true
324346
}
325347

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ require (
1313
github.com/spf13/pflag v1.0.9
1414
go.yaml.in/yaml/v2 v2.4.3
1515
golang.org/x/text v0.33.0
16-
k8s.io/apimachinery v0.0.0-20260227163238-b6415d345084
16+
k8s.io/apimachinery v0.0.0-20260227203245-48224b4d1ddb
1717
k8s.io/gengo/v2 v2.0.0-20250922181213-ec3ebc5fd46b
1818
k8s.io/klog/v2 v2.130.1
1919
k8s.io/kube-openapi v0.0.0-20260127142750-a19766b6e2d4

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,8 +130,8 @@ gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
130130
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
131131
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
132132
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
133-
k8s.io/apimachinery v0.0.0-20260227163238-b6415d345084 h1:vRyPwew4b3Yiq7mwOpqX+o8qxkT//RhS9FQLN5ziq1A=
134-
k8s.io/apimachinery v0.0.0-20260227163238-b6415d345084/go.mod h1:zqp0Kd80VeQZHyQ4j0VW/sn9zTHYeXFd/brJe5Po20w=
133+
k8s.io/apimachinery v0.0.0-20260227203245-48224b4d1ddb h1:0MWXuP1Qkr2TJBSQ2qYrHARDtTXH4TeTZ9q8OPHOQFM=
134+
k8s.io/apimachinery v0.0.0-20260227203245-48224b4d1ddb/go.mod h1:zqp0Kd80VeQZHyQ4j0VW/sn9zTHYeXFd/brJe5Po20w=
135135
k8s.io/gengo/v2 v2.0.0-20250922181213-ec3ebc5fd46b h1:gMplByicHV/TJBizHd9aVEsTYoJBnnUAT5MHlTkbjhQ=
136136
k8s.io/gengo/v2 v2.0.0-20250922181213-ec3ebc5fd46b/go.mod h1:CgujABENc3KuTrcsdpGmrrASjtQsWCT7R99mEV4U/fM=
137137
k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=

0 commit comments

Comments
 (0)