Skip to content

Commit

Permalink
Merge pull request #1000 from twz123/optional-groupname
Browse files Browse the repository at this point in the history
✨ Make the anonymous field of the groupName marker optional
  • Loading branch information
k8s-ci-robot authored Jul 16, 2024
2 parents 979e571 + 7c1db6b commit b1ff5ff
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 4 deletions.
2 changes: 1 addition & 1 deletion pkg/crd/markers/package.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import (

func init() {
AllDefinitions = append(AllDefinitions,
must(markers.MakeDefinition("groupName", markers.DescribesPackage, "")).
mustOptional(markers.MakeDefinition("groupName", markers.DescribesPackage, "")).
WithHelp(markers.SimpleHelp("CRD", "specifies the API group name for this package.")),

must(markers.MakeDefinition("versionName", markers.DescribesPackage, "")).
Expand Down
14 changes: 14 additions & 0 deletions pkg/crd/markers/register.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ limitations under the License.
package markers

import (
"fmt"
"reflect"

"sigs.k8s.io/controller-tools/pkg/markers"
Expand Down Expand Up @@ -56,6 +57,19 @@ func must(def *markers.Definition, err error) *definitionWithHelp {
}
}

func mustOptional(def *markers.Definition, err error) *definitionWithHelp {
def = markers.Must(def, err)
if !def.AnonymousField() {
def = markers.Must(def, fmt.Errorf("not an anonymous field: %v", def))
}
field := def.Fields[""]
field.Optional = true
def.Fields[""] = field
return &definitionWithHelp{
Definition: def,
}
}

// AllDefinitions contains all marker definitions for this package.
var AllDefinitions []*definitionWithHelp

Expand Down
20 changes: 17 additions & 3 deletions pkg/crd/parser_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,9 +100,9 @@ var _ = Describe("CRD Generation From Parsing to CustomResourceDefinition", func
}
})

assertCRD := func(pkg *loader.Package, kind, fileName string) {
By(fmt.Sprintf("requesting that the %s CRD be generated", kind))
groupKind := schema.GroupKind{Kind: kind, Group: "testdata.kubebuilder.io"}
assertCRDForGroupKind := func(pkg *loader.Package, groupKind schema.GroupKind, fileName string) {
kind := groupKind.Kind
By(fmt.Sprintf("requesting that the %s CRD be generated in group %s", kind, groupKind.Group))
parser.NeedCRDFor(groupKind, nil)

By(fmt.Sprintf("fixing top level ObjectMeta on the %s CRD", kind))
Expand Down Expand Up @@ -131,6 +131,10 @@ var _ = Describe("CRD Generation From Parsing to CustomResourceDefinition", func
ExpectWithOffset(1, parser.CustomResourceDefinitions[groupKind]).To(Equal(crd), "type not as expected, check pkg/crd/testdata/README.md for more details.\n\nDiff:\n\n%s", cmp.Diff(parser.CustomResourceDefinitions[groupKind], crd))
}

assertCRD := func(pkg *loader.Package, kind, fileName string) {
assertCRDForGroupKind(pkg, schema.GroupKind{Group: "testdata.kubebuilder.io", Kind: kind}, fileName)
}

assertError := func(pkg *loader.Package, kind, errorMsg string) {
By(fmt.Sprintf("requesting that the %s CRD be generated", kind))
groupKind := schema.GroupKind{Kind: kind, Group: "testdata.kubebuilder.io"}
Expand Down Expand Up @@ -183,6 +187,16 @@ var _ = Describe("CRD Generation From Parsing to CustomResourceDefinition", func
assertError(pkgs[0], "CronJob", "is not in 'xxx=xxx' format")
})
})

Context("CronJob API without group", func() {
BeforeEach(func() {
pkgPaths = []string{"./nogroup"}
expPkgLen = 1
})
It("should successfully generate the CronJob CRD", func() {
assertCRDForGroupKind(pkgs[0], schema.GroupKind{Kind: "CronJob"}, "testdata._cronjobs.yaml")
})
})
})

It("should generate plural words for Kind correctly", func() {
Expand Down
29 changes: 29 additions & 0 deletions pkg/crd/testdata/nogroup/types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

// +groupName=
package nogroup

import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

// +kubebuilder:object:root=true

// CronJob is the Schema for the cronjobs API
type CronJob struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
}
41 changes: 41 additions & 0 deletions pkg/crd/testdata/testdata._cronjobs.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: (devel)
name: cronjobs.
spec:
group: ""
names:
kind: CronJob
listKind: CronJobList
plural: cronjobs
singular: cronjob
scope: Namespaced
versions:
- name: nogroup
schema:
openAPIV3Schema:
description: CronJob is the Schema for the cronjobs API
properties:
apiVersion:
description: |-
APIVersion defines the versioned schema of this representation of an object.
Servers should convert recognized schemas to the latest internal value, and
may reject unrecognized values.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
type: string
kind:
description: |-
Kind is a string value representing the REST resource this object represents.
Servers may infer this from the endpoint the client submits requests to.
Cannot be updated.
In CamelCase.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
type: string
metadata:
type: object
type: object
served: true
storage: true

0 comments on commit b1ff5ff

Please sign in to comment.