cmd.Flag.BoolVar(&buildA, "a", false, "")
cmd.Flag.BoolVar(&buildN, "n", false, "")
cmd.Flag.IntVar(&buildP, "p", buildP, "")
- cmd.Flag.StringVar(&buildContext.InstallSuffix, "installsuffix", "", "")
cmd.Flag.BoolVar(&buildV, "v", false, "")
cmd.Flag.BoolVar(&buildX, "x", false, "")
- cmd.Flag.BoolVar(&buildWork, "work", false, "")
cmd.Flag.Var((*stringsFlag)(&buildAsmflags), "asmflags", "")
cmd.Flag.Var((*stringsFlag)(&buildGcflags), "gcflags", "")
cmd.Flag.Var((*stringsFlag)(&buildLdflags), "ldflags", "")
cmd.Flag.Var((*stringsFlag)(&buildGccgoflags), "gccgoflags", "")
- cmd.Flag.Var((*stringsFlag)(&buildContext.BuildTags), "tags", "")
+ cmd.Flag.StringVar(&buildContext.InstallSuffix, "installsuffix", "", "")
cmd.Flag.Var(buildCompiler{}, "compiler", "")
cmd.Flag.BoolVar(&buildRace, "race", false, "")
- cmd.Flag.Var((*stringsFlag)(&buildToolExec), "toolexec", "")
cmd.Flag.StringVar(&buildBuildmode, "buildmode", "default", "")
cmd.Flag.BoolVar(&buildLinkshared, "linkshared", false, "")
+ cmd.Flag.Var((*stringsFlag)(&buildContext.BuildTags), "tags", "")
+ cmd.Flag.Var((*stringsFlag)(&buildToolExec), "toolexec", "")
+ cmd.Flag.BoolVar(&buildWork, "work", false, "")
}
func addBuildFlagsNX(cmd *Command) {
package main
import (
+ "flag"
"fmt"
"os"
"strconv"
type testFlagSpec struct {
name string
boolVar *bool
+ flagValue flag.Value
passToTest bool // pass to Test
multiOK bool // OK to have multiple instances
present bool // flag has been seen
var testFlagDefn = []*testFlagSpec{
// local.
{name: "c", boolVar: &testC},
+ {name: "i", boolVar: &buildI},
+ {name: "o"},
{name: "cover", boolVar: &testCover},
{name: "covermode"},
{name: "coverpkg"},
- {name: "o"},
-
- // build flags.
- {name: "a", boolVar: &buildA},
- {name: "n", boolVar: &buildN},
- {name: "p"},
- {name: "x", boolVar: &buildX},
- {name: "i", boolVar: &buildI},
- {name: "work", boolVar: &buildWork},
- {name: "gcflags"},
- {name: "exec"},
- {name: "ldflags"},
- {name: "gccgoflags"},
- {name: "tags"},
- {name: "compiler"},
- {name: "race", boolVar: &buildRace},
- {name: "linkshared", boolVar: &buildLinkshared},
- {name: "installsuffix"},
// passed to 6.out, adding a "test." prefix to the name if necessary: -v becomes -test.v.
{name: "bench", passToTest: true},
{name: "v", boolVar: &testV, passToTest: true},
}
+// add build flags to testFlagDefn
+func init() {
+ var cmd Command
+ addBuildFlags(&cmd)
+ cmd.Flag.VisitAll(func(f *flag.Flag) {
+ if f.Name == "v" {
+ // test overrides the build -v flag
+ return
+ }
+ testFlagDefn = append(testFlagDefn, &testFlagSpec{
+ name: f.Name,
+ flagValue: f.Value,
+ })
+ })
+}
+
// testFlags processes the command line, grabbing -x and -c, rewriting known flags
// to have "test" before them, and reading the command line for the 6.out.
// Unfortunately for us, we need to do our own flag processing because go test
passToTest = append(passToTest, args[i])
continue
}
- var err error
- switch f.name {
- // bool flags.
- case "a", "c", "i", "n", "x", "v", "race", "cover", "work", "linkshared":
- setBoolFlag(f.boolVar, value)
- case "o":
- testO = value
- testNeedBinary = true
- case "p":
- setIntFlag(&buildP, value)
- case "exec":
- execCmd, err = splitQuotedFields(value)
- if err != nil {
+ if f.flagValue != nil {
+ if err := f.flagValue.Set(value); err != nil {
fatalf("invalid flag argument for -%s: %v", f.name, err)
}
- case "gcflags":
- buildGcflags, err = splitQuotedFields(value)
- if err != nil {
- fatalf("invalid flag argument for -%s: %v", f.name, err)
- }
- case "ldflags":
- buildLdflags, err = splitQuotedFields(value)
- if err != nil {
- fatalf("invalid flag argument for -%s: %v", f.name, err)
- }
- case "gccgoflags":
- buildGccgoflags, err = splitQuotedFields(value)
- if err != nil {
- fatalf("invalid flag argument for -%s: %v", f.name, err)
- }
- case "tags":
- buildContext.BuildTags = strings.Fields(value)
- case "compiler":
- buildCompiler{}.Set(value)
- case "bench":
- // record that we saw the flag; don't care about the value
- testBench = true
- case "timeout":
- testTimeout = value
- case "blockprofile", "cpuprofile", "memprofile", "trace":
- testProfile = true
- testNeedBinary = true
- case "coverpkg":
- testCover = true
- if value == "" {
- testCoverPaths = nil
- } else {
- testCoverPaths = strings.Split(value, ",")
- }
- case "coverprofile":
- testCover = true
- testProfile = true
- case "covermode":
- switch value {
- case "set", "count", "atomic":
- testCoverMode = value
- default:
- fatalf("invalid flag argument for -covermode: %q", value)
+ } else {
+ // Test-only flags.
+ // Arguably should be handled by f.flagValue, but aren't.
+ var err error
+ switch f.name {
+ // bool flags.
+ case "c", "i", "v", "cover":
+ setBoolFlag(f.boolVar, value)
+ case "o":
+ testO = value
+ testNeedBinary = true
+ case "exec":
+ execCmd, err = splitQuotedFields(value)
+ if err != nil {
+ fatalf("invalid flag argument for -%s: %v", f.name, err)
+ }
+ case "bench":
+ // record that we saw the flag; don't care about the value
+ testBench = true
+ case "timeout":
+ testTimeout = value
+ case "blockprofile", "cpuprofile", "memprofile", "trace":
+ testProfile = true
+ testNeedBinary = true
+ case "coverpkg":
+ testCover = true
+ if value == "" {
+ testCoverPaths = nil
+ } else {
+ testCoverPaths = strings.Split(value, ",")
+ }
+ case "coverprofile":
+ testCover = true
+ testProfile = true
+ case "covermode":
+ switch value {
+ case "set", "count", "atomic":
+ testCoverMode = value
+ default:
+ fatalf("invalid flag argument for -covermode: %q", value)
+ }
+ testCover = true
+ case "outputdir":
+ outputDir = value
}
- testCover = true
- case "outputdir":
- outputDir = value
}
if extraWord {
i++
for _, f = range testFlagDefn {
if name == f.name {
// Booleans are special because they have modes -x, -x=true, -x=false.
- if f.boolVar != nil {
+ if f.boolVar != nil || isBoolFlag(f.flagValue) {
if equals < 0 { // otherwise, it's been set and will be verified in setBoolFlag
value = "true"
} else {
return
}
+// isBoolFlag reports whether v is a bool flag.
+func isBoolFlag(v flag.Value) bool {
+ vv, ok := v.(interface {
+ IsBoolFlag() bool
+ })
+ if ok {
+ return vv.IsBoolFlag()
+ }
+ return false
+}
+
// setBoolFlag sets the addressed boolean to the value.
func setBoolFlag(flag *bool, value string) {
x, err := strconv.ParseBool(value)