Skip to content

Commit b290147

Browse files
authored
Merge pull request #1967 from Adirio/plurals
⚠ Add --plural flag (go/v3)
2 parents 1e78a6f + 1a6bb7a commit b290147

File tree

19 files changed

+121
-40
lines changed

19 files changed

+121
-40
lines changed

generate_testdata.sh

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,31 +59,47 @@ scaffold_test_project() {
5959
$kb create api --group crew --version v1 --kind Captain --controller=true --resource=true --make=false
6060
$kb create api --group crew --version v1 --kind Captain --controller=true --resource=true --make=false --force
6161
$kb create webhook --group crew --version v1 --kind Captain --defaulting --programmatic-validation
62+
if [ $project == "project-v3" ]; then
63+
$kb create webhook --group crew --version v1 --kind Captain --defaulting --programmatic-validation --force
64+
fi
65+
6266
$kb create api --group crew --version v1 --kind FirstMate --controller=true --resource=true --make=false
6367
$kb create webhook --group crew --version v1 --kind FirstMate --conversion
64-
$kb create api --group crew --version v1 --kind Admiral --controller=true --resource=true --namespaced=false --make=false
65-
$kb create webhook --group crew --version v1 --kind Admiral --defaulting
66-
$kb create api --group crew --version v1 --kind Laker --controller=true --resource=false --make=false
68+
6769
if [ $project == "project-v3" ]; then
68-
$kb create webhook --group crew --version v1 --kind Captain --defaulting --programmatic-validation --force
70+
$kb create api --group crew --version v1 --kind Admiral --plural=admirales --controller=true --resource=true --namespaced=false --make=false
71+
$kb create webhook --group crew --version v1 --kind Admiral --plural=admirales --defaulting
72+
else
73+
$kb create api --group crew --version v1 --kind Admiral --controller=true --resource=true --namespaced=false --make=false
74+
$kb create webhook --group crew --version v1 --kind Admiral --defaulting
6975
fi
76+
77+
$kb create api --group crew --version v1 --kind Laker --controller=true --resource=false --make=false
7078
elif [[ $project =~ multigroup ]]; then
7179
header_text 'Switching to multigroup layout ...'
7280
$kb edit --multigroup=true
7381

7482
header_text 'Creating APIs ...'
7583
$kb create api --group crew --version v1 --kind Captain --controller=true --resource=true --make=false
7684
$kb create webhook --group crew --version v1 --kind Captain --defaulting --programmatic-validation
85+
7786
$kb create api --group ship --version v1beta1 --kind Frigate --controller=true --resource=true --make=false
7887
$kb create webhook --group ship --version v1beta1 --kind Frigate --conversion
88+
7989
$kb create api --group ship --version v1 --kind Destroyer --controller=true --resource=true --namespaced=false --make=false
8090
$kb create webhook --group ship --version v1 --kind Destroyer --defaulting
91+
8192
$kb create api --group ship --version v2alpha1 --kind Cruiser --controller=true --resource=true --namespaced=false --make=false
8293
$kb create webhook --group ship --version v2alpha1 --kind Cruiser --programmatic-validation
94+
8395
$kb create api --group sea-creatures --version v1beta1 --kind Kraken --controller=true --resource=true --make=false
96+
8497
$kb create api --group sea-creatures --version v1beta2 --kind Leviathan --controller=true --resource=true --make=false
98+
8599
$kb create api --group foo.policy --version v1 --kind HealthCheckPolicy --controller=true --resource=true --make=false
100+
86101
$kb create api --group apps --version v1 --kind Pod --controller=true --resource=false --make=false
102+
87103
if [ $project == "project-v3-multigroup" ]; then
88104
$kb create api --version v1 --kind Lakers --controller=true --resource=true --make=false
89105
$kb create webhook --version v1 --kind Lakers --defaulting --programmatic-validation

pkg/model/resource/resource.go

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,11 @@ func (r Resource) HasConversionWebhook() bool {
8585
return r.Webhooks != nil && r.Webhooks.Conversion
8686
}
8787

88+
// IsRegularPlural returns true if the plural is the regular plural form for the kind.
89+
func (r Resource) IsRegularPlural() bool {
90+
return r.Plural == RegularPlural(r.Kind)
91+
}
92+
8893
// Copy returns a deep copy of the Resource that can be safely modified without affecting the original.
8994
func (r Resource) Copy() Resource {
9095
// As this function doesn't use a pointer receiver, r is already a shallow copy.
@@ -112,9 +117,13 @@ func (r *Resource) Update(other Resource) error {
112117
return fmt.Errorf("unable to update a Resource with another with non-matching GVK")
113118
}
114119

115-
// TODO: currently Plural & Path will always match. In the future, this may not be true (e.g. providing a
116-
// --plural flag). In that case, we should yield an error in case of updating two resources with different
117-
// values for these fields.
120+
if r.Plural != other.Plural {
121+
return fmt.Errorf("unable to update Resource with another with non-matching Plural")
122+
}
123+
124+
if r.Path != other.Path {
125+
return fmt.Errorf("unable to update Resource with another with non-matching Path")
126+
}
118127

119128
// Update API.
120129
if r.API == nil && other.API != nil {

pkg/model/resource/resource_test.go

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,16 @@ var _ = Describe("Resource", func() {
138138
Entry("no conversion", Resource{Webhooks: &Webhooks{Conversion: false}}),
139139
)
140140
})
141+
142+
Context("IsRegularPlural", func() {
143+
It("should return true if the regular plural form is used", func() {
144+
Expect(Resource{GVK: GVK{Kind: "FirstMate"}, Plural: "firstmates"}.IsRegularPlural()).To(BeTrue())
145+
})
146+
147+
It("should return false if an irregular plural form is used", func() {
148+
Expect(Resource{GVK: GVK{Kind: "FirstMate"}, Plural: "mates"}.IsRegularPlural()).To(BeFalse())
149+
})
150+
})
141151
})
142152

