Allow for legacy and newer Action func signatures
This commit is contained in:
parent
d48e22a9dd
commit
d45f7c1fe2
51
app.go
51
app.go
@ -6,6 +6,7 @@ import (
|
|||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"reflect"
|
||||||
"sort"
|
"sort"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
@ -55,7 +56,10 @@ type App struct {
|
|||||||
// It is run even if Action() panics
|
// It is run even if Action() panics
|
||||||
After AfterFunc
|
After AfterFunc
|
||||||
// The action to execute when no subcommands are specified
|
// The action to execute when no subcommands are specified
|
||||||
Action ActionFunc
|
Action interface{}
|
||||||
|
// TODO: replace `Action: interface{}` with `Action: ActionFunc` once some kind
|
||||||
|
// of deprecation period has passed, maybe?
|
||||||
|
|
||||||
// Execute this function if the proper command cannot be found
|
// Execute this function if the proper command cannot be found
|
||||||
CommandNotFound CommandNotFoundFunc
|
CommandNotFound CommandNotFoundFunc
|
||||||
// Execute this function if an usage error occurs
|
// Execute this function if an usage error occurs
|
||||||
@ -179,8 +183,7 @@ func (a *App) Run(arguments []string) (err error) {
|
|||||||
|
|
||||||
if a.After != nil {
|
if a.After != nil {
|
||||||
defer func() {
|
defer func() {
|
||||||
afterErr := a.After(context)
|
if afterErr := a.After(context); afterErr != nil {
|
||||||
if afterErr != nil {
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = NewMultiError(err, afterErr)
|
err = NewMultiError(err, afterErr)
|
||||||
} else {
|
} else {
|
||||||
@ -210,9 +213,11 @@ func (a *App) Run(arguments []string) (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Run default Action
|
// Run default Action
|
||||||
err = a.Action(context)
|
err = HandleAction(a.Action, context)
|
||||||
HandleExitCoder(err)
|
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
HandleExitCoder(err)
|
||||||
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -318,7 +323,12 @@ func (a *App) RunAsSubcommand(ctx *Context) (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Run default Action
|
// Run default Action
|
||||||
return a.Action(context)
|
err = HandleAction(a.Action, context)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
HandleExitCoder(err)
|
||||||
|
}
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the named command on App. Returns nil if the command does not exist
|
// Returns the named command on App. Returns nil if the command does not exist
|
||||||
@ -368,3 +378,32 @@ func (a Author) String() string {
|
|||||||
|
|
||||||
return fmt.Sprintf("%v %v", a.Name, e)
|
return fmt.Sprintf("%v %v", a.Name, e)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HandleAction uses ✧✧✧reflection✧✧✧ to figure out if the given Action is an
|
||||||
|
// ActionFunc, LegacyActionFunc, or some other invalid thing. If it's an
|
||||||
|
// ActionFunc or LegacyActionFunc, the func is run!
|
||||||
|
func HandleAction(action interface{}, context *Context) error {
|
||||||
|
if reflect.TypeOf(action).Kind() != reflect.Func {
|
||||||
|
panic("given Action must be a func")
|
||||||
|
}
|
||||||
|
|
||||||
|
vals := reflect.ValueOf(action).Call([]reflect.Value{reflect.ValueOf(context)})
|
||||||
|
|
||||||
|
if len(vals) == 0 {
|
||||||
|
fmt.Fprintln(os.Stderr,
|
||||||
|
"DEPRECATED Action signature. Must be `cli.ActionFunc`")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(vals) > 1 {
|
||||||
|
fmt.Fprintln(os.Stderr,
|
||||||
|
"ERROR invalid Action signature. Must be `cli.ActionFunc`")
|
||||||
|
panic("given Action has invalid return signature")
|
||||||
|
}
|
||||||
|
|
||||||
|
if err, ok := reflect.ValueOf(vals[0]).Interface().(error); ok {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
@ -34,7 +34,10 @@ type Command struct {
|
|||||||
// It is run even if Action() panics
|
// It is run even if Action() panics
|
||||||
After AfterFunc
|
After AfterFunc
|
||||||
// The function to call when this command is invoked
|
// The function to call when this command is invoked
|
||||||
Action ActionFunc
|
Action interface{}
|
||||||
|
// TODO: replace `Action: interface{}` with `Action: ActionFunc` once some kind
|
||||||
|
// of deprecation period has passed, maybe?
|
||||||
|
|
||||||
// Execute this function if a usage error occurs.
|
// Execute this function if a usage error occurs.
|
||||||
OnUsageError OnUsageErrorFunc
|
OnUsageError OnUsageErrorFunc
|
||||||
// List of child commands
|
// List of child commands
|
||||||
@ -178,7 +181,8 @@ func (c Command) Run(ctx *Context) (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
context.Command = c
|
context.Command = c
|
||||||
err = c.Action(context)
|
err = HandleAction(c.Action, context)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
HandleExitCoder(err)
|
HandleExitCoder(err)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user