Added ValidArgs as object to prevent memory wasting using new Command to subsubcommands

This commit is contained in:
themester 2017-11-11 00:01:00 +01:00
parent 2da4a54c5c
commit b415b76121
7 changed files with 75 additions and 23 deletions

View file

@ -35,7 +35,14 @@ func NoArgs(cmd *Command, args []string) error {
func OnlyValidArgs(cmd *Command, args []string) error {
if len(cmd.ValidArgs) > 0 {
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]))
}
}

View file

@ -36,7 +36,10 @@ func TestOnlyValidArgs(t *testing.T) {
c := &Command{
Use: "c",
Args: OnlyValidArgs,
ValidArgs: []string{"one", "two"},
ValidArgs: []ValidArgs{
{"one", "one thing"},
{"two", "two things"},
},
Run: emptyRun,
}
@ -53,7 +56,10 @@ func TestOnlyValidArgsWithInvalidArgs(t *testing.T) {
c := &Command{
Use: "c",
Args: OnlyValidArgs,
ValidArgs: []string{"one", "two"},
ValidArgs: []ValidArgs{
{"one", "one thing"},
{"two", "two things"},
},
Run: emptyRun,
}

View file

@ -428,9 +428,11 @@ func writeRequiredFlag(buf *bytes.Buffer, cmd *Command) {
func writeRequiredNouns(buf *bytes.Buffer, cmd *Command) {
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 {
buf.WriteString(fmt.Sprintf(" must_have_one_noun+=(%q)\n", value))
buf.WriteString(fmt.Sprintf(" must_have_one_noun+=(%q)\n", value.Name))
}
}

View file

@ -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:
```go
validArgs []string = { "pod", "node", "service", "replicationcontroller" }
validArgs []ValidArgs = {
{"pod", ""},
{"node", ""},
{"service", ""},
{"replicationcontroller", ""},
}
cmd := &cobra.Command{
Use: "get [(-o|--output=)json|yaml|template|...] (RESOURCE [NAME] | RESOURCE/NAME ...)",

View file

@ -50,7 +50,12 @@ func TestBashCompletions(t *testing.T) {
rootCmd := &Command{
Use: "root",
ArgAliases: []string{"pods", "nodes", "services", "replicationcontrollers", "po", "no", "svc", "rc"},
ValidArgs: []string{"pod", "node", "service", "replicationcontroller"},
ValidArgs: []ValidArgs{
{"pod", ""},
{"node", ""},
{"service", ""},
{"replicationcontroller", ""},
},
BashCompletionFunction: bashCompletionFunc,
Run: emptyRun,
}
@ -111,7 +116,12 @@ func TestBashCompletions(t *testing.T) {
Use: "times [# times] [string to echo]",
SuggestFor: []string{"counts"},
Args: OnlyValidArgs,
ValidArgs: []string{"one", "two", "three", "four"},
ValidArgs: []ValidArgs{
{"one", ""},
{"two", ""},
{"three", ""},
{"four", ""},
},
Short: "Echo anything to the screen more times",
Long: "a slightly useless command for testing.",
Run: emptyRun,

View file

@ -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");
// you may not use this file except in compliance with the License.

View file

@ -1,4 +1,3 @@
// Copyright © 2013 Steve Francia <spf@spf13.com>.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@ -27,6 +26,17 @@ import (
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.
// E.g. 'go run ...' - 'run' is the command. Cobra requires
// you to define the usage and description as part of your command
@ -52,7 +62,9 @@ type Command struct {
Example string
// 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
Args PositionalArgs
@ -372,7 +384,10 @@ func (c *Command) UsageTemplate() string {
{{.CommandPath}} [command]{{end}}{{if gt (len .Aliases) 0}}
Aliases:
{{.NameAndAliases}}{{end}}{{if .HasExample}}
{{.NameAndAliases}}{{end}}{{if .HasValidArgs}}
Valid Args:{{range .ValidArgs}}
{{.Name}} {{.Short}}{{end}}{{end}}{{if .HasExample}}
Examples:
{{.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.
func (c *Command) HelpTemplate() string {
if c.helpTemplate != "" {