From d910a04b50558720351969b37a39a931b37b99c7 Mon Sep 17 00:00:00 2001 From: Anastasis Andronidis Date: Thu, 14 May 2015 19:38:15 +0200 Subject: [PATCH] Add Global Normalization Function [close #110] --- cobra_test.go | 27 +++++++++++++++++++++++++++ command.go | 24 ++++++++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/cobra_test.go b/cobra_test.go index 71243b51..9848d211 100644 --- a/cobra_test.go +++ b/cobra_test.go @@ -8,6 +8,8 @@ import ( "runtime" "strings" "testing" + + "github.com/spf13/pflag" ) var _ = fmt.Println @@ -913,3 +915,28 @@ func TestPeristentPreRunPropagation(t *testing.T) { t.Error("RootCmd PersistentPreRun not called but should have been") } } + +func TestGlobalNormFuncPropagation(t *testing.T) { + normFunc := func(f *pflag.FlagSet, name string) pflag.NormalizedName { + return pflag.NormalizedName(name) + } + + rootCmd := initialize() + rootCmd.SetGlobalNormalizationFunc(normFunc) + if reflect.ValueOf(normFunc) != reflect.ValueOf(rootCmd.GlobalNormalizationFunc()) { + t.Error("rootCmd seems to have a wrong normalization function") + } + + // First add the cmdEchoSub to cmdPrint + cmdPrint.AddCommand(cmdEchoSub) + if cmdPrint.GlobalNormalizationFunc() != nil && cmdEchoSub.GlobalNormalizationFunc() != nil { + t.Error("cmdPrint and cmdEchoSub should had no normalization functions") + } + + // Now add cmdPrint to rootCmd + rootCmd.AddCommand(cmdPrint) + if reflect.ValueOf(cmdPrint.GlobalNormalizationFunc()).Pointer() != reflect.ValueOf(rootCmd.GlobalNormalizationFunc()).Pointer() || + reflect.ValueOf(cmdEchoSub.GlobalNormalizationFunc()).Pointer() != reflect.ValueOf(rootCmd.GlobalNormalizationFunc()).Pointer() { + t.Error("cmdPrint and cmdEchoSub should had the normalization function of rootCmd") + } +} diff --git a/command.go b/command.go index 7dd34f6d..3831c337 100644 --- a/command.go +++ b/command.go @@ -94,6 +94,8 @@ type Command struct { helpFunc func(*Command, []string) // Help can be defined by application helpCommand *Command // The help command helpFlagVal bool + // The global normalization function that we can use on every pFlag set and children commands + globNormFunc func(f *flag.FlagSet, name string) flag.NormalizedName } // os.Args[1:] by default, if desired, can be overridden @@ -152,6 +154,19 @@ func (c *Command) SetHelpTemplate(s string) { c.helpTemplate = s } +// SetGlobalNormalizationFunc sets a normalization function to all flag sets and also to child commands. +// The user should not have a cyclic dependency on commands. +func (c *Command) SetGlobalNormalizationFunc(n func(f *flag.FlagSet, name string) flag.NormalizedName) { + c.Flags().SetNormalizeFunc(n) + c.PersistentFlags().SetNormalizeFunc(n) + c.LocalFlags().SetNormalizeFunc(n) + c.globNormFunc = n + + for _, command := range c.commands { + command.SetGlobalNormalizationFunc(n) + } +} + func (c *Command) UsageFunc() (f func(*Command) error) { if c.usageFunc != nil { return c.usageFunc @@ -610,6 +625,10 @@ func (c *Command) AddCommand(cmds ...*Command) { if nameLen > c.commandsMaxNameLen { c.commandsMaxNameLen = nameLen } + // If glabal normalization function exists, update all children + if c.globNormFunc != nil { + x.SetGlobalNormalizationFunc(c.globNormFunc) + } c.commands = append(c.commands, x) } } @@ -834,6 +853,11 @@ func (c *Command) HasParent() bool { return c.parent != nil } +// GlobalNormalizationFunc returns the global normalization function or nil if doesn't exists +func (c *Command) GlobalNormalizationFunc() func(f *flag.FlagSet, name string) flag.NormalizedName { + return c.globNormFunc +} + // Get the complete FlagSet that applies to this command (local and persistent declared here and by all parents) func (c *Command) Flags() *flag.FlagSet { if c.flags == nil {