Repository: spf13/cobra
Pull request #345 (2016-09-08 13:51:47)

Go vet
A couple of cleanups needed for `go vet ./...` to pass.

Discovered after vendoring cobra.



Patch:
diff --git a/README.md b/README.md
index 5d2504b..2efda59 100644
--- a/README.md
+++ b/README.md
@@ -157,7 +157,12 @@ In a Cobra app, typically the main.go file is very bare. It serves, one purpose,
 ```go
 package main
 
-import "{pathToYourApp}/cmd"
+import (
+	"fmt"
+	"os"
+
+	"{pathToYourApp}/cmd"
+)
 
 func main() {
 	if err := cmd.RootCmd.Execute(); err != nil {
@@ -313,7 +318,12 @@ In a Cobra app, typically the main.go file is very bare. It serves, one purpose,
 ```go
 package main
 
-import "{pathToYourApp}/cmd"
+import (
+	"fmt"
+	"os"
+
+	"{pathToYourApp}/cmd"
+)
 
 func main() {
 	if err := cmd.RootCmd.Execute(); err != nil {
@@ -337,6 +347,7 @@ package cmd
 
 import (
 	"github.com/spf13/cobra"
+	"fmt"
 )
 
 func init() {
diff --git a/bash_completions.go b/bash_completions.go
index 7a5bd4d..8820ba8 100644
--- a/bash_completions.go
+++ b/bash_completions.go
@@ -10,6 +10,7 @@ import (
 	"github.com/spf13/pflag"
 )
 
+// Annotations for Bash completion.
 const (
 	BashCompFilenameExt     = "cobra_annotation_bash_completion_filename_extensions"
 	BashCompCustom          = "cobra_annotation_bash_completion_custom"
@@ -22,7 +23,7 @@ func preamble(out io.Writer, name string) error {
 	if err != nil {
 		return err
 	}
-	_, err = fmt.Fprint(out, `
+	preamStr := `
 __debug()
 {
     if [[ -n ${BASH_COMP_DEBUG_FILE} ]]; then
@@ -246,7 +247,8 @@ __handle_word()
     __handle_word
 }
 
-`)
+`
+	_, err = fmt.Fprint(out, preamStr)
 	return err
 }
 
@@ -566,6 +568,7 @@ func gen(cmd *Command, w io.Writer) error {
 	return nil
 }
 
+// GenBashCompletion generates bash completion file and writes to the passed writer.
 func (cmd *Command) GenBashCompletion(w io.Writer) error {
 	if err := preamble(w, cmd.Name()); err != nil {
 		return err
@@ -585,6 +588,7 @@ func nonCompletableFlag(flag *pflag.Flag) bool {
 	return flag.Hidden || len(flag.Deprecated) > 0
 }
 
+// GenBashCompletionFile generates bash completion file.
 func (cmd *Command) GenBashCompletionFile(filename string) error {
 	outFile, err := os.Create(filename)
 	if err != nil {
diff --git a/bash_completions.md b/bash_completions.md
index 6e3b71f..7fa970f 100644
--- a/bash_completions.md
+++ b/bash_completions.md
@@ -18,7 +18,7 @@ func main() {
 }
 ```
 
-That will get you completions of subcommands and flags. If you make additional annotations to your code, you can get even more intelligent and flexible behavior.
+`out.sh` will get you completions of subcommands and flags. Copy it to `/etc/bash_completion.d/` as described [here](https://debian-administration.org/article/316/An_introduction_to_bash_completion_part_1) and reset your terminal to use autocompletion. If you make additional annotations to your code, you can get even more intelligent and flexible behavior.
 
 ## Creating your own custom functions
 
diff --git a/cobra.go b/cobra.go
index b39c715..9605b98 100644
--- a/cobra.go
+++ b/cobra.go
@@ -37,7 +37,8 @@ var templateFuncs = template.FuncMap{
 
 var initializers []func()
 
-// Automatic prefix matching can be a dangerous thing to automatically enable in CLI tools.
+// EnablePrefixMatching allows to set automatic prefix matching. Automatic prefix matching can be a dangerous thing
+// to automatically enable in CLI tools.
 // Set this to true to enable it.
 var EnablePrefixMatching = false
 
diff --git a/command.go b/command.go
index 9ae9836..3ee1a0a 100644
--- a/command.go
+++ b/command.go
@@ -109,10 +109,11 @@ type Command struct {
 
 	flagErrorBuf *bytes.Buffer
 
-	args          []string                 // actual args parsed from flags
-	output        *io.Writer               // out writer if set in SetOutput(w)
-	usageFunc     func(*Command) error     // Usage can be defined by application
-	usageTemplate string                   // Can be defined by Application
+	args          []string             // actual args parsed from flags
+	output        *io.Writer           // out writer if set in SetOutput(w)
+	usageFunc     func(*Command) error // Usage can be defined by application
+	usageTemplate string               // Can be defined by Application
+	flagErrorFunc func(*Command, error) error
 	helpTemplate  string                   // Can be defined by Application
 	helpFunc      func(*Command, []string) // Help can be defined by application
 	helpCommand   *Command                 // The help command
@@ -128,7 +129,7 @@ type Command struct {
 	DisableFlagParsing bool
 }
 
-// os.Args[1:] by default, if desired, can be overridden
+// SetArgs sets arguments for the command. It is set to os.Args[1:] by default, if desired, can be overridden
 // particularly useful when testing.
 func (c *Command) SetArgs(a []string) {
 	c.args = a
@@ -140,26 +141,33 @@ func (c *Command) SetOutput(output io.Writer) {
 	c.output = &output
 }
 
-// Usage can be defined by application.
+// SetUsageFunc sets usage function. Usage can be defined by application.
 func (c *Command) SetUsageFunc(f func(*Command) error) {
 	c.usageFunc = f
 }
 
-// Can be defined by Application.
+// SetUsageTemplate sets usage template. Can be defined by Application.
 func (c *Command) SetUsageTemplate(s string) {
 	c.usageTemplate = s
 }
 
-// Can be defined by Application.
+// SetFlagErrorFunc sets a function to generate an error when flag parsing
+// fails
+func (c *Command) SetFlagErrorFunc(f func(*Command, error) error) {
+	c.flagErrorFunc = f
+}
+
+// SetHelpFunc sets help function. Can be defined by Application
 func (c *Command) SetHelpFunc(f func(*Command, []string)) {
 	c.helpFunc = f
 }
 
+// SetHelpCommand sets help command.
 func (c *Command) SetHelpCommand(cmd *Command) {
 	c.helpCommand = cmd
 }
 
-// Can be defined by Application.
+// SetHelpTemplate sets help template to be used. Application can use it to set custom template.
 func (c *Command) SetHelpTemplate(s string) {
 	c.helpTemplate = s
 }
@@ -176,10 +184,12 @@ func (c *Command) SetGlobalNormalizationFunc(n func(f *flag.FlagSet, name string
 	}
 }
 
+// OutOrStdout returns output to stdout
 func (c *Command) OutOrStdout() io.Writer {
 	return c.getOut(os.Stdout)
 }
 
+// OutOrStderr returns output to stderr
 func (c *Command) OutOrStderr() io.Writer {
 	return c.getOut(os.Stderr)
 }
@@ -224,12 +234,8 @@ func (c *Command) Usage() error {
 // HelpFunc returns either the function set by SetHelpFunc for this command
 // or a parent, or it returns a function with default help behavior.
 func (c *Command) HelpFunc() func(*Command, []string) {
-	cmd := c
-	for cmd != nil {
-		if cmd.helpFunc != nil {
-			return cmd.helpFunc
-		}
-		cmd = cmd.parent
+	if helpFunc := c.checkHelpFunc(); helpFunc != nil {
+		return helpFunc
 	}
 	return func(*Command, []string) {
 		c.mergePersistentFlags()
@@ -240,6 +246,20 @@ func (c *Command) HelpFunc() func(*Command, []string) {
 	}
 }
 
+// checkHelpFunc checks if there is helpFunc in ancestors of c.
+func (c *Command) checkHelpFunc() func(*Command, []string) {
+	if c == nil {
+		return nil
+	}
+	if c.helpFunc != nil {
+		return c.helpFunc
+	}
+	if c.HasParent() {
+		return c.parent.checkHelpFunc()
+	}
+	return nil
+}
+
 // Help puts out the help for the command.
 // Used when a user calls help [command].
 // Can be defined by user by overriding HelpFunc.
@@ -248,6 +268,7 @@ func (c *Command) Help() error {
 	return nil
 }
 
+// UsageString return usage string.
 func (c *Command) UsageString() string {
 	tmpOutput := c.output
 	bb := new(bytes.Buffer)
@@ -257,8 +278,25 @@ func (c *Command) UsageString() string {
 	return bb.String()
 }
 
+// FlagErrorFunc returns either the function set by SetFlagErrorFunc for this
+// command or a parent, or it returns a function which returns the original
+// error.
+func (c *Command) FlagErrorFunc() (f func(*Command, error) error) {
+	if c.flagErrorFunc != nil {
+		return c.flagErrorFunc
+	}
+
+	if c.HasParent() {
+		return c.parent.FlagErrorFunc()
+	}
+	return func(c *Command, err error) error {
+		return err
+	}
+}
+
 var minUsagePadding = 25
 
+// UsagePadding return padding for the usage.
 func (c *Command) UsagePadding() int {
 	if c.parent == nil || minUsagePadding > c.parent.commandsMaxUseLen {
 		return minUsagePadding
@@ -268,7 +306,7 @@ func (c *Command) UsagePadding() int {
 
 var minCommandPathPadding = 11
 
-//
+// CommandPathPadding return padding for the command path.
 func (c *Command) CommandPathPadding() int {
 	if c.parent == nil || minCommandPathPadding > c.parent.commandsMaxCommandPathLen {
 		return minCommandPathPadding
@@ -278,6 +316,7 @@ func (c *Command) CommandPathPadding() int {
 
 var minNamePadding = 11
 
+// NamePadding returns padding for the name.
 func (c *Command) NamePadding() int {
 	if c.parent == nil || minNamePadding > c.parent.commandsMaxNameLen {
 		return minNamePadding
@@ -285,6 +324,7 @@ func (c *Command) NamePadding() int {
 	return c.parent.commandsMaxNameLen
 }
 
+// UsageTemplate returns usage template for the command.
 func (c *Command) UsageTemplate() string {
 	if c.usageTemplate != "" {
 		return c.usageTemplate
@@ -320,6 +360,7 @@ Use "{{.CommandPath}} [command] --help" for more information about a command.{{e
 `
 }
 
+// HelpTemplate return help template for the command.
 func (c *Command) HelpTemplate() string {
 	if c.helpTemplate != "" {
 		return c.helpTemplate
@@ -385,7 +426,7 @@ func stripFlags(args []string, c *Command) []string {
 			case inFlag:
 				inFlag = false
 			case y == "":
-				// strip empty commands, as the go tests expect this to be ok....
+			// strip empty commands, as the go tests expect this to be ok....
 			case !strings.HasPrefix(y, "-"):
 				commands = append(commands, y)
 				inFlag = false
@@ -414,7 +455,7 @@ func argsMinusFirstX(args []string, x string) []string {
 	return args
 }
 
-// find the target command given the args and command tree
+// Find finds the target command given the args and command tree
 // Meant to be run on the highest node. Only searches down.
 func (c *Command) Find(args []string) (*Command, []string, error) {
 	if c == nil {
@@ -482,6 +523,7 @@ func (c *Command) Find(args []string) (*Command, []string, error) {
 	return commandFound, a, nil
 }
 
+// SuggestionsFor provides suggestions for the typedName.
 func (c *Command) SuggestionsFor(typedName string) []string {
 	suggestions := []string{}
 	for _, cmd := range c.commands {
@@ -502,6 +544,7 @@ func (c *Command) SuggestionsFor(typedName string) []string {
 	return suggestions
 }
 
+// VisitParents visits all parents of the command and invokes fn on each parent.
 func (c *Command) VisitParents(fn func(*Command)) {
 	var traverse func(*Command) *Command
 
@@ -517,6 +560,7 @@ func (c *Command) VisitParents(fn func(*Command)) {
 	traverse(c)
 }
 
+// Root finds root command.
 func (c *Command) Root() *Command {
 	var findRoot func(*Command) *Command
 
@@ -553,7 +597,7 @@ func (c *Command) execute(a []string) (err error) {
 
 	err = c.ParseFlags(a)
 	if err != nil {
-		return err
+		return c.FlagErrorFunc()(c, err)
 	}
 	// If help is called, regardless of other flags, return we want help
 	// Also say we need help if the command isn't runnable.
@@ -641,7 +685,7 @@ func (c *Command) errorMsgFromParse() string {
 	return ""
 }
 
-// Call execute to use the args (os.Args[1:] by default)
+// Execute Call execute to use the args (os.Args[1:] by default)
 // and run through the command tree finding appropriate matches
 // for commands and then corresponding flags.
 func (c *Command) Execute() error {
@@ -649,6 +693,7 @@ func (c *Command) Execute() error {
 	return err
 }
 
+// ExecuteC executes the command.
 func (c *Command) ExecuteC() (cmd *Command, err error) {
 
 	// Regardless of what command execute is called on, run on Root only
@@ -712,6 +757,7 @@ func (c *Command) ExecuteC() (cmd *Command, err error) {
 }
 
 func (c *Command) initHelpFlag() {
+	c.mergePersistentFlags()
 	if c.Flags().Lookup("help") == nil {
 		c.Flags().BoolP("help", "h", false, "help for "+c.Name())
 	}
@@ -745,7 +791,7 @@ func (c *Command) initHelpCmd() {
 	c.AddCommand(c.helpCommand)
 }
 
-// Used for testing.
+// ResetCommands used for testing.
 func (c *Command) ResetCommands() {
 	c.commands = nil
 	c.helpCommand = nil
@@ -868,7 +914,7 @@ func (c *Command) UseLine() string {
 	return str + c.Use
 }
 
-// For use in determining which flags have been assigned to which commands
+// DebugFlags used to determine which flags have been assigned to which commands
 // and which persist.
 func (c *Command) DebugFlags() {
 	c.Println("DebugFlags called on", c.Name())
@@ -936,10 +982,12 @@ func (c *Command) HasAlias(s string) bool {
 	return false
 }
 
+// NameAndAliases returns string containing name and all aliases
 func (c *Command) NameAndAliases() string {
 	return strings.Join(append([]string{c.Name()}, c.Aliases...), ", ")
 }
 
+// HasExample determines if the command has example.
 func (c *Command) HasExample() bool {
 	return len(c.Example) > 0
 }
@@ -1036,7 +1084,7 @@ func (c *Command) GlobalNormalizationFunc() func(f *flag.FlagSet, name string) f
 	return c.globNormFunc
 }
 
-// Flage returns the complete FlagSet that applies
+// Flags returns 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 {
@@ -1136,44 +1184,44 @@ func (c *Command) ResetFlags() {
 	c.pflags.SetOutput(c.flagErrorBuf)
 }
 
-// Does the command contain any flags (local plus persistent from the entire structure).
+// HasFlags checks if the command contains any flags (local plus persistent from the entire structure).
 func (c *Command) HasFlags() bool {
 	return c.Flags().HasFlags()
 }
 
-// Does the command contain persistent flags.
+// HasPersistentFlags checks if the command contains persistent flags.
 func (c *Command) HasPersistentFlags() bool {
 	return c.PersistentFlags().HasFlags()
 }
 
-// Does the command has flags specifically declared locally.
+// HasLocalFlags checks if the command has flags specifically declared locally.
 func (c *Command) HasLocalFlags() bool {
 	return c.LocalFlags().HasFlags()
 }
 
-// Does the command have flags inherited from its parent command.
+// HasInheritedFlags checks if the command has flags inherited from its parent command.
 func (c *Command) HasInheritedFlags() bool {
 	return c.InheritedFlags().HasFlags()
 }
 
-// Does the command contain any flags (local plus persistent from the entire
+// HasAvailableFlags checks if the command contains any flags (local plus persistent from the entire
 // structure) which are not hidden or deprecated.
 func (c *Command) HasAvailableFlags() bool {
 	return c.Flags().HasAvailableFlags()
 }
 
-// Does the command contain persistent flags which are not hidden or deprecated.
+// HasAvailablePersistentFlags checks if the command contains persistent flags which are not hidden or deprecated.
 func (c *Command) HasAvailablePersistentFlags() bool {
 	return c.PersistentFlags().HasAvailableFlags()
 }
 
-// Does the command has flags specifically declared locally which are not hidden
+// HasAvailableLocalFlags checks if the command has flags specifically declared locally which are not hidden
 // or deprecated.
 func (c *Command) HasAvailableLocalFlags() bool {
 	return c.LocalFlags().HasAvailableFlags()
 }
 
-// Does the command have flags inherited from its parent command which are
+// HasAvailableInheritedFlags checks if the command has flags inherited from its parent command which are
 // not hidden or deprecated.
 func (c *Command) HasAvailableInheritedFlags() bool {
 	return c.InheritedFlags().HasAvailableFlags()
diff --git a/doc/man_docs.go b/doc/man_docs.go
index 5798d0f..fd7107c 100644
--- a/doc/man_docs.go
+++ b/doc/man_docs.go
@@ -37,7 +37,7 @@ func GenManTree(cmd *cobra.Command, header *GenManHeader, dir string) error {
 	return GenManTreeFromOpts(cmd, GenManTreeOptions{
 		Header:           header,
 		Path:             dir,
-		CommandSeparator: "_",
+		CommandSeparator: "-",
 	})
 }
 
diff --git a/doc/man_docs.md b/doc/man_docs.md
index 5fe957a..d568d9a 100644
--- a/doc/man_docs.md
+++ b/doc/man_docs.md
@@ -15,7 +15,7 @@ func main() {
 		Use:   "test",
 		Short: "my test program",
 	}
-	header := &cobra.GenManHeader{
+	header := &doc.GenManHeader{
 		Title: "MINE",
 		Section: "3",
 	}
@@ -23,4 +23,4 @@ func main() {
 }
 ```
 
-That will get you a man page `/tmp/test.1`
+That will get you a man page `/tmp/test.3`
diff --git a/doc/md_docs.md b/doc/md_docs.md
index 0c3b96e..480b152 100644
--- a/doc/md_docs.md
+++ b/doc/md_docs.md
@@ -101,4 +101,3 @@ linkHandler := func(name string) string {
 	return "/commands/" + strings.ToLower(base) + "/"
 }
 ```
-


Test patch:
diff --git a/cobra_test.go b/cobra_test.go
index 699a2f6..46887fd 100644
--- a/cobra_test.go
+++ b/cobra_test.go
@@ -612,7 +612,7 @@ func TestSubcommandExecuteC(t *testing.T) {
 		Use: "echo message",
 		Run: func(c *Command, args []string) {
 			msg := strings.Join(args, " ")
-			c.Println(msg, msg)
+			c.Println(msg)
 		},
 	}
 
diff --git a/command_test.go b/command_test.go
index b0c17e2..7947f6c 100644
--- a/command_test.go
+++ b/command_test.go
@@ -1,6 +1,8 @@
 package cobra
 
 import (
+	"bytes"
+	"fmt"
 	"os"
 	"reflect"
 	"testing"
@@ -134,6 +136,20 @@ func Test_DisableFlagParsing(t *testing.T) {
 	}
 }
 
+func TestInitHelpFlagMergesFlags(t *testing.T) {
+	usage := "custom flag"
+	baseCmd := Command{Use: "testcmd"}
+	baseCmd.PersistentFlags().Bool("help", false, usage)
+	cmd := Command{Use: "do"}
+	baseCmd.AddCommand(&cmd)
+
+	cmd.initHelpFlag()
+	actual := cmd.Flags().Lookup("help").Usage
+	if actual != usage {
+		t.Fatalf("Expected the help flag from the base command with usage '%s', but got the default with usage '%s'", usage, actual)
+	}
+}
+
 func TestCommandsAreSorted(t *testing.T) {
 	EnableCommandSorting = true
 
@@ -174,3 +190,27 @@ func TestEnableCommandSortingIsDisabled(t *testing.T) {
 
 	EnableCommandSorting = true
 }
+
+func TestFlagErrorFunc(t *testing.T) {
+
+	cmd := &Command{
+		Use: "print",
+		RunE: func(cmd *Command, args []string) error {
+			return nil
+		},
+	}
+	expectedFmt := "This is expected: %s"
+
+	cmd.SetFlagErrorFunc(func(c *Command, err error) error {
+		return fmt.Errorf(expectedFmt, err)
+	})
+	cmd.SetArgs([]string{"--bogus-flag"})
+	cmd.SetOutput(new(bytes.Buffer))
+
+	err := cmd.Execute()
+
+	expected := fmt.Sprintf(expectedFmt, "unknown flag: --bogus-flag")
+	if err.Error() != expected {
+		t.Errorf("expected %v, got %v", expected, err.Error())
+	}
+}