Optimize usage message of commands which have subcommands.

Signed-off-by: LronDC <lun.su@daocloud.io>
This commit is contained in:
LronDC 2023-05-10 18:10:28 +08:00
parent 484645e817
commit 15678e4a67
4 changed files with 48 additions and 9 deletions

View File

@ -44,10 +44,11 @@ import (
// This is the entry point of create_secret.go which will be called by create.go // This is the entry point of create_secret.go which will be called by create.go
func NewCmdCreateSecret(f cmdutil.Factory, ioStreams genericiooptions.IOStreams) *cobra.Command { func NewCmdCreateSecret(f cmdutil.Factory, ioStreams genericiooptions.IOStreams) *cobra.Command {
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "secret", Use: "secret (docker-registry | generic | tls)",
Short: i18n.T("Create a secret using specified subcommand"), DisableFlagsInUseLine: true,
Long: i18n.T("Create a secret using specified subcommand."), Short: i18n.T("Create a secret using a specified subcommand"),
Run: cmdutil.DefaultSubCommandRun(ioStreams.ErrOut), Long: secretLong,
Run: cmdutil.DefaultSubCommandRun(ioStreams.ErrOut),
} }
cmd.AddCommand(NewCmdCreateSecretDockerRegistry(f, ioStreams)) cmd.AddCommand(NewCmdCreateSecretDockerRegistry(f, ioStreams))
cmd.AddCommand(NewCmdCreateSecretTLS(f, ioStreams)) cmd.AddCommand(NewCmdCreateSecretTLS(f, ioStreams))
@ -58,6 +59,15 @@ func NewCmdCreateSecret(f cmdutil.Factory, ioStreams genericiooptions.IOStreams)
var ( var (
secretLong = templates.LongDesc(i18n.T(` secretLong = templates.LongDesc(i18n.T(`
Create a secret with specified type.
A docker-registry type secret is for accessing a container registry.
A generic type secret indicate an Opaque secret type.
A tls type secret holds TLS certificate and its associated key.`))
secretForGenericLong = templates.LongDesc(i18n.T(`
Create a secret based on a file, directory, or specified literal value. Create a secret based on a file, directory, or specified literal value.
A single secret may package one or more key/value pairs. A single secret may package one or more key/value pairs.
@ -70,7 +80,7 @@ var (
packaged into the secret. Any directory entries except regular files are ignored (e.g. subdirectories, packaged into the secret. Any directory entries except regular files are ignored (e.g. subdirectories,
symlinks, devices, pipes, etc).`)) symlinks, devices, pipes, etc).`))
secretExample = templates.Examples(i18n.T(` secretForGenericExample = templates.Examples(i18n.T(`
# Create a new secret named my-secret with keys for each file in folder bar # Create a new secret named my-secret with keys for each file in folder bar
kubectl create secret generic my-secret --from-file=path/to/bar kubectl create secret generic my-secret --from-file=path/to/bar
@ -134,8 +144,8 @@ func NewCmdCreateSecretGeneric(f cmdutil.Factory, ioStreams genericiooptions.IOS
Use: "generic NAME [--type=string] [--from-file=[key=]source] [--from-literal=key1=value1] [--dry-run=server|client|none]", Use: "generic NAME [--type=string] [--from-file=[key=]source] [--from-literal=key1=value1] [--dry-run=server|client|none]",
DisableFlagsInUseLine: true, DisableFlagsInUseLine: true,
Short: i18n.T("Create a secret from a local file, directory, or literal value"), Short: i18n.T("Create a secret from a local file, directory, or literal value"),
Long: secretLong, Long: secretForGenericLong,
Example: secretExample, Example: secretForGenericExample,
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
cmdutil.CheckErr(o.Complete(f, cmd, args)) cmdutil.CheckErr(o.Complete(f, cmd, args))
cmdutil.CheckErr(o.Validate()) cmdutil.CheckErr(o.Validate())

View File

@ -126,6 +126,7 @@ func (templater *templater) templateFuncs(exposedFlags ...string) template.FuncM
"isRootCmd": templater.isRootCmd, "isRootCmd": templater.isRootCmd,
"optionsCmdFor": templater.optionsCmdFor, "optionsCmdFor": templater.optionsCmdFor,
"usageLine": templater.usageLine, "usageLine": templater.usageLine,
"reverseParentsNames": templater.reverseParentsNames,
"exposed": func(c *cobra.Command) *flag.FlagSet { "exposed": func(c *cobra.Command) *flag.FlagSet {
exposed := flag.NewFlagSet("exposed", flag.ContinueOnError) exposed := flag.NewFlagSet("exposed", flag.ContinueOnError)
if len(exposedFlags) > 0 { if len(exposedFlags) > 0 {
@ -172,6 +173,15 @@ func (t *templater) rootCmdName(c *cobra.Command) string {
return t.rootCmd(c).CommandPath() return t.rootCmd(c).CommandPath()
} }
func (t *templater) reverseParentsNames(c *cobra.Command) []string {
reverseParentsNames := []string{}
parents := t.parents(c)
for i := len(parents) - 1; i >= 0; i-- {
reverseParentsNames = append(reverseParentsNames, parents[i].Name())
}
return reverseParentsNames
}
func (t *templater) isRootCmd(c *cobra.Command) bool { func (t *templater) isRootCmd(c *cobra.Command) bool {
return t.rootCmd(c) == c return t.rootCmd(c) == c
} }

View File

@ -28,7 +28,8 @@ const (
`{{$visibleFlags := visibleFlags (flagsNotIntersected .LocalFlags .PersistentFlags)}}` + `{{$visibleFlags := visibleFlags (flagsNotIntersected .LocalFlags .PersistentFlags)}}` +
`{{$explicitlyExposedFlags := exposed .}}` + `{{$explicitlyExposedFlags := exposed .}}` +
`{{$optionsCmdFor := optionsCmdFor .}}` + `{{$optionsCmdFor := optionsCmdFor .}}` +
`{{$usageLine := usageLine .}}` `{{$usageLine := usageLine .}}` +
`{{$reverseParentsNames := reverseParentsNames .}}`
// SectionAliases is the help template section that displays command aliases. // SectionAliases is the help template section that displays command aliases.
SectionAliases = `{{if gt .Aliases 0}}Aliases: SectionAliases = `{{if gt .Aliases 0}}Aliases:
@ -61,7 +62,7 @@ const (
{{end}}` {{end}}`
// SectionTipsHelp is the help template section that displays the '--help' hint. // SectionTipsHelp is the help template section that displays the '--help' hint.
SectionTipsHelp = `{{if .HasSubCommands}}Use "{{$rootCmd}} <command> --help" for more information about a given command. SectionTipsHelp = `{{if .HasSubCommands}}Use "{{range $reverseParentsNames}}{{.}} {{end}}<command> --help" for more information about a given command.
{{end}}` {{end}}`
// SectionTipsGlobalOptions is the help template section that displays the 'options' hint for displaying global flags. // SectionTipsGlobalOptions is the help template section that displays the 'options' hint for displaying global flags.

View File

@ -47,6 +47,24 @@ run_kubectl_help_tests() {
kube::test::if_has_string "$(LANG=zh_CN.UTF-8 kubectl uncordon --help)" "标记节点为可调度。" kube::test::if_has_string "$(LANG=zh_CN.UTF-8 kubectl uncordon --help)" "标记节点为可调度。"
kube::test::if_has_string "$(LANG=zh_TW.UTF-8 kubectl uncordon --help)" "Mark node as schedulable." kube::test::if_has_string "$(LANG=zh_TW.UTF-8 kubectl uncordon --help)" "Mark node as schedulable."
# This part of test is to check those commands that have subcommands output the correct usage prompts.
# If a new command with subcommands is added, it is best to be added here.
# If some refactoring causes the command to become without subcommands, it needs to be removed here to ensure that the test passes.
kube::test::if_has_string "$(kubectl --help)" "Use \"kubectl <command> --help\" for more information about a given command."
kube::test::if_has_string "$(kubectl apply --help)" "Use \"kubectl apply <command> --help\" for more information about a given command."
kube::test::if_has_string "$(kubectl auth --help)" "Use \"kubectl auth <command> --help\" for more information about a given command."
kube::test::if_has_string "$(kubectl certificate --help)" "Use \"kubectl certificate <command> --help\" for more information about a given command."
kube::test::if_has_string "$(kubectl cluster-info --help)" "Use \"kubectl cluster-info <command> --help\" for more information about a given command."
kube::test::if_has_string "$(kubectl config --help)" "Use \"kubectl config <command> --help\" for more information about a given command."
kube::test::if_has_string "$(kubectl create --help)" "Use \"kubectl create <command> --help\" for more information about a given command."
kube::test::if_has_string "$(kubectl create secret --help)" "Use \"kubectl create secret <command> --help\" for more information about a given command."
kube::test::if_has_string "$(kubectl create service --help)" "Use \"kubectl create service <command> --help\" for more information about a given command."
kube::test::if_has_string "$(kubectl plugin --help)" "Use \"kubectl plugin <command> --help\" for more information about a given command."
kube::test::if_has_string "$(kubectl rollout --help)" "Use \"kubectl rollout <command> --help\" for more information about a given command."
kube::test::if_has_string "$(kubectl set --help)" "Use \"kubectl set <command> --help\" for more information about a given command."
kube::test::if_has_string "$(kubectl top --help)" "Use \"kubectl top <command> --help\" for more information about a given command."
set +o nounset set +o nounset
set +o errexit set +o errexit
} }