Skip to content

Commit 35ffe38

Browse files
issue-5446-cli-help-enhancements
Update init.go
1 parent 66f3131 commit 35ffe38

7 files changed

Lines changed: 133 additions & 103 deletions

File tree

internal/cli/alpha/generate.go

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -43,20 +43,27 @@ func NewScaffoldCommand() *cobra.Command {
4343
scaffoldCmd := &cobra.Command{
4444
Use: "generate",
4545
Short: "Re-scaffold a Kubebuilder project from its PROJECT file",
46-
Long: `The 'generate' command re-creates a Kubebuilder project scaffold based on the configuration
47-
defined in the PROJECT file, using the latest installed Kubebuilder version and plugins.
46+
Long: `Re-generate a Kubebuilder project scaffold based on the PROJECT file configuration.
4847
49-
This is helpful for migrating projects to a newer Kubebuilder layout or plugin version (e.g., v3 to v4)
50-
as update your project from any previous version to the current one.
48+
This command uses the latest installed Kubebuilder version and plugins to regenerate
49+
the entire project structure.
5150
52-
If no output directory is provided, the current working directory will be cleaned (except .git and PROJECT).`,
51+
This is helpful for migrating projects to newer Kubebuilder
52+
layouts or plugin version (e.g., v3 to v4)
53+
54+
This command deletes all files except .git/ and PROJECT before regenerating in-place when
55+
--output-dir is not specified.
56+
57+
The PROJECT file must exist and contain valid plugin configuration.`,
5358
Example: `
54-
# **WARNING**(will delete all files to allow the re-scaffold except .git and PROJECT)
55-
# Re-scaffold the project in-place
59+
# Re-scaffold in-place (WARNING: deletes all files except .git and PROJECT)
5660
kubebuilder alpha generate
5761
58-
# Re-scaffold the project from ./test into ./my-output
59-
kubebuilder alpha generate --input-dir="./path/to/project" --output-dir="./my-output"
62+
# Re-scaffold to a different directory (safe, preserves original)
63+
kubebuilder alpha generate --output-dir="./regenerated"
64+
65+
# Re-scaffold from a specific project directory to a different directory
66+
kubebuilder alpha generate --input-dir="./my-project" --output-dir="./my-project-v4"
6067
`,
6168
PreRunE: func(_ *cobra.Command, _ []string) error {
6269
return opts.Validate()
@@ -70,13 +77,12 @@ If no output directory is provided, the current working directory will be cleane
7077
}
7178

7279
scaffoldCmd.Flags().StringVar(&opts.InputDir, "input-dir", "",
73-
"Path to the directory containing the PROJECT file. "+
74-
"Defaults to the current working directory. WARNING: delete existing files (except .git and PROJECT).")
80+
"path to directory containing the PROJECT file (default: current directory). "+
81+
"WARNING: if --output-dir is not set, all files except .git/ and PROJECT will be deleted")
7582

7683
scaffoldCmd.Flags().StringVar(&opts.OutputDir, "output-dir", "",
77-
"Directory where the new project scaffold will be written. "+
78-
"If unset, re-scaffolding occurs in-place "+
79-
"and will delete existing files (except .git and PROJECT).")
84+
"path to directory where regenerated scaffold will be written. "+
85+
"If not set, regenerates in-place and deletes existing files (except .git/ and PROJECT)")
8086

8187
return scaffoldCmd
8288
}

internal/cli/alpha/update.go

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -145,38 +145,39 @@ Defaults:
145145
}
146146

