From 817fe94c8b8f0ecc301dec298405bbcd0263f9bf Mon Sep 17 00:00:00 2001 From: poy Date: Tue, 13 Oct 2020 22:54:23 -0600 Subject: [PATCH] Adds SetContext() fixes #563 --- command.go | 8 +++++++- command_test.go | 21 ++++++++++++++------- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/command.go b/command.go index b098c330e..14b4406ea 100644 --- a/command.go +++ b/command.go @@ -244,11 +244,17 @@ type Command struct { } // Context returns underlying command context. If command wasn't -// executed with ExecuteContext Context returns Background context. +// executed with ExecuteContext Context, or overriden via SetContext it +// returns Background context. func (c *Command) Context() context.Context { return c.ctx } +// SetContext overrides the command's underlying context. +func (c *Command) SetContext(ctx context.Context) { + c.ctx = ctx +} + // SetArgs sets arguments for the command. It is set to os.Args[1:] by default, if desired, can be overridden // particularly useful when testing. func (c *Command) SetArgs(a []string) { diff --git a/command_test.go b/command_test.go index 8033ac2e2..71629a280 100644 --- a/command_test.go +++ b/command_test.go @@ -162,17 +162,24 @@ func TestSubcommandExecuteC(t *testing.T) { } func TestExecuteContext(t *testing.T) { - ctx := context.TODO() + ctx := context.WithValue(context.TODO(), "base", "base") - ctxRun := func(cmd *Command, args []string) { - if cmd.Context() != ctx { - t.Errorf("Command %q must have context when called with ExecuteContext", cmd.Use) + ctxRun := func(name string, testValues ...string) func(*Command, []string) { + return func(cmd *Command, args []string) { + for _, testValue := range testValues { + actual, _ := cmd.Context().Value(testValue).(string) + if actual != testValue { + t.Fatalf("Command %q must have context with value %s, got %s", name, testValue, actual) + } + } + + cmd.SetContext(context.WithValue(cmd.Context(), name, name)) } } - rootCmd := &Command{Use: "root", Run: ctxRun, PreRun: ctxRun} - childCmd := &Command{Use: "child", Run: ctxRun, PreRun: ctxRun} - granchildCmd := &Command{Use: "grandchild", Run: ctxRun, PreRun: ctxRun} + rootCmd := &Command{TraverseChildrenHooks: true, Use: "root", PersistentPreRun: ctxRun("root", "base"), Run: ctxRun("root", "base", "root")} + childCmd := &Command{Use: "child", PersistentPreRun: ctxRun("child", "base", "root", "root"), Run: ctxRun("child", "base", "root", "root", "child")} + granchildCmd := &Command{Use: "grandchild", PersistentPreRun: ctxRun("grandchild", "base", "root", "root", "child", "child"), Run: ctxRun("grandchild", "base", "root", "root", "child", "child", "grandchild")} childCmd.AddCommand(granchildCmd) rootCmd.AddCommand(childCmd)