]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/go: add -args to 'go test' to resolve -v ambiguity
authorRuss Cox <rsc@golang.org>
Mon, 14 Dec 2015 16:04:03 +0000 (11:04 -0500)
committerRuss Cox <rsc@golang.org>
Thu, 17 Dec 2015 01:59:58 +0000 (01:59 +0000)
The new flag -args stops flag processing, leaving the rest of the command line
to be passed to the underlying test binary verbatim. Thus, both of these pass
a literal -v -n on the test binary command line, without putting the go command
into verbose mode or disabling execution of commands:

go test . -args -v -n
go test -args -v -n

Also try to make the documentation a bit clearer.

Fixes #7221.
Fixes #12177.

Change-Id: Ief9e830a6fbb9475d96011716a86e2524a35eceb
Reviewed-on: https://go-review.googlesource.com/17775
Reviewed-by: Rob Pike <r@golang.org>
src/cmd/go/alldocs.go
src/cmd/go/go_test.go
src/cmd/go/test.go
src/cmd/go/testflag.go

index ecacf6d3dca440fcd583100d5bfc00158230566a..8053b862d1a21cf7b50a537b0b608941f5c0670b 100644 (file)
@@ -660,7 +660,7 @@ Test packages
 
 Usage:
 
-       go test [-c] [-i] [build and test flags] [packages] [flags for test binary]
+       go test [build/test flags] [packages] [build/test flags & test binary flags]
 
 'Go test' automates testing the packages named by the import paths.
 It prints a summary of the test results in the format:
@@ -690,10 +690,16 @@ non-test installation.
 
 In addition to the build flags, the flags handled by 'go test' itself are:
 
+       -args
+           Pass the remainder of the command line (everything after -args)
+           to the test binary, uninterpreted and unchanged.
+           Because this flag consumes the remainder of the command line,
+           the package list (if present) must appear before this flag.
+
        -c