147147
updateCmd.Flags().StringVar(&opts.FromVersion, "from-version", "",
148-
"binary release version to upgrade from. Should match the version used to init the project and be "+
149-
"a valid release version, e.g., v4.6.0. If not set, it defaults to the version specified in the PROJECT file.")
148+
"Kubebuilder version to upgrade from (e.g., v4.6.0). Should match version used to initialize project "+
149+
"If not set, uses version from PROJECT file")
150150
updateCmd.Flags().StringVar(&opts.ToVersion, "to-version", "",
151-
"binary release version to upgrade to. Should be a valid release version, e.g., v4.7.0. "+
152-
"If not set, it defaults to the latest release version available in the project repository.")
151+
"Kubebuilder version to upgrade to (e.g., v4.7.0). "+
152+
"If not set, uses latest version available in the project repository")
153153
updateCmd.Flags().StringVar(&opts.FromBranch, "from-branch", "",
154-
"Git branch to use as current state of the project for the update.")
154+
"Git branch containing current project state (default: main)")
155155
updateCmd.Flags().BoolVar(&opts.Force, "force", false,
156-
"Force the update even if conflicts occur. Conflicted files will include conflict markers, and a "+
157-
"commit will be created automatically. Ideal for automation (e.g., cronjobs, CI).")
156+
"if true, commit even with conflicts (adds conflict markers). "+
157+
"Ideal for automation (CI/CD pipelines, cronjobs)")
158158
updateCmd.Flags().BoolVar(&opts.ShowCommits, "show-commits", false,
159-
"If set, the update will keep the full history instead of squashing into a single commit.")
159+
"if true, keep full commit history instead of squashing. "+
160+
"Cannot be used with --restore-path")
160161
updateCmd.Flags().StringArrayVar(&opts.RestorePath, "restore-path", nil,
161-
"Paths to preserve from the base branch (repeatable). Not supported with --show-commits.")
162+
"paths to preserve from base branch (repeatable, e.g., --restore-path .github/workflows). "+
163+
"Cannot be used with --show-commits")
162164
updateCmd.Flags().StringVar(&opts.OutputBranch, "output-branch", "",
163165
"Override the default output branch name (default: kubebuilder-update-from-<from-version>-to-<to-version>).")
164166
updateCmd.Flags().BoolVar(&opts.Push, "push", false,
165-
"Push the output branch to the remote repository after the update.")
167+
"if true, push output branch to origin after update")
166168
updateCmd.Flags().StringVar(&opts.CommitMessage, "merge-message", "",
167-
"Custom commit message for successful merges (no conflicts). "+
168-
"Defaults to 'chore(kubebuilder): update scaffold <from> -> <to>'.")
169+
"custom commit message for clean merges (no conflicts)"+
170+
"(default: 'chore(kubebuilder): update scaffold <from> -> <to>')")
169171
updateCmd.Flags().StringVar(&opts.CommitMessageConflict, "conflict-message", "",
170-
"Custom commit message for merges with conflicts. "+
171-
"Defaults to 'chore(kubebuilder): (:warning: manual conflict resolution required) update scaffold <from> -> <to>'.")
172+
"custom commit message for merges with conflicts. "+
173+
"(default: 'chore(kubebuilder): (:warning: manual conflict resolution required) update scaffold <from> -> <to>')")
172174
updateCmd.Flags().BoolVar(&opts.OpenGhIssue, "open-gh-issue", false,
173-
"Create a GitHub issue with a pre-filled checklist and compare link after the update completes (requires `gh`).")
175+
"if true, create GitHub issue with a pre-filled checklist and compare link (requires gh CLI)")
174176
updateCmd.Flags().BoolVar(
175177
&opts.UseGhModels,
176178
"use-gh-models",
177179
false,
178-
"Generate and post an AI summary comment to the GitHub Issue using `gh models run`. "+
179-
"Requires --open-gh-issue and GitHub CLI (`gh`) with the `gh-models` extension.")
180+
"if true, add AI-generated summary comment to GitHub issue (requires --open-gh-issue and gh CLI with gh-models extension)")
180181
updateCmd.Flags().StringArrayVar(
181182
&gitCfg,
182183
"git-config",

pkg/cli/root.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ func (c CLI) newRootCmd() *cobra.Command {
105105
cmd.PersistentFlags().StringSlice(pluginsFlag, nil, "plugin keys to be used for this subcommand execution")
106106

107107
// Register --project-version on the root command so that it shows up in help.
108-
cmd.Flags().String(projectVersionFlag, c.defaultProjectVersion.String(), "project version")
108+
cmd.Flags().String(projectVersionFlag, c.defaultProjectVersion.String(), "project version to scaffold (default: latest stable)")
109109

110110
// As the root command will be used to shot the help message under some error conditions,
111111
// like during plugin resolving, we need to allow unknown flags to prevent parsing errors.

pkg/plugins/golang/v4/api.go

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,6 @@ make generate will be run.
7070
%[1]s create api --group ship --version v1beta1 --kind Frigate
7171
7272
# Edit the API Scheme
73-
7473
nano api/v1beta1/frigate_types.go
7574
7675
# Edit the Controller
@@ -91,34 +90,35 @@ make generate will be run.
9190
}
9291

9392
func (p *createAPISubcommand) BindFlags(fs *pflag.FlagSet) {
94-
fs.BoolVar(&p.runMake, "make", true, "if true, run `make generate` after generating files")
93+
fs.BoolVar(&p.runMake, "make", true, "if true, run `make generate` after scaffolding (default: true)")
9594

9695
fs.BoolVar(&p.force, "force", false,
97-
"attempt to create resource even if it already exists")
96+
"if true, attempt to create resource even if it already exists")
9897

9998
p.options = &goPlugin.Options{}
10099

101-
fs.StringVar(&p.options.Plural, "plural", "", "resource irregular plural form")
100+
fs.StringVar(&p.options.Plural, "plural", "", "specify irregular plural form of the resource (e.g., 'mice' for 'Mouse')")
102101

103102
fs.BoolVar(&p.options.DoAPI, "resource", true,
104-
"if set, generate the resource without prompting the user")
103+
"if true, scaffold the API resource types without prompting (default: true)")
105104
p.resourceFlag = fs.Lookup("resource")
106-
fs.BoolVar(&p.options.Namespaced, "namespaced", true, "resource is namespaced")
105+
fs.BoolVar(&p.options.Namespaced, "namespaced", true, "if true, resource is namespace-scoped rather than cluster-scoped (default: true)")
107106

