From a3b93076fffa81ce505c15d47e3f847d37a97382 Mon Sep 17 00:00:00 2001 From: bryanl Date: Mon, 8 Jun 2015 16:21:26 -0400 Subject: [PATCH 1/3] Allow context value to be set after parse This change allows a context value to be set after parsing. The use case is updating default settings in a Before func. An example usage: ``` f, err := os.Open(configPath) if err == nil { config, err := docli.NewConfig(f) if err != nil { panic(err) } c.Set("token", config.APIKey) } ``` --- context.go | 5 +++++ context_test.go | 9 +++++++++ 2 files changed, 14 insertions(+) diff --git a/context.go b/context.go index 5b67129..3c8f468 100644 --- a/context.go +++ b/context.go @@ -132,6 +132,11 @@ func (c *Context) NumFlags() int { return c.flagSet.NFlag() } +// Set sets a context flag to a value. +func (c *Context) Set(name, value string) error { + return c.flagSet.Set(name, value) +} + // Determines if the flag was actually set func (c *Context) IsSet(name string) bool { if c.setFlags == nil { diff --git a/context_test.go b/context_test.go index 6c27d06..c3f2631 100644 --- a/context_test.go +++ b/context_test.go @@ -113,3 +113,12 @@ func TestContext_NumFlags(t *testing.T) { globalSet.Parse([]string{"--myflagGlobal"}) expect(t, c.NumFlags(), 2) } + +func TestContext_Set(t *testing.T) { + set := flag.NewFlagSet("test", 0) + set.Int("int", 5, "an int") + c := cli.NewContext(nil, set, nil) + + c.Set("int", "1") + expect(t, c.Int("int"), 1) +} From e059dc81880375ca5efca91549d2361a87df35ae Mon Sep 17 00:00:00 2001 From: Dan Buch Date: Sat, 30 Apr 2016 11:46:47 -0400 Subject: [PATCH 2/3] Implement *Context.GlobalSet + relevant CHANGELOG entry --- CHANGELOG.md | 2 ++ context.go | 20 ++++++++++++++++++++ context_test.go | 19 +++++++++++++++++++ 3 files changed, 41 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 434c88c..a4d88ae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,8 @@ - This file! - Support for placeholders in flag usage strings - `App.Metadata` map for arbitrary data/state management +- `Set` and `GlobalSet` methods on `*cli.Context` for altering values after +parsing. ### Changed - The `App.Action` and `Command.Action` now prefer a return signature of diff --git a/context.go b/context.go index 93c000c..45013ac 100644 --- a/context.go +++ b/context.go @@ -146,6 +146,11 @@ func (c *Context) Set(name, value string) error { return c.flagSet.Set(name, value) } +// GlobalSet sets a context flag to a value on the global flagset +func (c *Context) GlobalSet(name, value string) error { + return globalContext(c).flagSet.Set(name, value) +} + // Determines if the flag was actually set func (c *Context) IsSet(name string) bool { if c.setFlags == nil { @@ -252,6 +257,21 @@ func (a Args) Swap(from, to int) error { return nil } +func globalContext(ctx *Context) *Context { + if ctx == nil { + return nil + } + + for { + if ctx.parentContext == nil { + return ctx + } + ctx = ctx.parentContext + } + + return nil +} + func lookupGlobalFlagSet(name string, ctx *Context) *flag.FlagSet { if ctx.parentContext != nil { ctx = ctx.parentContext diff --git a/context_test.go b/context_test.go index 20970b2..4c23271 100644 --- a/context_test.go +++ b/context_test.go @@ -211,3 +211,22 @@ func TestContext_Set(t *testing.T) { c.Set("int", "1") expect(t, c.Int("int"), 1) } + +func TestContext_GlobalSet(t *testing.T) { + gSet := flag.NewFlagSet("test", 0) + gSet.Int("int", 5, "an int") + + set := flag.NewFlagSet("sub", 0) + set.Int("int", 3, "an int") + + pc := NewContext(nil, gSet, nil) + c := NewContext(nil, set, pc) + + c.Set("int", "1") + expect(t, c.Int("int"), 1) + expect(t, c.GlobalInt("int"), 5) + + c.GlobalSet("int", "1") + expect(t, c.Int("int"), 1) + expect(t, c.GlobalInt("int"), 1) +} From f3b589e89239925ddf57fda31d049dd31ce3f495 Mon Sep 17 00:00:00 2001 From: Dan Buch Date: Sat, 30 Apr 2016 12:22:32 -0400 Subject: [PATCH 3/3] Remove unreachable code --- context.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/context.go b/context.go index 45013ac..ef3d2fc 100644 --- a/context.go +++ b/context.go @@ -268,8 +268,6 @@ func globalContext(ctx *Context) *Context { } ctx = ctx.parentContext } - - return nil } func lookupGlobalFlagSet(name string, ctx *Context) *flag.FlagSet {