Commit ca33f33b authored by Daniel Martí's avatar Daniel Martí

cmd/go: make 'go test -h' print two lines

Like every other command's -h flag. To achieve this, pass the command's
usage function to the cmdflag package, since that package is used by
multiple commands and cannot directly access *base.Command.

This also lets us get rid of testFlag1 and testFlag2, and instead have
contiguous raw strings for the test and testflag help docs.

Fixes #26999.

Change-Id: I2ebd66835ee61fa83270816a01fa312425224bb3
Reviewed-on: https://go-review.googlesource.com/c/144558
Run-TryBot: Daniel Martí <mvdan@mvdan.cc>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarAlan Donovan <adonovan@google.com>
parent 9c772522
...@@ -79,15 +79,15 @@ func AddKnownFlags(cmd string, defns []*Defn) { ...@@ -79,15 +79,15 @@ func AddKnownFlags(cmd string, defns []*Defn) {
// Parse sees if argument i is present in the definitions and if so, // Parse sees if argument i is present in the definitions and if so,
// returns its definition, value, and whether it consumed an extra word. // returns its definition, value, and whether it consumed an extra word.
// If the flag begins (cmd+".") it is ignored for the purpose of this function. // If the flag begins (cmd.Name()+".") it is ignored for the purpose of this function.
func Parse(cmd string, defns []*Defn, args []string, i int) (f *Defn, value string, extra bool) { func Parse(cmd string, usage func(), defns []*Defn, args []string, i int) (f *Defn, value string, extra bool) {
arg := args[i] arg := args[i]
if strings.HasPrefix(arg, "--") { // reduce two minuses to one if strings.HasPrefix(arg, "--") { // reduce two minuses to one
arg = arg[1:] arg = arg[1:]
} }
switch arg { switch arg {
case "-?", "-h", "-help": case "-?", "-h", "-help":
base.Usage() usage()
} }
if arg == "" || arg[0] != '-' { if arg == "" || arg[0] != '-' {
return return
......
...@@ -124,16 +124,6 @@ A cached test result is treated as executing in no time at all, ...@@ -124,16 +124,6 @@ A cached test result is treated as executing in no time at all,
so a successful package test result will be cached and reused so a successful package test result will be cached and reused
regardless of -timeout setting. regardless of -timeout setting.
` + strings.TrimSpace(testFlag1) + ` See 'go help testflag' for details.
For more about build flags, see 'go help build'.
For more about specifying packages, see 'go help packages'.
See also: go build, go vet.
`,
}
const testFlag1 = `
In addition to the build flags, the flags handled by 'go test' itself are: In addition to the build flags, the flags handled by 'go test' itself are:
-args -args
...@@ -164,15 +154,13 @@ In addition to the build flags, the flags handled by 'go test' itself are: ...@@ -164,15 +154,13 @@ In addition to the build flags, the flags handled by 'go test' itself are:
The test still runs (unless -c or -i is specified). The test still runs (unless -c or -i is specified).
The test binary also accepts flags that control execution of the test; these The test binary also accepts flags that control execution of the test; these
flags are also accessible by 'go test'. flags are also accessible by 'go test'. See 'go help testflag' for details.
`
For more about build flags, see 'go help build'.
// Usage prints the usage message for 'go test -h' and exits. For more about specifying packages, see 'go help packages'.
func Usage() {
os.Stderr.WriteString("usage: " + testUsage + "\n\n" + See also: go build, go vet.
strings.TrimSpace(testFlag1) + "\n\n\t" + `,
strings.TrimSpace(testFlag2) + "\n")
os.Exit(2)
} }
var HelpTestflag = &base.Command{ var HelpTestflag = &base.Command{
...@@ -190,11 +178,6 @@ options of pprof control how the information is presented. ...@@ -190,11 +178,6 @@ options of pprof control how the information is presented.
The following flags are recognized by the 'go test' command and The following flags are recognized by the 'go test' command and
control the execution of any test: control the execution of any test:
` + strings.TrimSpace(testFlag2) + `
`,
}
const testFlag2 = `
-bench regexp -bench regexp
Run only those benchmarks matching a regular expression. Run only those benchmarks matching a regular expression.
By default, no benchmarks are run. By default, no benchmarks are run.
...@@ -414,7 +397,8 @@ In the first example, the -x and the second -v are passed through to the ...@@ -414,7 +397,8 @@ In the first example, the -x and the second -v are passed through to the
test binary unchanged and with no effect on the go command itself. test binary unchanged and with no effect on the go command itself.
In the second example, the argument math is passed through to the test In the second example, the argument math is passed through to the test
binary, instead of being interpreted as the package list. binary, instead of being interpreted as the package list.
` `,
}
var HelpTestfunc = &base.Command{ var HelpTestfunc = &base.Command{
UsageLine: "testfunc", UsageLine: "testfunc",
...@@ -532,7 +516,7 @@ var testVetFlags = []string{ ...@@ -532,7 +516,7 @@ var testVetFlags = []string{
func runTest(cmd *base.Command, args []string) { func runTest(cmd *base.Command, args []string) {
modload.LoadTests = true modload.LoadTests = true
pkgArgs, testArgs = testFlags(args) pkgArgs, testArgs = testFlags(cmd.Usage, args)
work.FindExecCmd() // initialize cached result work.FindExecCmd() // initialize cached result
......
...@@ -87,7 +87,7 @@ func init() { ...@@ -87,7 +87,7 @@ func init() {
// to allow both // to allow both
// go test fmt -custom-flag-for-fmt-test // go test fmt -custom-flag-for-fmt-test
// go test -x math // go test -x math
func testFlags(args []string) (packageNames, passToTest []string) { func testFlags(usage func(), args []string) (packageNames, passToTest []string) {
args = str.StringList(cmdflag.FindGOFLAGS(testFlagDefn), args) args = str.StringList(cmdflag.FindGOFLAGS(testFlagDefn), args)
inPkg := false inPkg := false
var explicitArgs []string var explicitArgs []string
...@@ -108,7 +108,7 @@ func testFlags(args []string) (packageNames, passToTest []string) { ...@@ -108,7 +108,7 @@ func testFlags(args []string) (packageNames, passToTest []string) {
inPkg = false inPkg = false
} }
f, value, extraWord := cmdflag.Parse(cmd, testFlagDefn, args, i) f, value, extraWord := cmdflag.Parse(cmd, usage, testFlagDefn, args, i)
if f == nil { if f == nil {
// This is a flag we do not know; we must assume // This is a flag we do not know; we must assume
// that any args we see after this might be flag // that any args we see after this might be flag
......
...@@ -38,7 +38,7 @@ See also: go fmt, go fix. ...@@ -38,7 +38,7 @@ See also: go fmt, go fix.
func runVet(cmd *base.Command, args []string) { func runVet(cmd *base.Command, args []string) {
modload.LoadTests = true modload.LoadTests = true
vetFlags, pkgArgs := vetFlags(args) vetFlags, pkgArgs := vetFlags(cmd.Usage, args)
work.BuildInit() work.BuildInit()
work.VetFlags = vetFlags work.VetFlags = vetFlags
......
...@@ -40,7 +40,7 @@ var vetTool = os.Getenv("GOVETTOOL") ...@@ -40,7 +40,7 @@ var vetTool = os.Getenv("GOVETTOOL")
// vetFlags processes the command line, splitting it at the first non-flag // vetFlags processes the command line, splitting it at the first non-flag
// into the list of flags and list of packages. // into the list of flags and list of packages.
func vetFlags(args []string) (passToVet, packageNames []string) { func vetFlags(usage func(), args []string) (passToVet, packageNames []string) {
// Query the vet command for its flags. // Query the vet command for its flags.
tool := vetTool tool := vetTool
if tool != "" { if tool != "" {
...@@ -108,7 +108,7 @@ func vetFlags(args []string) (passToVet, packageNames []string) { ...@@ -108,7 +108,7 @@ func vetFlags(args []string) (passToVet, packageNames []string) {
return args[:i], args[i:] return args[:i], args[i:]
} }
f, value, extraWord := cmdflag.Parse("vet", vetFlagDefn, args, i) f, value, extraWord := cmdflag.Parse("vet", usage, vetFlagDefn, args, i)
if f == nil { if f == nil {
fmt.Fprintf(os.Stderr, "vet: flag %q not defined\n", args[i]) fmt.Fprintf(os.Stderr, "vet: flag %q not defined\n", args[i])
fmt.Fprintf(os.Stderr, "Run \"go help vet\" for more information\n") fmt.Fprintf(os.Stderr, "Run \"go help vet\" for more information\n")
......
...@@ -235,17 +235,6 @@ func init() { ...@@ -235,17 +235,6 @@ func init() {
} }
func mainUsage() { func mainUsage() {
// special case "go test -h"
if len(os.Args) > 1 && os.Args[1] == "test" {
test.Usage()
}
// Since vet shares code with test in cmdflag, it doesn't show its
// command usage properly. For now, special case it too.
// TODO(mvdan): fix the cmdflag package instead; see
// golang.org/issue/26999
if len(os.Args) > 1 && os.Args[1] == "vet" {
vet.CmdVet.Usage()
}
help.PrintUsage(os.Stderr, base.Go) help.PrintUsage(os.Stderr, base.Go)
os.Exit(2) os.Exit(2)
} }
...@@ -35,7 +35,13 @@ stderr 'Run ''go help mod'' for usage.' ...@@ -35,7 +35,13 @@ stderr 'Run ''go help mod'' for usage.'
stderr 'usage: go vet' stderr 'usage: go vet'
stderr 'Run ''go help vet'' for details' stderr 'Run ''go help vet'' for details'
# Earlier versions of Go printed a large document here, instead of these two
# lines.
! go test -h
stderr 'usage: go test'
stderr 'Run ''go help test'' for details'
# go help get shows usage for get # go help get shows usage for get
go help get go help get
stdout 'usage: go get' stdout 'usage: go get'
stdout 'get when using GOPATH' stdout 'get when using GOPATH'
\ No newline at end of file
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