108107
fs.BoolVar(&p.options.DoController, "controller", true,
109-
"if set, generate the controller without prompting the user")
108+
"if true, scaffold the controller without prompting (default: true)")
110109
p.controllerFlag = fs.Lookup("controller")
111110

112111
fs.StringVar(&p.options.ExternalAPIPath, "external-api-path", "",
113-
"Specify the Go package import path for the external API. This is used to scaffold controllers for resources "+
114-
"defined outside this project (e.g., github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1).")
112+
"specify Go package import path for external API (e.g., github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1). "+
113+
"Used to scaffold controllers for external types with --resource=false")
115114

116115
fs.StringVar(&p.options.ExternalAPIDomain, "external-api-domain", "",
117-
"Specify the domain name for the external API. This domain is used to generate accurate RBAC "+
118-
"markers and permissions for the external resources (e.g., cert-manager.io).")
116+
"specify domain for external API (e.g., cert-manager.io). "+
117+
"Used to generate accurate RBAC markers for external resources. Requires --external-api-path")
119118

120119
fs.StringVar(&p.options.ExternalAPIModule, "external-api-module", "",
121-
"external API module with optional version (e.g., github.com/cert-manager/cert-manager@v1.18.2)")
120+
"external API Go module with optional version (e.g., github.com/cert-manager/cert-manager@v1.18.2). "+
121+
"Requires --external-api-path")
122122
}
123123

