Add Global Normalization Function

[close #110]
This commit is contained in:
Anastasis Andronidis 2015-05-14 19:38:15 +02:00 committed by spf13
parent e0f326dabc
commit d910a04b50
2 changed files with 51 additions and 0 deletions

View file

@ -8,6 +8,8 @@ import (
"runtime" "runtime"
"strings" "strings"
"testing" "testing"
"github.com/spf13/pflag"
) )
var _ = fmt.Println var _ = fmt.Println
@ -913,3 +915,28 @@ func TestPeristentPreRunPropagation(t *testing.T) {
t.Error("RootCmd PersistentPreRun not called but should have been") 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")
}
}

View file

@ -94,6 +94,8 @@ type Command struct {
helpFunc func(*Command, []string) // Help can be defined by application helpFunc func(*Command, []string) // Help can be defined by application
helpCommand *Command // The help command helpCommand *Command // The help command
helpFlagVal bool 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 // os.Args[1:] by default, if desired, can be overridden
@ -152,6 +154,19 @@ func (c *Command) SetHelpTemplate(s string) {
c.helpTemplate = s 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) { func (c *Command) UsageFunc() (f func(*Command) error) {
if c.usageFunc != nil { if c.usageFunc != nil {
return c.usageFunc return c.usageFunc
@ -610,6 +625,10 @@ func (c *Command) AddCommand(cmds ...*Command) {
if nameLen > c.commandsMaxNameLen { if nameLen > c.commandsMaxNameLen {
c.commandsMaxNameLen = nameLen 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) c.commands = append(c.commands, x)
} }
} }
@ -834,6 +853,11 @@ func (c *Command) HasParent() bool {
return c.parent != nil 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) // Get the complete FlagSet that applies to this command (local and persistent declared here and by all parents)
func (c *Command) Flags() *flag.FlagSet { func (c *Command) Flags() *flag.FlagSet {
if c.flags == nil { if c.flags == nil {