From 87fe13079e3f452a366ae8d7f991261f9324d630 Mon Sep 17 00:00:00 2001 From: Jesse Szwedko Date: Mon, 24 Apr 2017 15:19:34 -0700 Subject: [PATCH] Rely on Command context in Run() Was previously relying on the parent context which caused things like `.Command` to not be available to OnUsageError(). Fixes #609 --- command.go | 16 ++++++++-------- command_test.go | 24 ++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 8 deletions(-) diff --git a/command.go b/command.go index 40ebdb6..63f183a 100644 --- a/command.go +++ b/command.go @@ -154,19 +154,20 @@ func (c Command) Run(ctx *Context) (err error) { } context := NewContext(ctx.App, set, ctx) + context.Command = c if checkCommandCompletions(context, c.Name) { return nil } if err != nil { if c.OnUsageError != nil { - err := c.OnUsageError(ctx, err, false) + err := c.OnUsageError(context, err, false) HandleExitCoder(err) return err } - fmt.Fprintln(ctx.App.Writer, "Incorrect Usage:", err.Error()) - fmt.Fprintln(ctx.App.Writer) - ShowCommandHelp(ctx, c.Name) + fmt.Fprintln(context.App.Writer, "Incorrect Usage:", err.Error()) + fmt.Fprintln(context.App.Writer) + ShowCommandHelp(context, c.Name) return err } @@ -191,9 +192,9 @@ func (c Command) Run(ctx *Context) (err error) { 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) + fmt.Fprintln(context.App.Writer, err) + fmt.Fprintln(context.App.Writer) + ShowCommandHelp(context, c.Name) HandleExitCoder(err) return err } @@ -203,7 +204,6 @@ func (c Command) Run(ctx *Context) (err error) { c.Action = helpSubcommand.Action } - context.Command = c err = HandleAction(c.Action, context) if err != nil { diff --git a/command_test.go b/command_test.go index 5710184..10fff2d 100644 --- a/command_test.go +++ b/command_test.go @@ -127,6 +127,30 @@ func TestCommand_Run_BeforeSavesMetadata(t *testing.T) { } } +func TestCommand_OnUsageError_hasCommandContext(t *testing.T) { + app := NewApp() + app.Commands = []Command{ + { + Name: "bar", + Flags: []Flag{ + IntFlag{Name: "flag"}, + }, + OnUsageError: func(c *Context, err error, _ bool) error { + return fmt.Errorf("intercepted in %s: %s", c.Command.Name, err.Error()) + }, + }, + } + + err := app.Run([]string{"foo", "bar", "--flag=wrong"}) + if err == nil { + t.Fatalf("expected to receive error from Run, got none") + } + + if !strings.HasPrefix(err.Error(), "intercepted in bar") { + t.Errorf("Expect an intercepted error, but got \"%v\"", err) + } +} + func TestCommand_OnUsageError_WithWrongFlagValue(t *testing.T) { app := NewApp() app.Commands = []Command{