Add support for ignoring parse errors (#662)

This commit is contained in:
Rajat Jindal 2018-03-31 05:36:20 -07:00 committed by Eric Paris
parent a1f051bc3e
commit 4dab30cb33
2 changed files with 115 additions and 0 deletions

View File

@ -27,6 +27,9 @@ import (
flag "github.com/spf13/pflag" flag "github.com/spf13/pflag"
) )
// FParseErrWhitelist configures Flag parse errors to be ignored
type FParseErrWhitelist flag.ParseErrorsWhitelist
// 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
@ -137,6 +140,9 @@ type Command struct {
// TraverseChildren parses flags on all parents before executing child command. // TraverseChildren parses flags on all parents before executing child command.
TraverseChildren bool TraverseChildren bool
//FParseErrWhitelist flag parse errors to be ignored
FParseErrWhitelist FParseErrWhitelist
// commands is the list of commands supported by this program. // commands is the list of commands supported by this program.
commands []*Command commands []*Command
// parent is a parent command for this command. // parent is a parent command for this command.
@ -1463,6 +1469,10 @@ func (c *Command) ParseFlags(args []string) error {
} }
beforeErrorBufLen := c.flagErrorBuf.Len() beforeErrorBufLen := c.flagErrorBuf.Len()
c.mergePersistentFlags() c.mergePersistentFlags()
//do it here after merging all flags and just before parse
c.Flags().ParseErrorsWhitelist = flag.ParseErrorsWhitelist(c.FParseErrWhitelist)
err := c.Flags().Parse(args) err := c.Flags().Parse(args)
// Print warnings if they occurred (e.g. deprecated flag messages). // Print warnings if they occurred (e.g. deprecated flag messages).
if c.flagErrorBuf.Len()-beforeErrorBufLen > 0 && err == nil { if c.flagErrorBuf.Len()-beforeErrorBufLen > 0 && err == nil {

View File

@ -1626,3 +1626,108 @@ func TestCalledAs(t *testing.T) {
t.Run(name, tc.test) t.Run(name, tc.test)
} }
} }
func TestFParseErrWhitelistBackwardCompatibility(t *testing.T) {
c := &Command{Use: "c", Run: emptyRun}
c.Flags().BoolP("boola", "a", false, "a boolean flag")
output, err := executeCommand(c, "c", "-a", "--unknown", "flag")
if err == nil {
t.Error("expected unknown flag error")
}
checkStringContains(t, output, "unknown flag: --unknown")
}
func TestFParseErrWhitelistSameCommand(t *testing.T) {
c := &Command{
Use: "c",
Run: emptyRun,
FParseErrWhitelist: FParseErrWhitelist{
UnknownFlags: true,
},
}
c.Flags().BoolP("boola", "a", false, "a boolean flag")
_, err := executeCommand(c, "c", "-a", "--unknown", "flag")
if err != nil {
t.Error("unexpected error: ", err)
}
}
func TestFParseErrWhitelistParentCommand(t *testing.T) {
root := &Command{
Use: "root",
Run: emptyRun,
FParseErrWhitelist: FParseErrWhitelist{
UnknownFlags: true,
},
}
c := &Command{
Use: "child",
Run: emptyRun,
}
c.Flags().BoolP("boola", "a", false, "a boolean flag")
root.AddCommand(c)
output, err := executeCommand(root, "child", "-a", "--unknown", "flag")
if err == nil {
t.Error("expected unknown flag error")
}
checkStringContains(t, output, "unknown flag: --unknown")
}
func TestFParseErrWhitelistChildCommand(t *testing.T) {
root := &Command{
Use: "root",
Run: emptyRun,
}
c := &Command{
Use: "child",
Run: emptyRun,
FParseErrWhitelist: FParseErrWhitelist{
UnknownFlags: true,
},
}
c.Flags().BoolP("boola", "a", false, "a boolean flag")
root.AddCommand(c)
_, err := executeCommand(root, "child", "-a", "--unknown", "flag")
if err != nil {
t.Error("unexpected error: ", err.Error())
}
}
func TestFParseErrWhitelistSiblingCommand(t *testing.T) {
root := &Command{
Use: "root",
Run: emptyRun,
}
c := &Command{
Use: "child",
Run: emptyRun,
FParseErrWhitelist: FParseErrWhitelist{
UnknownFlags: true,
},
}
c.Flags().BoolP("boola", "a", false, "a boolean flag")
s := &Command{
Use: "sibling",
Run: emptyRun,
}
s.Flags().BoolP("boolb", "b", false, "a boolean flag")
root.AddCommand(c)
root.AddCommand(s)
output, err := executeCommand(root, "sibling", "-b", "--unknown", "flag")
if err == nil {
t.Error("expected unknown flag error")
}
checkStringContains(t, output, "unknown flag: --unknown")
}