Don't display usage on a returned error by a RunE function

Signed-off-by: Pierre-Emmanuel Jacquier <pierre-emmanuel.jacquier@epitech.eu>
This commit is contained in:
Pierre-Emmanuel Jacquier 2018-07-04 14:23:45 +02:00
parent a114f312e0
commit 4864275d4a

View file

@ -27,6 +27,24 @@ import (
flag "github.com/spf13/pflag"
)
// CmdErrorType command error type
type CmdErrorType int
const (
// ErrHelp is like flag.ErrHelp
ErrHelp CmdErrorType = iota
// RunError error returned during a Run function
RunError
// CommandError error during cmd execution or flag parsing
CommandError
)
// CmdError command executed error type
type CmdError struct {
error
CmdErrorType
}
// FParseErrWhitelist configures Flag parse errors to be ignored
type FParseErrWhitelist flag.ParseErrorsWhitelist
@ -672,9 +690,9 @@ func (c *Command) ArgsLenAtDash() int {
return c.Flags().ArgsLenAtDash()
}
func (c *Command) execute(a []string) (err error) {
func (c *Command) execute(a []string) *CmdError {
if c == nil {
return fmt.Errorf("Called Execute() on a nil Command")
return &CmdError{fmt.Errorf("Called Execute() on a nil Command"), CommandError}
}
if len(c.Deprecated) > 0 {
@ -686,9 +704,9 @@ func (c *Command) execute(a []string) (err error) {
c.InitDefaultHelpFlag()
c.InitDefaultVersionFlag()
err = c.ParseFlags(a)
err := c.ParseFlags(a)
if err != nil {
return c.FlagErrorFunc()(c, err)
return &CmdError{c.FlagErrorFunc()(c, err), CommandError}
}
// If help is called, regardless of other flags, return we want help.
@ -698,11 +716,11 @@ func (c *Command) execute(a []string) (err error) {
// should be impossible to get here as we always declare a help
// flag in InitDefaultHelpFlag()
c.Println("\"help\" flag declared as non-bool. Please correct your code")
return err
return &CmdError{err, CommandError}
}
if helpVal {
return flag.ErrHelp
return &CmdError{flag.ErrHelp, ErrHelp}
}
// for back-compat, only add version flag behavior if version is defined
@ -710,19 +728,19 @@ func (c *Command) execute(a []string) (err error) {
versionVal, err := c.Flags().GetBool("version")
if err != nil {
c.Println("\"version\" flag declared as non-bool. Please correct your code")
return err
return &CmdError{err, CommandError}
}
if versionVal {
err := tmpl(c.OutOrStdout(), c.VersionTemplate(), c)
if err != nil {
c.Println(err)
}
return err
return &CmdError{err, CommandError}
}
}
if !c.Runnable() {
return flag.ErrHelp
return &CmdError{flag.ErrHelp, ErrHelp}
}
c.preRun()
@ -733,13 +751,13 @@ func (c *Command) execute(a []string) (err error) {
}
if err := c.ValidateArgs(argWoFlags); err != nil {
return err
return &CmdError{err, CommandError}
}
for p := c; p != nil; p = p.Parent() {
if p.PersistentPreRunE != nil {
if err := p.PersistentPreRunE(c, argWoFlags); err != nil {
return err
return &CmdError{err, RunError}
}
break
} else if p.PersistentPreRun != nil {
@ -749,25 +767,25 @@ func (c *Command) execute(a []string) (err error) {
}
if c.PreRunE != nil {
if err := c.PreRunE(c, argWoFlags); err != nil {
return err
return &CmdError{err, RunError}
}
} else if c.PreRun != nil {
c.PreRun(c, argWoFlags)
}
if err := c.validateRequiredFlags(); err != nil {
return err
return &CmdError{err, CommandError}
}
if c.RunE != nil {
if err := c.RunE(c, argWoFlags); err != nil {
return err
return &CmdError{err, RunError}
}
} else {
c.Run(c, argWoFlags)
}
if c.PostRunE != nil {
if err := c.PostRunE(c, argWoFlags); err != nil {
return err
return &CmdError{err, RunError}
}
} else if c.PostRun != nil {
c.PostRun(c, argWoFlags)
@ -775,7 +793,7 @@ func (c *Command) execute(a []string) (err error) {
for p := c; p != nil; p = p.Parent() {
if p.PersistentPostRunE != nil {
if err := p.PersistentPostRunE(c, argWoFlags); err != nil {
return err
return &CmdError{err, RunError}
}
break
} else if p.PersistentPostRun != nil {
@ -849,19 +867,23 @@ func (c *Command) ExecuteC() (cmd *Command, err error) {
cmd.commandCalledAs.name = cmd.Name()
}
err = cmd.execute(flags)
if err != nil {
cmdErr := cmd.execute(flags)
if cmdErr != nil {
// Always show help if requested, even if SilenceErrors is in
// effect
if err == flag.ErrHelp {
if cmdErr.CmdErrorType == ErrHelp {
cmd.HelpFunc()(cmd, args)
return cmd, nil
}
if cmdErr.CmdErrorType == RunError {
return cmd, cmdErr
}
// If root command has SilentErrors flagged,
// all subcommands should respect it
if !cmd.SilenceErrors && !c.SilenceErrors {
c.Println("Error:", err.Error())
c.Println("Error:", cmdErr)
}
// If root command has SilentUsage flagged,
@ -869,6 +891,7 @@ func (c *Command) ExecuteC() (cmd *Command, err error) {
if !cmd.SilenceUsage && !c.SilenceUsage {
c.Println(cmd.UsageString())
}
return cmd, cmdErr
}
return cmd, err
}