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 c542a67..ef3d2fc 100644 --- a/context.go +++ b/context.go @@ -141,6 +141,16 @@ 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) +} + +// 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 { @@ -247,6 +257,19 @@ 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 + } +} + 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 cbad304..4c23271 100644 --- a/context_test.go +++ b/context_test.go @@ -202,3 +202,31 @@ func TestContext_GlobalFlagsInSubcommands(t *testing.T) { expect(t, subcommandRun, true) expect(t, parentFlag, true) } + +func TestContext_Set(t *testing.T) { + set := flag.NewFlagSet("test", 0) + set.Int("int", 5, "an int") + c := NewContext(nil, set, nil) + + 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) +}