mirror of
https://github.com/spf13/cobra
synced 2024-11-25 07:07:15 +00:00
Added ValidArgs as object to prevent memory wasting using new Command to subsubcommands
This commit is contained in:
parent
2da4a54c5c
commit
b415b76121
7 changed files with 75 additions and 23 deletions
9
args.go
9
args.go
|
@ -35,7 +35,14 @@ func NoArgs(cmd *Command, args []string) error {
|
||||||
func OnlyValidArgs(cmd *Command, args []string) error {
|
func OnlyValidArgs(cmd *Command, args []string) error {
|
||||||
if len(cmd.ValidArgs) > 0 {
|
if len(cmd.ValidArgs) > 0 {
|
||||||
for _, v := range args {
|
for _, v := range args {
|
||||||
if !stringInSlice(v, cmd.ValidArgs) {
|
if !func() bool {
|
||||||
|
for _, cmdargs := range cmd.ValidArgs {
|
||||||
|
if v == cmdargs.Name {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}() {
|
||||||
return fmt.Errorf("invalid argument %q for %q%s", v, cmd.CommandPath(), cmd.findSuggestions(args[0]))
|
return fmt.Errorf("invalid argument %q for %q%s", v, cmd.CommandPath(), cmd.findSuggestions(args[0]))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
22
args_test.go
22
args_test.go
|
@ -34,10 +34,13 @@ func TestNoArgsWithArgs(t *testing.T) {
|
||||||
|
|
||||||
func TestOnlyValidArgs(t *testing.T) {
|
func TestOnlyValidArgs(t *testing.T) {
|
||||||
c := &Command{
|
c := &Command{
|
||||||
Use: "c",
|
Use: "c",
|
||||||
Args: OnlyValidArgs,
|
Args: OnlyValidArgs,
|
||||||
ValidArgs: []string{"one", "two"},
|
ValidArgs: []ValidArgs{
|
||||||
Run: emptyRun,
|
{"one", "one thing"},
|
||||||
|
{"two", "two things"},
|
||||||
|
},
|
||||||
|
Run: emptyRun,
|
||||||
}
|
}
|
||||||
|
|
||||||
output, err := executeCommand(c, "one", "two")
|
output, err := executeCommand(c, "one", "two")
|
||||||
|
@ -51,10 +54,13 @@ func TestOnlyValidArgs(t *testing.T) {
|
||||||
|
|
||||||
func TestOnlyValidArgsWithInvalidArgs(t *testing.T) {
|
func TestOnlyValidArgsWithInvalidArgs(t *testing.T) {
|
||||||
c := &Command{
|
c := &Command{
|
||||||
Use: "c",
|
Use: "c",
|
||||||
Args: OnlyValidArgs,
|
Args: OnlyValidArgs,
|
||||||
ValidArgs: []string{"one", "two"},
|
ValidArgs: []ValidArgs{
|
||||||
Run: emptyRun,
|
{"one", "one thing"},
|
||||||
|
{"two", "two things"},
|
||||||
|
},
|
||||||
|
Run: emptyRun,
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := executeCommand(c, "three")
|
_, err := executeCommand(c, "three")
|
||||||
|
|
|
@ -428,9 +428,11 @@ func writeRequiredFlag(buf *bytes.Buffer, cmd *Command) {
|
||||||
|
|
||||||
func writeRequiredNouns(buf *bytes.Buffer, cmd *Command) {
|
func writeRequiredNouns(buf *bytes.Buffer, cmd *Command) {
|
||||||
buf.WriteString(" must_have_one_noun=()\n")
|
buf.WriteString(" must_have_one_noun=()\n")
|
||||||
sort.Sort(sort.StringSlice(cmd.ValidArgs))
|
sort.Slice(cmd.ValidArgs, func(i, j int) bool {
|
||||||
|
return cmd.ValidArgs[i].Name < cmd.ValidArgs[j].Name
|
||||||
|
})
|
||||||
for _, value := range cmd.ValidArgs {
|
for _, value := range cmd.ValidArgs {
|
||||||
buf.WriteString(fmt.Sprintf(" must_have_one_noun+=(%q)\n", value))
|
buf.WriteString(fmt.Sprintf(" must_have_one_noun+=(%q)\n", value.Name))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -80,7 +80,12 @@ The `BashCompletionFunction` option is really only valid/useful on the root comm
|
||||||
In the above example "pod" was assumed to already be typed. But if you want `kubectl get [tab][tab]` to show a list of valid "nouns" you have to set them. Simplified code from `kubectl get` looks like:
|
In the above example "pod" was assumed to already be typed. But if you want `kubectl get [tab][tab]` to show a list of valid "nouns" you have to set them. Simplified code from `kubectl get` looks like:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
validArgs []string = { "pod", "node", "service", "replicationcontroller" }
|
validArgs []ValidArgs = {
|
||||||
|
{"pod", ""},
|
||||||
|
{"node", ""},
|
||||||
|
{"service", ""},
|
||||||
|
{"replicationcontroller", ""},
|
||||||
|
}
|
||||||
|
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "get [(-o|--output=)json|yaml|template|...] (RESOURCE [NAME] | RESOURCE/NAME ...)",
|
Use: "get [(-o|--output=)json|yaml|template|...] (RESOURCE [NAME] | RESOURCE/NAME ...)",
|
||||||
|
|
|
@ -48,9 +48,14 @@ const bashCompletionFunc = `__custom_func() {
|
||||||
|
|
||||||
func TestBashCompletions(t *testing.T) {
|
func TestBashCompletions(t *testing.T) {
|
||||||
rootCmd := &Command{
|
rootCmd := &Command{
|
||||||
Use: "root",
|
Use: "root",
|
||||||
ArgAliases: []string{"pods", "nodes", "services", "replicationcontrollers", "po", "no", "svc", "rc"},
|
ArgAliases: []string{"pods", "nodes", "services", "replicationcontrollers", "po", "no", "svc", "rc"},
|
||||||
ValidArgs: []string{"pod", "node", "service", "replicationcontroller"},
|
ValidArgs: []ValidArgs{
|
||||||
|
{"pod", ""},
|
||||||
|
{"node", ""},
|
||||||
|
{"service", ""},
|
||||||
|
{"replicationcontroller", ""},
|
||||||
|
},
|
||||||
BashCompletionFunction: bashCompletionFunc,
|
BashCompletionFunction: bashCompletionFunc,
|
||||||
Run: emptyRun,
|
Run: emptyRun,
|
||||||
}
|
}
|
||||||
|
@ -111,10 +116,15 @@ func TestBashCompletions(t *testing.T) {
|
||||||
Use: "times [# times] [string to echo]",
|
Use: "times [# times] [string to echo]",
|
||||||
SuggestFor: []string{"counts"},
|
SuggestFor: []string{"counts"},
|
||||||
Args: OnlyValidArgs,
|
Args: OnlyValidArgs,
|
||||||
ValidArgs: []string{"one", "two", "three", "four"},
|
ValidArgs: []ValidArgs{
|
||||||
Short: "Echo anything to the screen more times",
|
{"one", ""},
|
||||||
Long: "a slightly useless command for testing.",
|
{"two", ""},
|
||||||
Run: emptyRun,
|
{"three", ""},
|
||||||
|
{"four", ""},
|
||||||
|
},
|
||||||
|
Short: "Echo anything to the screen more times",
|
||||||
|
Long: "a slightly useless command for testing.",
|
||||||
|
Run: emptyRun,
|
||||||
}
|
}
|
||||||
|
|
||||||
echoCmd.AddCommand(timesCmd)
|
echoCmd.AddCommand(timesCmd)
|
||||||
|
|
2
cobra.go
2
cobra.go
|
@ -1,4 +1,4 @@
|
||||||
// Copyright © 2013 Steve Francia <spf@spf13.com>.
|
// Copyright © 2013 Steve Francia <spf@spf13.com>.
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
// you may not use this file except in compliance with the License.
|
||||||
|
|
28
command.go
28
command.go
|
@ -1,4 +1,3 @@
|
||||||
// Copyright © 2013 Steve Francia <spf@spf13.com>.
|
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
// you may not use this file except in compliance with the License.
|
||||||
|
@ -27,6 +26,17 @@ import (
|
||||||
flag "github.com/spf13/pflag"
|
flag "github.com/spf13/pflag"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// This structure has been created to replace
|
||||||
|
// ValidArgs []string in Command object to prevent
|
||||||
|
// wasting memory when new command objects are added simply
|
||||||
|
// to add new subsubcommands.
|
||||||
|
type ValidArgs struct {
|
||||||
|
// Name of subcommand
|
||||||
|
Name string
|
||||||
|
// Short description
|
||||||
|
Short string
|
||||||
|
}
|
||||||
|
|
||||||
// Command is just that, a command for your application.
|
// Command is just that, a command for your application.
|
||||||
// E.g. 'go run ...' - 'run' is the command. Cobra requires
|
// E.g. 'go run ...' - 'run' is the command. Cobra requires
|
||||||
// you to define the usage and description as part of your command
|
// you to define the usage and description as part of your command
|
||||||
|
@ -52,7 +62,9 @@ type Command struct {
|
||||||
Example string
|
Example string
|
||||||
|
|
||||||
// ValidArgs is list of all valid non-flag arguments that are accepted in bash completions
|
// ValidArgs is list of all valid non-flag arguments that are accepted in bash completions
|
||||||
ValidArgs []string
|
// We can use ValidArgs instead of adding new commands to list. This is to prevent
|
||||||
|
// wasting memory with new Command objects.
|
||||||
|
ValidArgs []ValidArgs
|
||||||
|
|
||||||
// Expected arguments
|
// Expected arguments
|
||||||
Args PositionalArgs
|
Args PositionalArgs
|
||||||
|
@ -372,7 +384,10 @@ func (c *Command) UsageTemplate() string {
|
||||||
{{.CommandPath}} [command]{{end}}{{if gt (len .Aliases) 0}}
|
{{.CommandPath}} [command]{{end}}{{if gt (len .Aliases) 0}}
|
||||||
|
|
||||||
Aliases:
|
Aliases:
|
||||||
{{.NameAndAliases}}{{end}}{{if .HasExample}}
|
{{.NameAndAliases}}{{end}}{{if .HasValidArgs}}
|
||||||
|
|
||||||
|
Valid Args:{{range .ValidArgs}}
|
||||||
|
{{.Name}} {{.Short}}{{end}}{{end}}{{if .HasExample}}
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
{{.Example}}{{end}}{{if .HasAvailableSubCommands}}
|
{{.Example}}{{end}}{{if .HasAvailableSubCommands}}
|
||||||
|
@ -393,6 +408,13 @@ Use "{{.CommandPath}} [command] --help" for more information about a command.{{e
|
||||||
`
|
`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Command) HasValidArgs() bool {
|
||||||
|
if len(c.ValidArgs) > 0 {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
// HelpTemplate return help template for the command.
|
// HelpTemplate return help template for the command.
|
||||||
func (c *Command) HelpTemplate() string {
|
func (c *Command) HelpTemplate() string {
|
||||||
if c.helpTemplate != "" {
|
if c.helpTemplate != "" {
|
||||||
|
|
Loading…
Reference in a new issue