From 0a7cad51ef27200ce065067b0d6401c15f4fb509 Mon Sep 17 00:00:00 2001 From: Steve Domino Date: Fri, 4 Sep 2015 16:29:28 -0600 Subject: [PATCH 1/5] checking if a flag is 'private' before adding it to the list of flags; this allows for hidden flags --- command.go | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/command.go b/command.go index bf642b53..21e001da 100644 --- a/command.go +++ b/command.go @@ -917,12 +917,16 @@ func (c *Command) LocalFlags() *flag.FlagSet { local := flag.NewFlagSet(c.Name(), flag.ContinueOnError) c.lflags.VisitAll(func(f *flag.Flag) { - local.AddFlag(f) + if !f.Private { + local.AddFlag(f) + } }) if !c.HasParent() { flag.CommandLine.VisitAll(func(f *flag.Flag) { if local.Lookup(f.Name) == nil { - local.AddFlag(f) + if !f.Private { + local.AddFlag(f) + } } }) } @@ -942,7 +946,9 @@ func (c *Command) InheritedFlags() *flag.FlagSet { if x.HasPersistentFlags() { x.PersistentFlags().VisitAll(func(f *flag.Flag) { if inherited.Lookup(f.Name) == nil && local.Lookup(f.Name) == nil { - inherited.AddFlag(f) + if !f.Private { + inherited.AddFlag(f) + } } }) } From 1c544baa194630ed41c1756dad28fb24dd237078 Mon Sep 17 00:00:00 2001 From: Steve Domino Date: Mon, 7 Sep 2015 18:34:39 -0600 Subject: [PATCH 2/5] updating 'private' to 'hidden' to match a corresponding change in pflag --- command.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/command.go b/command.go index 21e001da..5decbe2d 100644 --- a/command.go +++ b/command.go @@ -917,14 +917,14 @@ func (c *Command) LocalFlags() *flag.FlagSet { local := flag.NewFlagSet(c.Name(), flag.ContinueOnError) c.lflags.VisitAll(func(f *flag.Flag) { - if !f.Private { + if !f.Hidden { local.AddFlag(f) } }) if !c.HasParent() { flag.CommandLine.VisitAll(func(f *flag.Flag) { if local.Lookup(f.Name) == nil { - if !f.Private { + if !f.Hidden { local.AddFlag(f) } } @@ -946,7 +946,7 @@ func (c *Command) InheritedFlags() *flag.FlagSet { if x.HasPersistentFlags() { x.PersistentFlags().VisitAll(func(f *flag.Flag) { if inherited.Lookup(f.Name) == nil && local.Lookup(f.Name) == nil { - if !f.Private { + if !f.Hidden { inherited.AddFlag(f) } } From f3eb417cf8e8ed1c6bd7836599727386e86be9f1 Mon Sep 17 00:00:00 2001 From: Steve Domino Date: Tue, 8 Sep 2015 11:21:51 -0600 Subject: [PATCH 3/5] adding tests to ensure hidden flags run as intended, but do not show up in usage/help text --- command_test.go | 79 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/command_test.go b/command_test.go index 477d84e7..5ac6563e 100644 --- a/command_test.go +++ b/command_test.go @@ -5,6 +5,85 @@ import ( "testing" ) +// test to ensure hidden flags run as intended +func TestHiddenFlagExecutes(t *testing.T) { + var out string + var secretFlag bool + + boringCmd := &Command{ + Use: "boring", + Short: "Do something boring...", + Long: `Not a flashy command, just does boring stuff`, + Run: func(cmd *Command, args []string) { + out = "boring output" + + if secretFlag { + out = "super secret NOT boring output!" + } + }, + } + + // + boringCmd.Flags().BoolVarP(&secretFlag, "secret", "s", false, "makes commands run in super secret mode") + boringCmd.Flags().MarkHidden("secret") + + // + boringCmd.Execute() + + if out != "boring output" { + t.Errorf("Command with hidden flag failed to run!") + } + + // + boringCmd.execute([]string{"-s"}) + + if out != "super secret NOT boring output!" { + t.Errorf("Hidden flag failed to run!") + } +} + +// test to ensure hidden flags do not show up in usage/help text +func TestHiddenFlagsAreHidden(t *testing.T) { + var out string + var secretFlag bool + var persistentSecretFlag bool + + boringCmd := &Command{ + Use: "boring", + Short: "Do something boring...", + Long: `Not a flashy command, just does boring stuff`, + Run: func(cmd *Command, args []string) { + out = "boring output" + + if secretFlag { + out = "super secret NOT boring output!" + } + + if persistentSecretFlag { + out = "you have no idea what you're getting yourself into!" + } + }, + } + + // + boringCmd.Flags().BoolVarP(&secretFlag, "secret", "s", false, "run this command in super secret mode") + boringCmd.Flags().MarkHidden("secret") + + // if a command has local flags, they will appear in usage/help text + if boringCmd.HasLocalFlags() { + t.Errorf("Hidden flag found!") + } + + // + boringCmd.PersistentFlags().BoolVarP(&persistentSecretFlag, "Secret", "S", false, "run any sub command in super secret mode") + boringCmd.Flags().MarkHidden("Secret") + + // if a command has inherited flags, they will appear in usage/help text + if boringCmd.HasInheritedFlags() { + t.Errorf("Hidden flag found!") + } +} + func TestStripFlags(t *testing.T) { tests := []struct { input []string From 8be60dc5cd4bbda73bb9831ac00c6b393df7e48e Mon Sep 17 00:00:00 2001 From: Steve Domino Date: Tue, 8 Sep 2015 11:27:06 -0600 Subject: [PATCH 4/5] some minor updates to tests --- command_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/command_test.go b/command_test.go index 5ac6563e..93edaa22 100644 --- a/command_test.go +++ b/command_test.go @@ -24,7 +24,7 @@ func TestHiddenFlagExecutes(t *testing.T) { } // - boringCmd.Flags().BoolVarP(&secretFlag, "secret", "s", false, "makes commands run in super secret mode") + boringCmd.Flags().BoolVarP(&secretFlag, "secret", "s", false, "makes this command run in super secret mode") boringCmd.Flags().MarkHidden("secret") // @@ -76,7 +76,7 @@ func TestHiddenFlagsAreHidden(t *testing.T) { // boringCmd.PersistentFlags().BoolVarP(&persistentSecretFlag, "Secret", "S", false, "run any sub command in super secret mode") - boringCmd.Flags().MarkHidden("Secret") + boringCmd.PersistentFlags().MarkHidden("Secret") // if a command has inherited flags, they will appear in usage/help text if boringCmd.HasInheritedFlags() { From dfa8ea9685f9a4168310a68a809d9cca85093a38 Mon Sep 17 00:00:00 2001 From: Steve Domino Date: Tue, 8 Sep 2015 12:57:31 -0600 Subject: [PATCH 5/5] tests now leverage the built in test suite, and are much less custom --- cobra_test.go | 24 ++++++++++---- command_test.go | 85 +++++++++++-------------------------------------- 2 files changed, 36 insertions(+), 73 deletions(-) diff --git a/cobra_test.go b/cobra_test.go index 3aed7dd6..da4b50a2 100644 --- a/cobra_test.go +++ b/cobra_test.go @@ -18,8 +18,8 @@ var _ = os.Stderr var tp, te, tt, t1, tr []string var rootPersPre, echoPre, echoPersPre, timesPersPre []string -var flagb1, flagb2, flagb3, flagbr, flagbp bool -var flags1, flags2a, flags2b, flags3 string +var flagb1, flagb2, flagb3, flagbr, flagbp, flagbh, flagbph bool +var flags1, flags2a, flags2b, flags3, outs string var flagi1, flagi2, flagi3, flagir int var globalFlag1 bool var flagEcho, rootcalled bool @@ -28,6 +28,18 @@ var versionUsed int const strtwoParentHelp = "help message for parent flag strtwo" const strtwoChildHelp = "help message for child flag strtwo" +var cmdHiddenFlags = &Command{ + Use: "hidden [string to set]", + Short: "set a string value to string var", + Long: `an utterly useless command for testing.`, + Run: func(cmd *Command, args []string) { + outs = "visible" + if flagbh { + outs = "hidden" + } + }, +} + var cmdPrint = &Command{ Use: "print [string to print]", Short: "Print anything to the screen", @@ -976,15 +988,15 @@ func TestFlagOnPflagCommandLine(t *testing.T) { func TestAddTemplateFunctions(t *testing.T) { AddTemplateFunc("t", func() bool { return true }) AddTemplateFuncs(template.FuncMap{ - "f": func() bool { return false }, - "h": func() string { return "Hello," }, + "f": func() bool { return false }, + "h": func() string { return "Hello," }, "w": func() string { return "world." }}) const usage = "Hello, world." - + c := &Command{} c.SetUsageTemplate(`{{if t}}{{h}}{{end}}{{if f}}{{h}}{{end}} {{w}}`) - + if us := c.UsageString(); us != usage { t.Errorf("c.UsageString() != \"%s\", is \"%s\"", usage, us) } diff --git a/command_test.go b/command_test.go index 93edaa22..adb6fcf1 100644 --- a/command_test.go +++ b/command_test.go @@ -5,82 +5,33 @@ import ( "testing" ) -// test to ensure hidden flags run as intended +func init() { + cmdHiddenFlags.Flags().BoolVarP(&flagbh, "boolh", "", false, "") + cmdHiddenFlags.Flags().MarkHidden("boolh") + + cmdHiddenFlags.PersistentFlags().BoolVarP(&flagbph, "boolph", "", false, "") + cmdHiddenFlags.PersistentFlags().MarkHidden("boolph") +} + +// test to ensure hidden flags run as intended; if the the hidden flag fails to +// run, the output will be incorrect func TestHiddenFlagExecutes(t *testing.T) { - var out string - var secretFlag bool - - boringCmd := &Command{ - Use: "boring", - Short: "Do something boring...", - Long: `Not a flashy command, just does boring stuff`, - Run: func(cmd *Command, args []string) { - out = "boring output" - - if secretFlag { - out = "super secret NOT boring output!" - } - }, - } - - // - boringCmd.Flags().BoolVarP(&secretFlag, "secret", "s", false, "makes this command run in super secret mode") - boringCmd.Flags().MarkHidden("secret") - - // - boringCmd.Execute() - - if out != "boring output" { - t.Errorf("Command with hidden flag failed to run!") - } - - // - boringCmd.execute([]string{"-s"}) - - if out != "super secret NOT boring output!" { + cmdHiddenFlags.execute([]string{"--boolh"}) + if outs != "hidden" { t.Errorf("Hidden flag failed to run!") } } -// test to ensure hidden flags do not show up in usage/help text +// test to ensure hidden flags do not show up in usage/help text; if a flag is +// found by Lookup() it will be visible in usage/help text func TestHiddenFlagsAreHidden(t *testing.T) { - var out string - var secretFlag bool - var persistentSecretFlag bool - boringCmd := &Command{ - Use: "boring", - Short: "Do something boring...", - Long: `Not a flashy command, just does boring stuff`, - Run: func(cmd *Command, args []string) { - out = "boring output" - - if secretFlag { - out = "super secret NOT boring output!" - } - - if persistentSecretFlag { - out = "you have no idea what you're getting yourself into!" - } - }, + if cmdHiddenFlags.LocalFlags().Lookup("boolh") != nil { + t.Errorf("unexpected flag 'boolh'") } - // - boringCmd.Flags().BoolVarP(&secretFlag, "secret", "s", false, "run this command in super secret mode") - boringCmd.Flags().MarkHidden("secret") - - // if a command has local flags, they will appear in usage/help text - if boringCmd.HasLocalFlags() { - t.Errorf("Hidden flag found!") - } - - // - boringCmd.PersistentFlags().BoolVarP(&persistentSecretFlag, "Secret", "S", false, "run any sub command in super secret mode") - boringCmd.PersistentFlags().MarkHidden("Secret") - - // if a command has inherited flags, they will appear in usage/help text - if boringCmd.HasInheritedFlags() { - t.Errorf("Hidden flag found!") + if cmdHiddenFlags.InheritedFlags().Lookup("boolph") != nil { + t.Errorf("unexpected flag 'boolph'") } }