143153
Context("Copy", func() {
@@ -251,6 +261,46 @@ var _ = Describe("Resource", func() {
251261
Expect(r.Update(other)).NotTo(Succeed())
252262
})
253263

264+
It("should fail for different Plurals", func() {
265+
r = Resource{
266+
GVK: GVK{
267+
Group: group,
268+
Version: version,
269+
Kind: kind,
270+
},
271+
Plural: "kinds",
272+
}
273+
other = Resource{
274+
GVK: GVK{
275+
Group: group,
276+
Version: version,
277+
Kind: kind,
278+
},
279+
Plural: "types",
280+
}
281+
Expect(r.Update(other)).NotTo(Succeed())
282+
})
283+
284+
It("should fail for different Paths", func() {
285+
r = Resource{
286+
GVK: GVK{
287+
Group: group,
288+
Version: version,
289+
Kind: kind,
290+
},
291+
Path: "api/v1",
292+
}
293+
other = Resource{
294+
GVK: GVK{
295+
Group: group,
296+
Version: version,
297+
Kind: kind,
298+
},
299+
Path: "apis/group/v1",
300+
}
301+
Expect(r.Update(other)).NotTo(Succeed())
302+
})
303+
254304
Context("API", func() {
255305
It("should work with nil APIs", func() {
256306
r = Resource{

pkg/plugins/golang/v3/api.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ func (p *createAPISubcommand) BindFlags(fs *pflag.FlagSet) {
121121
p.options.Domain = p.config.GetDomain()
122122
fs.StringVar(&p.options.Version, "version", "", "resource Version")
123123
fs.StringVar(&p.options.Kind, "kind", "", "resource Kind")
124-
// p.options.Plural can be set to specify an irregular plural form
124+
fs.StringVar(&p.options.Plural, "plural", "", "resource irregular plural form")
125125

126126
fs.BoolVar(&p.options.DoAPI, "resource", true,
127127
"if set, generate the resource without prompting the user")

pkg/plugins/golang/v3/scaffolds/internal/templates/api/types.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,13 @@ type {{ .Resource.Kind }}Status struct {
9191
9292
//+kubebuilder:object:root=true
9393
//+kubebuilder:subresource:status
94-
{{ if not .Resource.API.Namespaced }} //+kubebuilder:resource:scope=Cluster {{ end }}
94+
{{- if and (not .Resource.API.Namespaced) (not .Resource.IsRegularPlural) }}
95+
//+kubebuilder:resource:path={{ .Resource.Plural }},scope=Cluster
96+
{{- else if not .Resource.API.Namespaced }}
97+
//+kubebuilder:resource:scope=Cluster
98+
{{- else if not .Resource.IsRegularPlural }}
99+
//+kubebuilder:resource:path={{ .Resource.Plural }}
100+
{{- end }}
95101
96102
// {{ .Resource.Kind }} is the Schema for the {{ .Resource.Plural }} API
97103
type {{ .Resource.Kind }} struct {

pkg/plugins/golang/v3/webhook.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ func (p *createWebhookSubcommand) BindFlags(fs *pflag.FlagSet) {
7676
p.options.Domain = p.config.GetDomain()
7777
fs.StringVar(&p.options.Version, "version", "", "resource Version")
7878
fs.StringVar(&p.options.Kind, "kind", "", "resource Kind")
79-
fs.StringVar(&p.options.Plural, "resource", "", "resource irregular plural form")
79+
fs.StringVar(&p.options.Plural, "plural", "", "resource irregular plural form")
8080

8181
fs.StringVar(&p.options.WebhookVersion, "webhook-version", defaultWebhookVersion,
8282
"version of {Mutating,Validating}WebhookConfigurations to scaffold. Options: [v1, v1beta1]")

testdata/project-v3/api/v1/admiral_types.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,9 @@ type AdmiralStatus struct {
4040

4141
//+kubebuilder:object:root=true
4242
//+kubebuilder:subresource:status
43-
//+kubebuilder:resource:scope=Cluster
43+
//+kubebuilder:resource:path=admirales,scope=Cluster
4444

45-
// Admiral is the Schema for the admirals API
45+
// Admiral is the Schema for the admirales API
4646
type Admiral struct {
4747
metav1.TypeMeta `json:",inline"`
4848
metav1.ObjectMeta `json:"metadata,omitempty"`

testdata/project-v3/api/v1/admiral_webhook.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ func (r *Admiral) SetupWebhookWithManager(mgr ctrl.Manager) error {
3333

3434
// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN!
3535

36-
//+kubebuilder:webhook:path=/mutate-crew-testproject-org-v1-admiral,mutating=true,failurePolicy=fail,sideEffects=None,groups=crew.testproject.org,resources=admirals,verbs=create;update,versions=v1,name=madmiral.kb.io,admissionReviewVersions={v1,v1beta1}
36+
//+kubebuilder:webhook:path=/mutate-crew-testproject-org-v1-admiral,mutating=true,failurePolicy=fail,sideEffects=None,groups=crew.testproject.org,resources=admirales,verbs=create;update,versions=v1,name=madmiral.kb.io,admissionReviewVersions={v1,v1beta1}
3737

3838
var _ webhook.Defaulter = &Admiral{}
3939

testdata/project-v3/api/v1/webhook_suite_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,10 +109,10 @@ var _ = BeforeSuite(func() {
109109
err = (&Captain{}).SetupWebhookWithManager(mgr)
110110
Expect(err).NotTo(HaveOccurred())
111111

112-
err = (&Admiral{}).SetupWebhookWithManager(mgr)
112+
err = (&Captain{}).SetupWebhookWithManager(mgr)
113113
Expect(err).NotTo(HaveOccurred())
114114

115-
err = (&Captain{}).SetupWebhookWithManager(mgr)
115+
err = (&Admiral{}).SetupWebhookWithManager(mgr)
116116
Expect(err).NotTo(HaveOccurred())
117117

118118
//+kubebuilder:scaffold:webhook

testdata/project-v3/config/crd/bases/crew.testproject.org_admirals.yaml renamed to testdata/project-v3/config/crd/bases/crew.testproject.org_admirales.yaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,20 @@ metadata:
66
annotations:
77
controller-gen.kubebuilder.io/version: v0.4.1
88
creationTimestamp: null
9-
name: admirals.crew.testproject.org
9+
name: admirales.crew.testproject.org
1010
spec:
1111
group: crew.testproject.org
1212
names:
1313
kind: Admiral
1414
listKind: AdmiralList
15-
plural: admirals
15+
plural: admirales
1616
singular: admiral
1717
scope: Cluster
1818
versions:
1919
- name: v1
2020
schema:
2121
openAPIV3Schema:
22-
description: Admiral is the Schema for the admirals API
22+
description: Admiral is the Schema for the admirales API
2323
properties:
2424
apiVersion:
2525
description: 'APIVersion defines the versioned schema of this representation

0 commit comments

Comments
 (0)