Commit e1f38cca authored by Brad Fitzpatrick's avatar Brad Fitzpatrick

flag: make default Usage prefer CommandLine's output over just os.Stderr

CommandLine (exported in Go 1.2) has default output of os.Stderr.

Before it was exported, it made sense to have the global Usage func
(the implicit usage func if CommandLine.Usage is nil) hard-code
os.Stderr has its output. But once CommandLine was exported, Usage
should use it if provided.

Fixes #20998

Change-Id: I9e1c0415a563a982634b9808199c9ee175d72f4c
Reviewed-on: https://go-review.googlesource.com/48390
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarRob Pike <r@golang.org>
parent 57912032
......@@ -8,6 +8,8 @@ import "os"
// Additional routines compiled into the package only during testing.
var DefaultUsage = Usage
// ResetForTesting clears all flag state and sets the usage function as directed.
// After calling ResetForTesting, parse errors in flag handling will not
// exit the program.
......
......@@ -515,13 +515,14 @@ func (f *FlagSet) defaultUsage() {
// because it serves (via godoc flag Usage) as the example
// for how to write your own usage function.
// Usage prints to standard error a usage message documenting all defined command-line flags.
// Usage prints a usage message documenting all defined command-line flags
// to CommandLine's output, which by default is os.Stderr.
// It is called when an error occurs while parsing flags.
// The function is a variable that may be changed to point to a custom function.
// By default it prints a simple header and calls PrintDefaults; for details about the
// format of the output and how to control it, see the documentation for PrintDefaults.
var Usage = func() {
fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0])
fmt.Fprintf(CommandLine.out(), "Usage of %s:\n", os.Args[0])
PrintDefaults()
}
......
......@@ -432,3 +432,17 @@ func TestIntFlagOverflow(t *testing.T) {
t.Error("unexpected success setting Uint")
}
}
// Issue 20998: Usage should respect CommandLine.output.
func TestUsageOutput(t *testing.T) {
ResetForTesting(DefaultUsage)
var buf bytes.Buffer
CommandLine.SetOutput(&buf)
defer func(old []string) { os.Args = old }(os.Args)
os.Args = []string{"app", "-i=1", "-unknown"}
Parse()
const want = "flag provided but not defined: -i\nUsage of app:\n"
if got := buf.String(); got != want {
t.Errorf("output = %q; want %q", got, want)
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment