// expList returns the list of lower-cased experiment names for
// experiments that differ from base. base may be nil to indicate no
-// experiments.
-func expList(exp, base *goexperiment.Flags) []string {
+// experiments. If all is true, then include all experiment flags,
+// regardless of base.
+func expList(exp, base *goexperiment.Flags, all bool) []string {
var list []string
rv := reflect.ValueOf(exp).Elem()
var rBase reflect.Value
if base != nil {
baseVal = rBase.Field(i).Bool()
}
- if val != baseVal {
+ if all || val != baseVal {
if val {
list = append(list, name)
} else {
// GOEXPERIMENT is exactly what a user would set on the command line
// to get the set of enabled experiments.
func GOEXPERIMENT() string {
- return strings.Join(expList(&Experiment, &experimentBaseline), ",")
+ return strings.Join(expList(&Experiment, &experimentBaseline, false), ",")
}
// EnabledExperiments returns a list of enabled experiments, as
// lower-cased experiment names.
func EnabledExperiments() []string {
- return expList(&Experiment, nil)
+ return expList(&Experiment, nil, false)
}
p := ""
- // If the enabled experiments differ from the defaults,
- // include that difference.
- if goexperiment := GOEXPERIMENT(); goexperiment != "" {
- p = " X:" + goexperiment
+ if s == "goexperiment" {
+ // test/run.go uses this to discover the full set of
+ // experiment tags. Report everything.
+ p = " X:" + strings.Join(expList(&Experiment, nil, true), ",")
+ } else {
+ // If the enabled experiments differ from the defaults,
+ // include that difference.
+ if goexperiment := GOEXPERIMENT(); goexperiment != "" {
+ p = " X:" + goexperiment
+ }
}
// The go command invokes -V=full to get a unique identifier
GOARCH string
cgoEnabled bool
noOptEnv bool
+ expTags map[string]bool // Set lazily
}
// shouldTest looks for build tags in a source file and returns
}
}
- exp := os.Getenv("GOEXPERIMENT")
- if exp == "" {
- // If GOEXPERIMENT environment variable is unset, get the default value
- // that is baked into the toolchain.
- cmd := exec.Command(goTool(), "tool", "compile", "-V")
- out, err := cmd.CombinedOutput()
- if err == nil {
+ if strings.HasPrefix(name, "goexperiment.") {
+ // Query goexperiment tags from the toolchain.
+ if ctxt.expTags == nil {
+ ctxt.expTags = make(map[string]bool)
+ cmd := exec.Command(goTool(), "tool", "compile", "-V=goexperiment")
+ out, err := cmd.CombinedOutput()
+ if err != nil {
+ log.Fatalf("failed to get GOEXPERIMENT configuration:\n%s", out)
+ }
i := bytes.Index(out, []byte("X:"))
if i != -1 {
- exp = string(out[i+2:])
- }
- }
- }
- if exp != "" {
- experiments := strings.Split(exp, ",")
- for _, e := range experiments {
- if name == "goexperiment."+e {
- return true
+ for _, exp := range strings.Split(string(out[i+2:]), ",") {
+ v := true
+ if strings.HasPrefix(exp, "no") {
+ v, exp = false, exp[2:]
+ }
+ ctxt.expTags["goexperiment."+exp] = v
+ }
}
}
+
+ return ctxt.expTags[name]
}
if name == "cgo" && ctxt.cgoEnabled {