Merge pull request #315 from blaubaer/master
Improved Before/After handling for Commands
This commit is contained in:
commit
f9cc3001e0
3
app.go
3
app.go
@ -164,6 +164,9 @@ func (a *App) Run(arguments []string) (err error) {
|
|||||||
if a.Before != nil {
|
if a.Before != nil {
|
||||||
err := a.Before(context)
|
err := a.Before(context)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
fmt.Fprintln(a.Writer, err)
|
||||||
|
fmt.Fprintln(a.Writer)
|
||||||
|
ShowAppHelp(context)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -942,6 +942,11 @@ func TestApp_Run_SubcommandDoesNotOverwriteErrorFromBefore(t *testing.T) {
|
|||||||
app := NewApp()
|
app := NewApp()
|
||||||
app.Commands = []Command{
|
app.Commands = []Command{
|
||||||
Command{
|
Command{
|
||||||
|
Subcommands: []Command{
|
||||||
|
Command{
|
||||||
|
Name: "sub",
|
||||||
|
},
|
||||||
|
},
|
||||||
Name: "bar",
|
Name: "bar",
|
||||||
Before: func(c *Context) error { return fmt.Errorf("before error") },
|
Before: func(c *Context) error { return fmt.Errorf("before error") },
|
||||||
After: func(c *Context) error { return fmt.Errorf("after error") },
|
After: func(c *Context) error { return fmt.Errorf("after error") },
|
||||||
|
29
command.go
29
command.go
@ -54,8 +54,8 @@ func (c Command) FullName() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Invokes the command given the context, parses ctx.Args() to generate command-specific flags
|
// Invokes the command given the context, parses ctx.Args() to generate command-specific flags
|
||||||
func (c Command) Run(ctx *Context) error {
|
func (c Command) Run(ctx *Context) (err error) {
|
||||||
if len(c.Subcommands) > 0 || c.Before != nil || c.After != nil {
|
if len(c.Subcommands) > 0 {
|
||||||
return c.startApp(ctx)
|
return c.startApp(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -74,7 +74,6 @@ func (c Command) Run(ctx *Context) error {
|
|||||||
set := flagSet(c.Name, c.Flags)
|
set := flagSet(c.Name, c.Flags)
|
||||||
set.SetOutput(ioutil.Discard)
|
set.SetOutput(ioutil.Discard)
|
||||||
|
|
||||||
var err error
|
|
||||||
if !c.SkipFlagParsing {
|
if !c.SkipFlagParsing {
|
||||||
firstFlagIndex := -1
|
firstFlagIndex := -1
|
||||||
terminatorIndex := -1
|
terminatorIndex := -1
|
||||||
@ -133,6 +132,30 @@ func (c Command) Run(ctx *Context) error {
|
|||||||
if checkCommandHelp(context, c.Name) {
|
if checkCommandHelp(context, c.Name) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if c.After != nil {
|
||||||
|
defer func() {
|
||||||
|
afterErr := c.After(context)
|
||||||
|
if afterErr != nil {
|
||||||
|
if err != nil {
|
||||||
|
err = NewMultiError(err, afterErr)
|
||||||
|
} else {
|
||||||
|
err = afterErr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.Before != nil {
|
||||||
|
err := c.Before(context)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintln(ctx.App.Writer, err)
|
||||||
|
fmt.Fprintln(ctx.App.Writer)
|
||||||
|
ShowCommandHelp(ctx, c.Name)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
context.Command = c
|
context.Command = c
|
||||||
c.Action(context)
|
c.Action(context)
|
||||||
return nil
|
return nil
|
||||||
|
@ -5,6 +5,8 @@ import (
|
|||||||
"flag"
|
"flag"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"testing"
|
"testing"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestCommandFlagParsing(t *testing.T) {
|
func TestCommandFlagParsing(t *testing.T) {
|
||||||
@ -43,3 +45,26 @@ func TestCommandFlagParsing(t *testing.T) {
|
|||||||
expect(t, []string(context.Args()), c.testArgs)
|
expect(t, []string(context.Args()), c.testArgs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestCommand_Run_DoesNotOverwriteErrorFromBefore(t *testing.T) {
|
||||||
|
app := NewApp()
|
||||||
|
app.Commands = []Command{
|
||||||
|
Command{
|
||||||
|
Name: "bar",
|
||||||
|
Before: func(c *Context) error { return fmt.Errorf("before error") },
|
||||||
|
After: func(c *Context) error { return fmt.Errorf("after error") },
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
err := app.Run([]string{"foo", "bar"})
|
||||||
|
if err == nil {
|
||||||
|
t.Fatalf("expected to receive error from Run, got none")
|
||||||
|
}
|
||||||
|
|
||||||
|
if !strings.Contains(err.Error(), "before error") {
|
||||||
|
t.Errorf("expected text of error from Before method, but got none in \"%v\"", err)
|
||||||
|
}
|
||||||
|
if !strings.Contains(err.Error(), "after error") {
|
||||||
|
t.Errorf("expected text of error from After method, but got none in \"%v\"", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user