124124
func (p *createAPISubcommand) InjectConfig(c config.Config) error {

pkg/plugins/golang/v4/edit.go

Lines changed: 49 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -43,57 +43,75 @@ type editSubcommand struct {
4343
func (p *editSubcommand) UpdateMetadata(cliMeta plugin.CLIMetadata, subcmdMeta *plugin.SubcommandMetadata) {
4444
subcmdMeta.Description = `Edit project configuration to enable or disable layout settings.
4545
46-
Multigroup (--multigroup):
47-
Enable or disable multi-group layout.
48-
Changes API structure: api/<version>/ becomes api/<group>/<version>/
49-
Automatic: Updates PROJECT file, future APIs use new structure
50-
Manual: Move existing API files, update import paths in controllers
51-
More info: https://book.kubebuilder.io/migration/multi-group.html
52-
53-
Namespaced (--namespaced):
54-
Enable or disable namespace-scoped deployment.
55-
Manager watches one or more specific namespaces vs all namespaces.
56-
Namespaces to watch are configured via WATCH_NAMESPACE environment variable.
57-
Automatic: Updates PROJECT file, scaffolds Role/RoleBinding, uses --force to regenerate manager.yaml
58-
Manual: Add namespace= to RBAC markers in existing controllers, update cmd/main.go, run 'make manifests'
59-
More info: https://book.kubebuilder.io/migration/namespace-scoped.html
60-
61-
WARNING - Webhooks and Namespace-Scoped Mode:
62-
Webhooks remain cluster-scoped even in namespace-scoped mode.
63-
The manager cache is restricted to WATCH_NAMESPACE, but webhooks receive requests
64-
from ALL namespaces. You must configure namespaceSelector or objectSelector to align
65-
webhook scope with the cache.
66-
67-
Force (--force):
68-
Overwrite existing scaffolded files to apply configuration changes.
69-
Example: With --namespaced, regenerates config/manager/manager.yaml to add WATCH_NAMESPACE env var.
70-
Warning: This overwrites default scaffold files; manual changes in those files may be lost.
46+
This command modifies the PROJECT file and optionally regenerates scaffolded files.
47+
Use this to change layout settings or add optional plugins after project initialization.
48+
49+
50+
Plugin flags:
51+
--plugins: Comma-separated list of plugins to add to the project
52+
Plugins are saved to the PROJECT file and used in future operations
53+
Run 'kubebuilder edit --plugins --help' to see available plugins
54+
55+
Layout flags:
56+
--multigroup: Enable/Disable multigroup layout to organize APIs by group
57+
Scaffolds APIs in api/<group>/<version>/ instead of api/<version>/
58+
Useful when managing multiple API groups (e.g., batch, apps, crew)
59+
Automatic: Updates PROJECT file; future APIs use new structure
60+
Manual: Move existing API files, update import paths in controllers
61+
More info: https://book.kubebuilder.io/migration/multi-group.html
62+
63+
--namespaced: Enable/Disable namespace-scoped deployment instead of cluster-scoped
64+
Manager watches one or more specific namespaces instead of all namespaces
65+
Namespaces to watch are configured via WATCH_NAMESPACE environment variable
66+
Uses Role/RoleBinding instead of ClusterRole/ClusterRoleBinding
67+
Automatic: Updates PROJECT file, scaffolds Role/RoleBinding
68+
Manual: Add namespace= to RBAC markers in controllers, update cmd/main.go, run 'make manifests'
69+
More info: https://book.kubebuilder.io/migration/namespace-scoped.html
70+
71+
WARNING - Webhooks and Namespace-Scoped Mode:
72+
Webhooks remain cluster-scoped even in namespace-scoped mode.
73+
The manager cache is restricted to WATCH_NAMESPACE, but webhooks receive requests
74+
from ALL namespaces. Configure namespaceSelector or objectSelector to align
75+
webhook scope with the cache.
76+
77+
--force: Overwrite existing scaffolded files to apply configuration changes
78+
Example: With --namespaced, regenerates config/manager/manager.yaml to add WATCH_NAMESPACE
79+
Warning: Overwrites default scaffold files; manual changes may be lost
7180
7281
Note: To add optional plugins after initialization, use 'kubebuilder edit --plugins <plugin-name>'.
7382
Run 'kubebuilder edit --plugins --help' to see available plugins.
7483
`
7584
subcmdMeta.Examples = fmt.Sprintf(` # Enable multigroup layout
7685
%[1]s edit --multigroup
7786
78-
# Enable namespace-scoped permissions
87+
# Enable namespace-scoped deployment
7988
%[1]s edit --namespaced
8089
81-
# Enable with automatic file regeneration
90+
# Enable namespace-scoped with automatic file regeneration
8291
%[1]s edit --namespaced --force
8392
8493
# Disable multigroup layout
8594
%[1]s edit --multigroup=false
8695
87-
# Enable/disable multiple settings
96+
# Enable/Disable multiple settings at once
8897
%[1]s edit --multigroup --namespaced --force
98+
99+
# Add Helm plugin to existing project
100+
%[1]s edit --plugins helm/v2-alpha
101+
102+
# Add multiple plugins
103+
%[1]s edit --plugins grafana/v1-alpha,autoupdate/v1-alpha
89104
`, cliMeta.CommandName)
90105
}
91106

92107
func (p *editSubcommand) BindFlags(fs *pflag.FlagSet) {
93108
p.fs = fs
94-
fs.BoolVar(&p.multigroup, "multigroup", false, "enable or disable multigroup layout")
95-
fs.BoolVar(&p.namespaced, "namespaced", false, "enable or disable namespace-scoped deployment")
96-
fs.BoolVar(&p.force, "force", false, "overwrite scaffolded files to apply changes (manual edits may be lost)")
109+
fs.BoolVar(&p.multigroup, "multigroup", false,
110+
"enable or disable multigroup layout (api/<group>/<version>/)")
111+
fs.BoolVar(&p.namespaced, "namespaced", false,
112+
"enable or disable namespace-scoped deployment (default: cluster-scoped)")
113+
fs.BoolVar(&p.force, "force", false,
114+
"overwrite scaffolded files to apply configuration changes (manual edits may be lost)")
97115
}
98116

99117
func (p *editSubcommand) InjectConfig(c config.Config) error {

pkg/plugins/golang/v4/init.go

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -64,20 +64,24 @@ type initSubcommand struct {
6464
func (p *initSubcommand) UpdateMetadata(cliMeta plugin.CLIMetadata, subcmdMeta *plugin.SubcommandMetadata) {
6565
p.commandName = cliMeta.CommandName
6666

67-
subcmdMeta.Description = `Initialize a new project including the following files:
68-
- a "go.mod" with project dependencies
69-
- a "PROJECT" file that stores project configuration
70-
- a "Makefile" with several useful make targets for the project
71-
- several YAML files for project deployment under the "config" directory
72-
- a "cmd/main.go" file that creates the manager that will run the project controllers
67+
subcmdMeta.Description = `Initialize a new project within the current directory. Following files will be generated automatically:
68+
- go.mod: Go module with project dependencies
69+
- PROJECT: file that stores project configuration
70+
- Makefile: provides useful make targets for the project
71+
- config/: Kubernetes manifests for deployment
72+
- cmd/main.go: controller manager entry point
73+
- Dockerfile: build controller manager container image
74+
- test/: unit tests for the project
75+
- hack/: contains licensing boilerplate.
76+
7377
7478
Required flags:
7579
--domain: Domain for your APIs (e.g., example.org creates crew.example.org for API groups)
7680
7781
Configuration flags:
7882
--repo: Go module path (e.g., github.com/user/repo); auto-detected if not provided
7983
--owner: Owner name for copyright license headers
80-
--license: License to use (apache2 or none, default: apache2)
84+
--license: License to use (apache2 | none; default "apache2")
8185
8286
Plugin flags:
8387
--plugins: Comma-separated list of plugins to use (default: go/v4)
@@ -120,21 +124,21 @@ Note: Layout settings can be changed later with 'kubebuilder edit'.
120124

121125
func (p *initSubcommand) BindFlags(fs *pflag.FlagSet) {
122126
fs.BoolVar(&p.skipGoVersionCheck, "skip-go-version-check",
123-
false, "skip Go version check")
127+
false, "if true, skip compatibility check of Kubebuilder plugin supported version vs installed Go version (default: false)")
124128

125129
// dependency args
126-
fs.BoolVar(&p.fetchDeps, "fetch-deps", true, "download dependencies after scaffolding")
130+
fs.BoolVar(&p.fetchDeps, "fetch-deps", true, "if true, download Go dependencies after scaffolding (default: true)")
127131

128132
// boilerplate args
129133
fs.StringVar(&p.license, "license", "apache2",
130-
"license header to use (apache2 or none)")
131-
fs.StringVar(&p.owner, "owner", "", "copyright owner for license headers")
134+
"license to use for boilerplate headers (apache2 or none)")
135+
fs.StringVar(&p.owner, "owner", "", "owner name for copyright license headers")
132136

133137
// project args
134138
fs.StringVar(&p.repo, "repo", "", "Go module name (e.g., github.com/user/repo); "+
135139
"auto-detected from current directory if not provided")
136140
fs.BoolVar(&p.multigroup, "multigroup", false,
137-
"enable multigroup layout (organize APIs by group)")
141+
"enable multigroup layout to organize APIs by group (api/<group>/<version>/)")
138142
fs.BoolVar(&p.namespaced, "namespaced", false,
139143
"enable namespace-scoped deployment (default: cluster-scoped)")
140144
}

0 commit comments

Comments
 (0)