Add support for setting a function to handle flag parsing errors.
The default pflag error is to only print the bad flag. This enables an application to include a usage message or other details about the error. Signed-off-by: Daniel Nephin <dnephin@gmail.com>
This commit is contained in:
parent
9c28e4bbd7
commit
67feb8173c
35
command.go
35
command.go
@ -109,10 +109,11 @@ type Command struct {
|
|||||||
|
|
||||||
flagErrorBuf *bytes.Buffer
|
flagErrorBuf *bytes.Buffer
|
||||||
|
|
||||||
args []string // actual args parsed from flags
|
args []string // actual args parsed from flags
|
||||||
output *io.Writer // out writer if set in SetOutput(w)
|
output *io.Writer // out writer if set in SetOutput(w)
|
||||||
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
|
||||||
@ -150,7 +151,13 @@ func (c *Command) SetUsageTemplate(s string) {
|
|||||||
c.usageTemplate = s
|
c.usageTemplate = s
|
||||||
}
|
}
|
||||||
|
|
||||||
// Can be defined by Application.
|
// 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
|
||||||
func (c *Command) SetHelpFunc(f func(*Command, []string)) {
|
func (c *Command) SetHelpFunc(f func(*Command, []string)) {
|
||||||
c.helpFunc = f
|
c.helpFunc = f
|
||||||
}
|
}
|
||||||
@ -257,6 +264,22 @@ func (c *Command) UsageString() string {
|
|||||||
return bb.String()
|
return bb.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 {
|
||||||
@ -553,7 +576,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.
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
package cobra
|
package cobra
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
@ -174,3 +176,27 @@ func TestEnableCommandSortingIsDisabled(t *testing.T) {
|
|||||||
|
|
||||||
EnableCommandSorting = true
|
EnableCommandSorting = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestFlagErrorFunc(t *testing.T) {
|
||||||
|
|
||||||
|
cmd := &Command{
|
||||||
|
Use: "print",
|
||||||
|
RunE: func(cmd *Command, args []string) error {
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
expectedFmt := "This is expected: %s"
|
||||||
|
|
||||||
|
cmd.SetFlagErrorFunc(func(c *Command, err error) error {
|
||||||
|
return fmt.Errorf(expectedFmt, err)
|
||||||
|
})
|
||||||
|
cmd.SetArgs([]string{"--bogus-flag"})
|
||||||
|
cmd.SetOutput(new(bytes.Buffer))
|
||||||
|
|
||||||
|
err := cmd.Execute()
|
||||||
|
|
||||||
|
expected := fmt.Sprintf(expectedFmt, "unknown flag: --bogus-flag")
|
||||||
|
if err.Error() != expected {
|
||||||
|
t.Errorf("expected %v, got %v", expected, err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -101,4 +101,3 @@ linkHandler := func(name string) string {
|
|||||||
return "/commands/" + strings.ToLower(base) + "/"
|
return "/commands/" + strings.ToLower(base) + "/"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user