mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Update cobra vendor
- adds support for usage strings on flag errors - adds support for arg validation Signed-off-by: Daniel Nephin <dnephin@docker.com>
This commit is contained in:
parent
667dcb0e8e
commit
3d624ed5d6
4 changed files with 193 additions and 26 deletions
|
@ -135,7 +135,7 @@ clone git google.golang.org/cloud dae7e3d993bc3812a2185af60552bb6b847e52a0 https
|
||||||
clone git github.com/docker/containerd 57b7c3da915ebe943bd304c00890959b191e5264
|
clone git github.com/docker/containerd 57b7c3da915ebe943bd304c00890959b191e5264
|
||||||
|
|
||||||
# cli
|
# cli
|
||||||
clone git github.com/spf13/cobra 0f866a6211e33cde2091d9290c08f6afd6c9ebbc
|
clone git github.com/spf13/cobra acf60156558542e78c6f3695f74b0f871614ff55 https://github.com/dnephin/cobra.git
|
||||||
clone git github.com/spf13/pflag cb88ea77998c3f024757528e3305022ab50b43be
|
clone git github.com/spf13/pflag cb88ea77998c3f024757528e3305022ab50b43be
|
||||||
clone git github.com/inconshreveable/mousetrap 76626ae9c91c4f2a10f34cad8ce83ea42c93bb75
|
clone git github.com/inconshreveable/mousetrap 76626ae9c91c4f2a10f34cad8ce83ea42c93bb75
|
||||||
|
|
||||||
|
|
36
vendor/src/github.com/spf13/cobra/README.md
vendored
36
vendor/src/github.com/spf13/cobra/README.md
vendored
|
@ -406,6 +406,42 @@ A flag can also be assigned locally which will only apply to that specific comma
|
||||||
RootCmd.Flags().StringVarP(&Source, "source", "s", "", "Source directory to read from")
|
RootCmd.Flags().StringVarP(&Source, "source", "s", "", "Source directory to read from")
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Positional Arguments
|
||||||
|
|
||||||
|
Validation of positional arguments can be specified using the `Args` field, which accepts
|
||||||
|
one of the following values:
|
||||||
|
|
||||||
|
- `NoArgs` - the command will report an error if there are any positional args.
|
||||||
|
- `ArbitraryArgs` - the command will accept any args.
|
||||||
|
- `OnlyValidArgs` - the command will report an error if there are any positiona
|
||||||
|
args that are not in the `ValidArgs` list.
|
||||||
|
- `MinimumNArgs(int)` - the command will report an error if there are not at
|
||||||
|
least N positional args.
|
||||||
|
- `MaximumNArgs(int)` - the command will report an error if there are more than
|
||||||
|
N positional args.
|
||||||
|
- `ExactArgs(int)` - the command will report an error if there are not
|
||||||
|
exactly N positional args.
|
||||||
|
- `RangeArgs(min, max)` - the command will report an error if the number of args
|
||||||
|
is not between the minimum and maximum number of expected args.
|
||||||
|
|
||||||
|
By default, `Args` uses the following legacy behaviour:
|
||||||
|
- root commands with no subcommands can take arbitrary arguments
|
||||||
|
- root commands with subcommands will do subcommand validity checking
|
||||||
|
- subcommands will always accept arbitrary arguments and do no subsubcommand validity checking
|
||||||
|
|
||||||
|
|
||||||
|
```go
|
||||||
|
var HugoCmd = &cobra.Command{
|
||||||
|
Use: "hugo",
|
||||||
|
Short: "Hugo is a very fast static site generator",
|
||||||
|
ValidArgs: []string{"one", "two"}
|
||||||
|
Args: cobra.OnlyValidArgs
|
||||||
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
|
// args will only have the values one, two
|
||||||
|
// or the cmd.Execute() will fail.
|
||||||
|
},
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
## Example
|
## Example
|
||||||
|
|
||||||
|
|
98
vendor/src/github.com/spf13/cobra/args.go
vendored
Normal file
98
vendor/src/github.com/spf13/cobra/args.go
vendored
Normal file
|
@ -0,0 +1,98 @@
|
||||||
|
package cobra
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PositionalArgs func(cmd *Command, args []string) error
|
||||||
|
|
||||||
|
// Legacy arg validation has the following behaviour:
|
||||||
|
// - root commands with no subcommands can take arbitrary arguments
|
||||||
|
// - root commands with subcommands will do subcommand validity checking
|
||||||
|
// - subcommands will always accept arbitrary arguments
|
||||||
|
func legacyArgs(cmd *Command, args []string) error {
|
||||||
|
// no subcommand, always take args
|
||||||
|
if !cmd.HasSubCommands() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// root command with subcommands, do subcommand checking
|
||||||
|
if !cmd.HasParent() && len(args) > 0 {
|
||||||
|
return fmt.Errorf("unknown command %q for %q%s", args[0], cmd.CommandPath(), cmd.findSuggestions(args[0]))
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// NoArgs returns an error if any args are included
|
||||||
|
func NoArgs(cmd *Command, args []string) error {
|
||||||
|
if len(args) > 0 {
|
||||||
|
return fmt.Errorf("unknown command %q for %q", args[0], cmd.CommandPath())
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// OnlyValidArgs returns an error if any args are not in the list of ValidArgs
|
||||||
|
func OnlyValidArgs(cmd *Command, args []string) error {
|
||||||
|
if len(cmd.ValidArgs) > 0 {
|
||||||
|
for _, v := range args {
|
||||||
|
if !stringInSlice(v, cmd.ValidArgs) {
|
||||||
|
return fmt.Errorf("invalid argument %q for %q%s", v, cmd.CommandPath(), cmd.findSuggestions(args[0]))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func stringInSlice(a string, list []string) bool {
|
||||||
|
for _, b := range list {
|
||||||
|
if b == a {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// ArbitraryArgs never returns an error
|
||||||
|
func ArbitraryArgs(cmd *Command, args []string) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// MinimumNArgs returns an error if there is not at least N args
|
||||||
|
func MinimumNArgs(n int) PositionalArgs {
|
||||||
|
return func(cmd *Command, args []string) error {
|
||||||
|
if len(args) < n {
|
||||||
|
return fmt.Errorf("requires at least %d arg(s), only received %d", n, len(args))
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MaximumNArgs returns an error if there are more than N args
|
||||||
|
func MaximumNArgs(n int) PositionalArgs {
|
||||||
|
return func(cmd *Command, args []string) error {
|
||||||
|
if len(args) > n {
|
||||||
|
return fmt.Errorf("accepts at most %d arg(s), received %d", n, len(args))
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ExactArgs returns an error if there are not exactly n args
|
||||||
|
func ExactArgs(n int) PositionalArgs {
|
||||||
|
return func(cmd *Command, args []string) error {
|
||||||
|
if len(args) != n {
|
||||||
|
return fmt.Errorf("accepts %d arg(s), received %d", n, len(args))
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// RangeArgs returns an error if the number of args is not within the expected range
|
||||||
|
func RangeArgs(min int, max int) PositionalArgs {
|
||||||
|
return func(cmd *Command, args []string) error {
|
||||||
|
if len(args) < min || len(args) > max {
|
||||||
|
return fmt.Errorf("accepts between %d and %d arg(s), received %d", min, max, len(args))
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
83
vendor/src/github.com/spf13/cobra/command.go
vendored
83
vendor/src/github.com/spf13/cobra/command.go
vendored
|
@ -50,6 +50,8 @@ type Command struct {
|
||||||
// List of aliases for ValidArgs. These are not suggested to the user in the bash
|
// List of aliases for ValidArgs. These are not suggested to the user in the bash
|
||||||
// completion, but accepted if entered manually.
|
// completion, but accepted if entered manually.
|
||||||
ArgAliases []string
|
ArgAliases []string
|
||||||
|
// Expected arguments
|
||||||
|
Args PositionalArgs
|
||||||
// Custom functions used by the bash autocompletion generator
|
// Custom functions used by the bash autocompletion generator
|
||||||
BashCompletionFunction string
|
BashCompletionFunction string
|
||||||
// Is this command deprecated and should print this string when used?
|
// Is this command deprecated and should print this string when used?
|
||||||
|
@ -110,6 +112,7 @@ type Command struct {
|
||||||
output *io.Writer // nil means stderr; use Out() method instead
|
output *io.Writer // nil means stderr; use Out() method instead
|
||||||
usageFunc func(*Command) error // Usage can be defined by application
|
usageFunc func(*Command) error // Usage can be defined by application
|
||||||
usageTemplate string // Can be defined by Application
|
usageTemplate string // Can be defined by Application
|
||||||
|
flagErrorFunc func(*Command, error) error
|
||||||
helpTemplate string // Can be defined by Application
|
helpTemplate string // Can be defined by Application
|
||||||
helpFunc func(*Command, []string) // Help can be defined by application
|
helpFunc func(*Command, []string) // Help can be defined by application
|
||||||
helpCommand *Command // The help command
|
helpCommand *Command // The help command
|
||||||
|
@ -163,6 +166,12 @@ func (c *Command) SetUsageTemplate(s string) {
|
||||||
c.usageTemplate = s
|
c.usageTemplate = s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetFlagErrorFunc sets a function to generate an error when flag parsing
|
||||||
|
// fails
|
||||||
|
func (c *Command) SetFlagErrorFunc(f func(*Command, error) error) {
|
||||||
|
c.flagErrorFunc = f
|
||||||
|
}
|
||||||
|
|
||||||
// Can be defined by Application
|
// Can be defined by Application
|
||||||
func (c *Command) SetHelpFunc(f func(*Command, []string)) {
|
func (c *Command) SetHelpFunc(f func(*Command, []string)) {
|
||||||
c.helpFunc = f
|
c.helpFunc = f
|
||||||
|
@ -224,6 +233,22 @@ func (c *Command) HelpFunc() func(*Command, []string) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FlagErrorFunc returns either the function set by SetFlagErrorFunc for this
|
||||||
|
// command or a parent, or it returns a function which returns the original
|
||||||
|
// error.
|
||||||
|
func (c *Command) FlagErrorFunc() (f func(*Command, error) error) {
|
||||||
|
if c.flagErrorFunc != nil {
|
||||||
|
return c.flagErrorFunc
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.HasParent() {
|
||||||
|
return c.parent.FlagErrorFunc()
|
||||||
|
}
|
||||||
|
return func(c *Command, err error) error {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var minUsagePadding = 25
|
var minUsagePadding = 25
|
||||||
|
|
||||||
func (c *Command) UsagePadding() int {
|
func (c *Command) UsagePadding() int {
|
||||||
|
@ -422,33 +447,29 @@ func (c *Command) Find(args []string) (*Command, []string, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
commandFound, a := innerfind(c, args)
|
commandFound, a := innerfind(c, args)
|
||||||
argsWOflags := stripFlags(a, commandFound)
|
if commandFound.Args == nil {
|
||||||
|
return commandFound, a, legacyArgs(commandFound, stripFlags(a, commandFound))
|
||||||
// no subcommand, always take args
|
|
||||||
if !commandFound.HasSubCommands() {
|
|
||||||
return commandFound, a, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// root command with subcommands, do subcommand checking
|
|
||||||
if commandFound == c && len(argsWOflags) > 0 {
|
|
||||||
suggestionsString := ""
|
|
||||||
if !c.DisableSuggestions {
|
|
||||||
if c.SuggestionsMinimumDistance <= 0 {
|
|
||||||
c.SuggestionsMinimumDistance = 2
|
|
||||||
}
|
|
||||||
if suggestions := c.SuggestionsFor(argsWOflags[0]); len(suggestions) > 0 {
|
|
||||||
suggestionsString += "\n\nDid you mean this?\n"
|
|
||||||
for _, s := range suggestions {
|
|
||||||
suggestionsString += fmt.Sprintf("\t%v\n", s)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return commandFound, a, fmt.Errorf("unknown command %q for %q%s", argsWOflags[0], commandFound.CommandPath(), suggestionsString)
|
|
||||||
}
|
|
||||||
|
|
||||||
return commandFound, a, nil
|
return commandFound, a, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Command) findSuggestions(arg string) string {
|
||||||
|
if c.DisableSuggestions {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
if c.SuggestionsMinimumDistance <= 0 {
|
||||||
|
c.SuggestionsMinimumDistance = 2
|
||||||
|
}
|
||||||
|
suggestionsString := ""
|
||||||
|
if suggestions := c.SuggestionsFor(arg); len(suggestions) > 0 {
|
||||||
|
suggestionsString += "\n\nDid you mean this?\n"
|
||||||
|
for _, s := range suggestions {
|
||||||
|
suggestionsString += fmt.Sprintf("\t%v\n", s)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return suggestionsString
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Command) SuggestionsFor(typedName string) []string {
|
func (c *Command) SuggestionsFor(typedName string) []string {
|
||||||
suggestions := []string{}
|
suggestions := []string{}
|
||||||
for _, cmd := range c.commands {
|
for _, cmd := range c.commands {
|
||||||
|
@ -520,7 +541,7 @@ func (c *Command) execute(a []string) (err error) {
|
||||||
|
|
||||||
err = c.ParseFlags(a)
|
err = c.ParseFlags(a)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return c.FlagErrorFunc()(c, err)
|
||||||
}
|
}
|
||||||
// If help is called, regardless of other flags, return we want help
|
// If help is called, regardless of other flags, return we want help
|
||||||
// Also say we need help if the command isn't runnable.
|
// Also say we need help if the command isn't runnable.
|
||||||
|
@ -535,6 +556,10 @@ func (c *Command) execute(a []string) (err error) {
|
||||||
return flag.ErrHelp
|
return flag.ErrHelp
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := c.ValidateArgs(a); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
c.preRun()
|
c.preRun()
|
||||||
argWoFlags := c.Flags().Args()
|
argWoFlags := c.Flags().Args()
|
||||||
|
|
||||||
|
@ -673,7 +698,15 @@ func (c *Command) ExecuteC() (cmd *Command, err error) {
|
||||||
return cmd, nil
|
return cmd, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Command) ValidateArgs(args []string) error {
|
||||||
|
if c.Args == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return c.Args(c, stripFlags(args, c))
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Command) initHelpFlag() {
|
func (c *Command) initHelpFlag() {
|
||||||
|
c.mergePersistentFlags()
|
||||||
if c.Flags().Lookup("help") == nil {
|
if c.Flags().Lookup("help") == nil {
|
||||||
c.Flags().BoolP("help", "h", false, "help for "+c.Name())
|
c.Flags().BoolP("help", "h", false, "help for "+c.Name())
|
||||||
}
|
}
|
||||||
|
@ -747,7 +780,7 @@ func (c *Command) AddCommand(cmds ...*Command) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddCommand removes one or more commands from a parent command.
|
// RemoveCommand removes one or more commands from a parent command.
|
||||||
func (c *Command) RemoveCommand(cmds ...*Command) {
|
func (c *Command) RemoveCommand(cmds ...*Command) {
|
||||||
commands := []*Command{}
|
commands := []*Command{}
|
||||||
main:
|
main:
|
||||||
|
|
Loading…
Reference in a new issue