Skip to content

Commit

Permalink
flag: make default Usage prefer CommandLine's output over just os.Stderr
Browse files Browse the repository at this point in the history
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 <[email protected]>
TryBot-Result: Gobot Gobot <[email protected]>
Reviewed-by: Rob Pike <[email protected]>
  • Loading branch information
bradfitz committed Aug 8, 2017
1 parent 5791203 commit e1f38cc
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 2 deletions.
2 changes: 2 additions & 0 deletions src/flag/export_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
5 changes: 3 additions & 2 deletions src/flag/flag.go
Original file line number Diff line number Diff line change
Expand Up @@ -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()
}

Expand Down
14 changes: 14 additions & 0 deletions src/flag/flag_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
}

0 comments on commit e1f38cc

Please sign in to comment.