From a8c0208903647e74d99f4b7c49f46b88e629f4ac Mon Sep 17 00:00:00 2001 From: Jason Shepherd Date: Tue, 31 Mar 2015 17:11:03 +1000 Subject: [PATCH 1/2] adding nicer help when missing arguments (#11858) Signed-off-by: Jason Shepherd --- mflag/flag.go | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/mflag/flag.go b/mflag/flag.go index ce003cd..2cead9e 100644 --- a/mflag/flag.go +++ b/mflag/flag.go @@ -289,7 +289,8 @@ type FlagSet struct { // Usage is the function called when an error occurs while parsing flags. // The field is a function (not a method) that may be changed to point to // a custom error handler. - Usage func() + Usage func() + ShortUsage func() name string parsed bool @@ -564,6 +565,12 @@ var Usage = func() { PrintDefaults() } +// Usage prints to standard error a usage message documenting the standard command layout +// The function is a variable that may be changed to point to a custom function. +var ShortUsage = func() { + fmt.Fprintf(CommandLine.output, "Usage of %s:\n", os.Args[0]) +} + // FlagCount returns the number of flags that have been defined. func (f *FlagSet) FlagCount() int { return len(sortFlags(f.formal)) } @@ -1073,6 +1080,8 @@ func (cmd *FlagSet) ParseFlags(args []string, withHelp bool) error { } if str := cmd.CheckArgs(); str != "" { cmd.ReportError(str, withHelp) + cmd.ShortUsage() + os.Exit(1) } return nil } @@ -1085,8 +1094,7 @@ func (cmd *FlagSet) ReportError(str string, withHelp bool) { str += ". See '" + os.Args[0] + " " + cmd.Name() + " --help'" } } - fmt.Fprintf(cmd.Out(), "docker: %s\n", str) - os.Exit(1) + fmt.Fprintf(cmd.Out(), "docker: %s.\n", str) } // Parsed reports whether f.Parse has been called. From ef185a9afc96ac027f5ff0928f819ac56691f22a Mon Sep 17 00:00:00 2001 From: Doug Davis Date: Sat, 23 May 2015 08:57:50 -0700 Subject: [PATCH 2/2] Carry #11858 Continues 11858 by: - Making sure the exit code is always zero when we ask for help - Making sure the exit code isn't zero when we print help on error cases - Making sure both short and long usage go to the same stream (stdout vs stderr) - Making sure all docker commands support --help - Test that all cmds send --help to stdout, exit code 0, show full usage, no blank lines at end - Test that all cmds (that support it) show short usage on bad arg to stderr, no blank line at end - Test that all cmds complain about a bad option, no blank line at end - Test that docker (w/o subcmd) does the same stuff mentioned above properly Signed-off-by: Doug Davis --- mflag/flag.go | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/mflag/flag.go b/mflag/flag.go index 2cead9e..9626a2f 100644 --- a/mflag/flag.go +++ b/mflag/flag.go @@ -512,6 +512,12 @@ func (f *FlagSet) PrintDefaults() { if runtime.GOOS != "windows" && home == "/" { home = "" } + + // Add a blank line between cmd description and list of options + if f.FlagCount() > 0 { + fmt.Fprintln(writer, "") + } + f.VisitAll(func(flag *Flag) { format := " -%s=%s" names := []string{} @@ -1074,11 +1080,12 @@ func (cmd *FlagSet) ParseFlags(args []string, withHelp bool) error { return err } if help != nil && *help { + cmd.SetOutput(os.Stdout) cmd.Usage() - // just in case Usage does not exit os.Exit(0) } if str := cmd.CheckArgs(); str != "" { + cmd.SetOutput(os.Stderr) cmd.ReportError(str, withHelp) cmd.ShortUsage() os.Exit(1) @@ -1089,9 +1096,9 @@ func (cmd *FlagSet) ParseFlags(args []string, withHelp bool) error { func (cmd *FlagSet) ReportError(str string, withHelp bool) { if withHelp { if os.Args[0] == cmd.Name() { - str += ". See '" + os.Args[0] + " --help'" + str += ".\nSee '" + os.Args[0] + " --help'" } else { - str += ". See '" + os.Args[0] + " " + cmd.Name() + " --help'" + str += ".\nSee '" + os.Args[0] + " " + cmd.Name() + " --help'" } } fmt.Fprintf(cmd.Out(), "docker: %s.\n", str)