Return exit code on error, disable in tests

This commit is contained in:
Ethan Frey 2017-06-14 16:51:33 +02:00
parent c5644aad31
commit 0ecb38c6da
2 changed files with 18 additions and 2 deletions

View File

@ -38,7 +38,7 @@ func PrepareBaseCmd(cmd *cobra.Command, envPrefix, defautRoot string) Executor {
cmd.PersistentFlags().String(HomeFlag, "", "root directory for config and data")
cmd.PersistentFlags().Bool(TraceFlag, false, "print out full stack trace on errors")
cmd.PersistentPreRunE = concatCobraCmdFuncs(bindFlagsLoadViper, cmd.PersistentPreRunE)
return Executor{cmd}
return Executor{cmd, os.Exit}
}
// PrepareMainCmd is meant for client side libs that want some more flags
@ -82,6 +82,11 @@ func copyEnvVars(prefix string) {
// Executor wraps the cobra Command with a nicer Execute method
type Executor struct {
*cobra.Command
Exit func(int) // this is os.Exit by default, override in tests
}
type ExitCoder interface {
ExitCode() int
}
// execute adds all child commands to the root command sets flags appropriately.
@ -91,12 +96,19 @@ func (e Executor) Execute() error {
e.SilenceErrors = true
err := e.Command.Execute()
if err != nil {
// TODO: something cooler with log-levels
if viper.GetBool(TraceFlag) {
fmt.Printf("ERROR: %+v\n", err)
} else {
fmt.Println("ERROR:", err.Error())
}
fmt.Printf("%#v\n", e)
// return error code 1 by default, can override it with a special error type
exitCode := 1
if ec, ok := err.(ExitCoder); ok {
exitCode = ec.ExitCode()
}
e.Exit(exitCode)
}
return err
}

View File

@ -46,6 +46,7 @@ func TestSetupEnv(t *testing.T) {
}
demo.Flags().String("foobar", "", "Some test value from config")
cmd := PrepareBaseCmd(demo, "DEMO", "/qwerty/asdfgh") // some missing dir..
cmd.Exit = func(int) {}
viper.Reset()
args := append([]string{cmd.Use}, tc.args...)
@ -98,6 +99,7 @@ func TestSetupConfig(t *testing.T) {
}
boo.Flags().String("boo", "", "Some test value from config")
cmd := PrepareBaseCmd(boo, "RD", "/qwerty/asdfgh") // some missing dir...
cmd.Exit = func(int) {}
viper.Reset()
args := append([]string{cmd.Use}, tc.args...)
@ -175,6 +177,7 @@ func TestSetupUnmarshal(t *testing.T) {
// from the default config here
marsh.Flags().Int("age", base.Age, "Some test value from config")
cmd := PrepareBaseCmd(marsh, "MR", "/qwerty/asdfgh") // some missing dir...
cmd.Exit = func(int) {}
viper.Reset()
args := append([]string{cmd.Use}, tc.args...)
@ -209,6 +212,7 @@ func TestSetupTrace(t *testing.T) {
},
}
cmd := PrepareBaseCmd(trace, "DBG", "/qwerty/asdfgh") // some missing dir..
cmd.Exit = func(int) {}
viper.Reset()
args := append([]string{cmd.Use}, tc.args...)