mirror of
https://github.com/spf13/cobra
synced 2024-11-24 22:57:12 +00:00
Improve consistency of flags when using SetGlobalNormalizationFunc (#522)
Fix #521
This commit is contained in:
parent
e5f66de850
commit
0dacccfbaa
2 changed files with 88 additions and 2 deletions
|
@ -190,6 +190,7 @@ func flagInit() {
|
||||||
cmdTimes.Flags().IntVarP(&flagi2, "inttwo", "j", 234, "help message for flag inttwo")
|
cmdTimes.Flags().IntVarP(&flagi2, "inttwo", "j", 234, "help message for flag inttwo")
|
||||||
cmdTimes.Flags().StringVarP(&flags2b, "strtwo", "t", "2", strtwoChildHelp)
|
cmdTimes.Flags().StringVarP(&flags2b, "strtwo", "t", "2", strtwoChildHelp)
|
||||||
cmdTimes.PersistentFlags().StringVarP(&flags2b, "strtwo", "t", "2", strtwoChildHelp)
|
cmdTimes.PersistentFlags().StringVarP(&flags2b, "strtwo", "t", "2", strtwoChildHelp)
|
||||||
|
cmdTimes.LocalFlags() // populate lflags before parent is set
|
||||||
cmdPrint.Flags().BoolVarP(&flagb3, "boolthree", "b", true, "help message for flag boolthree")
|
cmdPrint.Flags().BoolVarP(&flagb3, "boolthree", "b", true, "help message for flag boolthree")
|
||||||
cmdPrint.PersistentFlags().StringVarP(&flags3, "strthree", "s", "three", "help message for flag strthree")
|
cmdPrint.PersistentFlags().StringVarP(&flags3, "strthree", "s", "three", "help message for flag strthree")
|
||||||
}
|
}
|
||||||
|
@ -210,8 +211,8 @@ func initialize() *Command {
|
||||||
rootPersPre, echoPre, echoPersPre, timesPersPre = nil, nil, nil, nil
|
rootPersPre, echoPre, echoPersPre, timesPersPre = nil, nil, nil, nil
|
||||||
|
|
||||||
var c = cmdRootNoRun
|
var c = cmdRootNoRun
|
||||||
flagInit()
|
|
||||||
commandInit()
|
commandInit()
|
||||||
|
flagInit()
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -219,8 +220,8 @@ func initializeWithSameName() *Command {
|
||||||
tt, tp, te = nil, nil, nil
|
tt, tp, te = nil, nil, nil
|
||||||
rootPersPre, echoPre, echoPersPre, timesPersPre = nil, nil, nil, nil
|
rootPersPre, echoPre, echoPersPre, timesPersPre = nil, nil, nil, nil
|
||||||
var c = cmdRootSameName
|
var c = cmdRootSameName
|
||||||
flagInit()
|
|
||||||
commandInit()
|
commandInit()
|
||||||
|
flagInit()
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -910,6 +911,7 @@ func TestRootHelp(t *testing.T) {
|
||||||
func TestFlagAccess(t *testing.T) {
|
func TestFlagAccess(t *testing.T) {
|
||||||
initialize()
|
initialize()
|
||||||
|
|
||||||
|
cmdEcho.AddCommand(cmdTimes)
|
||||||
local := cmdTimes.LocalFlags()
|
local := cmdTimes.LocalFlags()
|
||||||
inherited := cmdTimes.InheritedFlags()
|
inherited := cmdTimes.InheritedFlags()
|
||||||
|
|
||||||
|
@ -1165,11 +1167,18 @@ func TestGlobalNormFuncPropagation(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
rootCmd := initialize()
|
rootCmd := initialize()
|
||||||
|
rootCmd.AddCommand(cmdEcho)
|
||||||
|
|
||||||
rootCmd.SetGlobalNormalizationFunc(normFunc)
|
rootCmd.SetGlobalNormalizationFunc(normFunc)
|
||||||
if reflect.ValueOf(normFunc).Pointer() != reflect.ValueOf(rootCmd.GlobalNormalizationFunc()).Pointer() {
|
if reflect.ValueOf(normFunc).Pointer() != reflect.ValueOf(rootCmd.GlobalNormalizationFunc()).Pointer() {
|
||||||
t.Error("rootCmd seems to have a wrong normalization function")
|
t.Error("rootCmd seems to have a wrong normalization function")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Also check it propagates retroactively
|
||||||
|
if reflect.ValueOf(normFunc).Pointer() != reflect.ValueOf(cmdEcho.GlobalNormalizationFunc()).Pointer() {
|
||||||
|
t.Error("cmdEcho should have had the normalization function of rootCmd")
|
||||||
|
}
|
||||||
|
|
||||||
// First add the cmdEchoSub to cmdPrint
|
// First add the cmdEchoSub to cmdPrint
|
||||||
cmdPrint.AddCommand(cmdEchoSub)
|
cmdPrint.AddCommand(cmdEchoSub)
|
||||||
if cmdPrint.GlobalNormalizationFunc() != nil && cmdEchoSub.GlobalNormalizationFunc() != nil {
|
if cmdPrint.GlobalNormalizationFunc() != nil && cmdEchoSub.GlobalNormalizationFunc() != nil {
|
||||||
|
@ -1184,6 +1193,67 @@ func TestGlobalNormFuncPropagation(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestNormPassedOnLocal(t *testing.T) {
|
||||||
|
n := func(f *pflag.FlagSet, name string) pflag.NormalizedName {
|
||||||
|
return pflag.NormalizedName(strings.ToUpper(name))
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd := &Command{}
|
||||||
|
flagVal := false
|
||||||
|
|
||||||
|
cmd.Flags().BoolVar(&flagVal, "flagname", true, "this is a dummy flag")
|
||||||
|
cmd.SetGlobalNormalizationFunc(n)
|
||||||
|
if cmd.LocalFlags().Lookup("flagname") != cmd.LocalFlags().Lookup("FLAGNAME") {
|
||||||
|
t.Error("Normalization function should be passed on to Local flag set")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNormPassedOnInherited(t *testing.T) {
|
||||||
|
n := func(f *pflag.FlagSet, name string) pflag.NormalizedName {
|
||||||
|
return pflag.NormalizedName(strings.ToUpper(name))
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd, childBefore, childAfter := &Command{}, &Command{}, &Command{}
|
||||||
|
flagVal := false
|
||||||
|
cmd.AddCommand(childBefore)
|
||||||
|
|
||||||
|
cmd.PersistentFlags().BoolVar(&flagVal, "flagname", true, "this is a dummy flag")
|
||||||
|
cmd.SetGlobalNormalizationFunc(n)
|
||||||
|
|
||||||
|
cmd.AddCommand(childAfter)
|
||||||
|
|
||||||
|
if f := childBefore.InheritedFlags(); f.Lookup("flagname") == nil || f.Lookup("flagname") != f.Lookup("FLAGNAME") {
|
||||||
|
t.Error("Normalization function should be passed on to inherited flag set in command added before flag")
|
||||||
|
}
|
||||||
|
if f := childAfter.InheritedFlags(); f.Lookup("flagname") == nil || f.Lookup("flagname") != f.Lookup("FLAGNAME") {
|
||||||
|
t.Error("Normalization function should be passed on to inherited flag set in command added after flag")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Related to https://github.com/spf13/cobra/issues/521.
|
||||||
|
func TestNormConsistent(t *testing.T) {
|
||||||
|
n := func(f *pflag.FlagSet, name string) pflag.NormalizedName {
|
||||||
|
return pflag.NormalizedName(strings.ToUpper(name))
|
||||||
|
}
|
||||||
|
id := func(f *pflag.FlagSet, name string) pflag.NormalizedName {
|
||||||
|
return pflag.NormalizedName(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd := &Command{}
|
||||||
|
flagVal := false
|
||||||
|
|
||||||
|
cmd.Flags().BoolVar(&flagVal, "flagname", true, "this is a dummy flag")
|
||||||
|
// Build local flag set
|
||||||
|
cmd.LocalFlags()
|
||||||
|
|
||||||
|
cmd.SetGlobalNormalizationFunc(n)
|
||||||
|
cmd.SetGlobalNormalizationFunc(id)
|
||||||
|
|
||||||
|
if cmd.LocalFlags().Lookup("flagname") == cmd.LocalFlags().Lookup("FLAGNAME") {
|
||||||
|
t.Error("Normalizing flag names should not result in duplicate flags")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestFlagOnPflagCommandLine(t *testing.T) {
|
func TestFlagOnPflagCommandLine(t *testing.T) {
|
||||||
flagName := "flagOnCommandLine"
|
flagName := "flagOnCommandLine"
|
||||||
pflag.String(flagName, "", "about my flag")
|
pflag.String(flagName, "", "about my flag")
|
||||||
|
|
16
command.go
16
command.go
|
@ -806,6 +806,7 @@ Simply type ` + c.Name() + ` help [path to command] for full details.`,
|
||||||
|
|
||||||
// ResetCommands used for testing.
|
// ResetCommands used for testing.
|
||||||
func (c *Command) ResetCommands() {
|
func (c *Command) ResetCommands() {
|
||||||
|
c.parent = nil
|
||||||
c.commands = nil
|
c.commands = nil
|
||||||
c.helpCommand = nil
|
c.helpCommand = nil
|
||||||
c.parentsPflags = nil
|
c.parentsPflags = nil
|
||||||
|
@ -1132,6 +1133,9 @@ func (c *Command) LocalFlags() *flag.FlagSet {
|
||||||
c.lflags.SetOutput(c.flagErrorBuf)
|
c.lflags.SetOutput(c.flagErrorBuf)
|
||||||
}
|
}
|
||||||
c.lflags.SortFlags = c.Flags().SortFlags
|
c.lflags.SortFlags = c.Flags().SortFlags
|
||||||
|
if c.globNormFunc != nil {
|
||||||
|
c.lflags.SetNormalizeFunc(c.globNormFunc)
|
||||||
|
}
|
||||||
|
|
||||||
addToLocal := func(f *flag.Flag) {
|
addToLocal := func(f *flag.Flag) {
|
||||||
if c.lflags.Lookup(f.Name) == nil && c.parentsPflags.Lookup(f.Name) == nil {
|
if c.lflags.Lookup(f.Name) == nil && c.parentsPflags.Lookup(f.Name) == nil {
|
||||||
|
@ -1156,6 +1160,10 @@ func (c *Command) InheritedFlags() *flag.FlagSet {
|
||||||
}
|
}
|
||||||
|
|
||||||
local := c.LocalFlags()
|
local := c.LocalFlags()
|
||||||
|
if c.globNormFunc != nil {
|
||||||
|
c.iflags.SetNormalizeFunc(c.globNormFunc)
|
||||||
|
}
|
||||||
|
|
||||||
c.parentsPflags.VisitAll(func(f *flag.Flag) {
|
c.parentsPflags.VisitAll(func(f *flag.Flag) {
|
||||||
if c.iflags.Lookup(f.Name) == nil && local.Lookup(f.Name) == nil {
|
if c.iflags.Lookup(f.Name) == nil && local.Lookup(f.Name) == nil {
|
||||||
c.iflags.AddFlag(f)
|
c.iflags.AddFlag(f)
|
||||||
|
@ -1189,6 +1197,10 @@ func (c *Command) ResetFlags() {
|
||||||
c.flags.SetOutput(c.flagErrorBuf)
|
c.flags.SetOutput(c.flagErrorBuf)
|
||||||
c.pflags = flag.NewFlagSet(c.Name(), flag.ContinueOnError)
|
c.pflags = flag.NewFlagSet(c.Name(), flag.ContinueOnError)
|
||||||
c.pflags.SetOutput(c.flagErrorBuf)
|
c.pflags.SetOutput(c.flagErrorBuf)
|
||||||
|
|
||||||
|
c.lflags = nil
|
||||||
|
c.iflags = nil
|
||||||
|
c.parentsPflags = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// HasFlags checks if the command contains any flags (local plus persistent from the entire structure).
|
// HasFlags checks if the command contains any flags (local plus persistent from the entire structure).
|
||||||
|
@ -1298,6 +1310,10 @@ func (c *Command) updateParentsPflags() {
|
||||||
c.parentsPflags.SortFlags = false
|
c.parentsPflags.SortFlags = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if c.globNormFunc != nil {
|
||||||
|
c.parentsPflags.SetNormalizeFunc(c.globNormFunc)
|
||||||
|
}
|
||||||
|
|
||||||
c.Root().PersistentFlags().AddFlagSet(flag.CommandLine)
|
c.Root().PersistentFlags().AddFlagSet(flag.CommandLine)
|
||||||
|
|
||||||
c.VisitParents(func(parent *Command) {
|
c.VisitParents(func(parent *Command) {
|
||||||
|
|
Loading…
Reference in a new issue