-               Compile the test binary to pkg.test but do not run it
-               (where pkg is the last element of the package's import path).
-               The file name can be changed with the -o flag.
+           Compile the test binary to pkg.test but do not run it
+           (where pkg is the last element of the package's import path).
+           The file name can be changed with the -o flag.
 
        -exec xprog
            Run the test binary using xprog. The behavior is the same as
@@ -704,17 +710,12 @@ In addition to the build flags, the flags handled by 'go test' itself are:
            Do not run the test.
 
        -o file
-               Compile the test binary to the named file.
-               The test still runs (unless -c or -i is specified).
+           Compile the test binary to the named file.
+           The test still runs (unless -c or -i is specified).
 
 The test binary also accepts flags that control execution of the test; these
 flags are also accessible by 'go test'. See 'go help testflag' for details.
 
-If the test binary needs any other flags, they should be presented after the
-package names. The go tool treats as a flag the first argument that begins with
-a minus sign that it does not recognize itself; that argument and all subsequent
-arguments are passed as arguments to the test binary.
-
 For more about build flags, see 'go help build'.
 For more about specifying packages, see 'go help packages'.
 
@@ -1442,25 +1443,58 @@ control the execution of any test:
            Verbose output: log all tests as they are run. Also print all
            text from Log and Logf calls even if the test succeeds.
 
-The test binary, called pkg.test where pkg is the name of the
-directory containing the package sources, can be invoked directly
-after building it with 'go test -c'. When invoking the test binary
-directly, each of the standard flag names must be prefixed with 'test.',
-as in -test.run=TestMyFunc or -test.v.
+Each of these flags is also recognized with an optional 'test.' prefix,
+as in -test.v. When invoking the generated test binary (the result of
+'go test -c') directly, however, the prefix is mandatory.
 
-When running 'go test', flags not listed above are passed through
-unaltered. For instance, the command
+The 'go test' command rewrites or removes recognized flags,
+as appropriate, both before and after the optional package list,
+before invoking the test binary.
 
-       go test -x -v -cpuprofile=prof.out -dir=testdata -update
+For instance, the command
+
+       go test -v -myflag testdata -cpuprofile=prof.out -x
 
 will compile the test binary and then run it as
 
-       pkg.test -test.v -test.cpuprofile=prof.out -dir=testdata -update
+       pkg.test -test.v -myflag testdata -test.cpuprofile=prof.out
+
+(The -x flag is removed because it applies only to the go command's
+execution, not to the test itself.)
 
 The test flags that generate profiles (other than for coverage) also
 leave the test binary in pkg.test for use when analyzing the profiles.
 
-Flags not recognized by 'go test' must be placed after any specified packages.
+The command-line package list, if present, must appear before any
+flag not known to the go test command. Continuing the example above,
+the package list would have to appear before -myflag, but could appear
+on either side of -v.
+
+To keep an argument for a test binary from being interpreted as a
+known flag or a package name, use -args (see 'go help test') which
+passes the remainder of the command line through to the test binary
+uninterpreted and unaltered.
+
+For instance, the command
+
+       go test -v -args -x -v
+
+will compile the test binary and then run it as
+
+       pkg.test -test.v -x -v
+
+Similarly,
+
+       go test -args math
+
+will compile the test binary and then run it as
+
+       pkg.test math
+
+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.
+In the second example, the argument math is passed through to the test
+binary, instead of being interpreted as the package list.
 
 
 Description of testing functions
index 735c935b575f044be325d44b61b70f52618ee98d..167b6c2fc2eb29125ca8b2e157e74355508ba9e3 100644 (file)
@@ -1983,6 +1983,13 @@ func TestGoTestFooTestWorks(t *testing.T) {
        tg.run("test", "testdata/standalone_test.go")
 }
 
+func TestGoTestFlagsAfterPackage(t *testing.T) {
+       tg := testgo(t)
+       defer tg.cleanup()
+       tg.run("test", "testdata/flag_test.go", "-v", "-args", "-v=7") // Two distinct -v flags.
+       tg.run("test", "-v", "testdata/flag_test.go", "-args", "-v=7") // Two distinct -v flags.
+}
+
 func TestGoTestXtestonlyWorks(t *testing.T) {
        tg := testgo(t)
        defer tg.cleanup()
index ccbe4ac1e9ae618c29533ecb78c5b52cf2ddc129..acca304dfeb69a7759eb168d9aa8af55198e2439 100644 (file)
@@ -32,7 +32,7 @@ func init() {
        cmdTest.Run = runTest
 }
 
-const testUsage = "test [-c] [-i] [build and test flags] [packages] [flags for test binary]"
+const testUsage = "test [build/test flags] [packages] [build/test flags & test binary flags]"
 
 var cmdTest = &Command{
        CustomFlags: true,
@@ -67,11 +67,6 @@ non-test installation.
 
 ` + strings.TrimSpace(testFlag1) + ` See 'go help testflag' for details.
 
-If the test binary needs any other flags, they should be presented after the
-package names. The go tool treats as a flag the first argument that begins with
-a minus sign that it does not recognize itself; that argument and all subsequent
-arguments are passed as arguments to the test binary.
-
 For more about build flags, see 'go help build'.
 For more about specifying packages, see 'go help packages'.
 
@@ -82,10 +77,16 @@ See also: go build, go vet.
 const testFlag1 = `
 In addition to the build flags, the flags handled by 'go test' itself are:
 
+       -args
+           Pass the remainder of the command line (everything after -args)
+           to the test binary, uninterpreted and unchanged.
+           Because this flag consumes the remainder of the command line,
+           the package list (if present) must appear before this flag.
+
        -c
-               Compile the test binary to pkg.test but do not run it
-               (where pkg is the last element of the package's import path).
-               The file name can be changed with the -o flag.
+           Compile the test binary to pkg.test but do not run it
+           (where pkg is the last element of the package's import path).
+           The file name can be changed with the -o flag.
 
        -exec xprog
            Run the test binary using xprog. The behavior is the same as
@@ -96,8 +97,8 @@ In addition to the build flags, the flags handled by 'go test' itself are:
            Do not run the test.
 
        -o file
-               Compile the test binary to the named file.
-               The test still runs (unless -c or -i is specified).
+           Compile the test binary to the named file.
+           The test still runs (unless -c or -i is specified).
 
 The test binary also accepts flags that control execution of the test; these
 flags are also accessible by 'go test'.
@@ -229,25 +230,58 @@ const testFlag2 = `
            Verbose output: log all tests as they are run. Also print all
            text from Log and Logf calls even if the test succeeds.
 
-The test binary, called pkg.test where pkg is the name of the
-directory containing the package sources, can be invoked directly
-after building it with 'go test -c'. When invoking the test binary
-directly, each of the standard flag names must be prefixed with 'test.',
-as in -test.run=TestMyFunc or -test.v.
+Each of these flags is also recognized with an optional 'test.' prefix,
+as in -test.v. When invoking the generated test binary (the result of
+'go test -c') directly, however, the prefix is mandatory.
 
-When running 'go test', flags not listed above are passed through
-unaltered. For instance, the command
+The 'go test' command rewrites or removes recognized flags,
+as appropriate, both before and after the optional package list,
+before invoking the test binary.
 
-       go test -x -v -cpuprofile=prof.out -dir=testdata -update
+For instance, the command
+
+       go test -v -myflag testdata -cpuprofile=prof.out -x
 
 will compile the test binary and then run it as
 
-       pkg.test -test.v -test.cpuprofile=prof.out -dir=testdata -update
+       pkg.test -test.v -myflag testdata -test.cpuprofile=prof.out
+
+(The -x flag is removed because it applies only to the go command's
+execution, not to the test itself.)
 
 The test flags that generate profiles (other than for coverage) also
 leave the test binary in pkg.test for use when analyzing the profiles.
 
-Flags not recognized by 'go test' must be placed after any specified packages.
+The command-line package list, if present, must appear before any
+flag not known to the go test command. Continuing the example above,
+the package list would have to appear before -myflag, but could appear
+on either side of -v.
+
+To keep an argument for a test binary from being interpreted as a
+known flag or a package name, use -args (see 'go help test') which
+passes the remainder of the command line through to the test binary
+uninterpreted and unaltered.
+
+For instance, the command
+
+       go test -v -args -x -v
+
+will compile the test binary and then run it as
+
+       pkg.test -test.v -x -v
+
+Similarly,
+
+       go test -args math
+
+will compile the test binary and then run it as
+
+       pkg.test math
+
+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.
+In the second example, the argument math is passed through to the test
+binary, instead of being interpreted as the package list.
 `
 
 var helpTestfunc = &Command{
index 1f3e3d316af5a8794e8746e6617d9a943a5fc3a3..873df1ffc36ce7434f2022fb35bfa6d4e1371e3c 100644 (file)
@@ -87,6 +87,7 @@ func init() {
 func testFlags(args []string) (packageNames, passToTest []string) {
        inPkg := false
        outputDir := ""
+       var explicitArgs []string
        for i := 0; i < len(args); i++ {
                if !strings.HasPrefix(args[i], "-") {
                        if !inPkg && packageNames == nil {
@@ -114,6 +115,12 @@ func testFlags(args []string) (packageNames, passToTest []string) {
                                // make non-nil: we have seen the empty package list
                                packageNames = []string{}
                        }
+                       if args[i] == "-args" || args[i] == "--args" {
+                               // -args or --args signals that everything that follows
+                               // should be passed to the test.
+                               explicitArgs = args[i+1:]
+                               break
+                       }
                        passToTest = append(passToTest, args[i])
                        continue
                }
@@ -191,6 +198,8 @@ func testFlags(args []string) (packageNames, passToTest []string) {
                }
                passToTest = append(passToTest, "-test.outputdir", dir)
        }
+
+       passToTest = append(passToTest, explicitArgs...)
        return
 }