diff --git a/gotooltest/setup.go b/gotooltest/setup.go index 84705cfa..b1092c92 100644 --- a/gotooltest/setup.go +++ b/gotooltest/setup.go @@ -10,7 +10,6 @@ import ( "bytes" "encoding/json" "fmt" - "go/build" "os/exec" "path/filepath" "regexp" @@ -22,7 +21,7 @@ import ( ) var ( - goVersionRegex = regexp.MustCompile(`^go([1-9][0-9]*)\.(0|[1-9][0-9]*)$`) + goVersionRegex = regexp.MustCompile(`^go([1-9][0-9]*)\.([1-9][0-9]*)$`) goEnv struct { GOROOT string @@ -104,27 +103,6 @@ func Setup(p *testscript.Params) error { p.Cmds = make(map[string]func(ts *testscript.TestScript, neg bool, args []string)) } p.Cmds["go"] = cmdGo - origCondition := p.Condition - p.Condition = func(cond string) (bool, error) { - if cond == "gc" || cond == "gccgo" { - // TODO this reflects the compiler that the current - // binary was built with but not necessarily the compiler - // that will be used. - return cond == runtime.Compiler, nil - } - if goVersionRegex.MatchString(cond) { - for _, v := range build.Default.ReleaseTags { - if cond == v { - return true, nil - } - } - return false, nil - } - if origCondition == nil { - return false, fmt.Errorf("unknown condition %q", cond) - } - return origCondition(cond) - } return nil } diff --git a/testscript/doc.go b/testscript/doc.go index d4fe1869..ba91db36 100644 --- a/testscript/doc.go +++ b/testscript/doc.go @@ -105,6 +105,9 @@ should only run when the condition is satisfied. The predefined conditions are: - [link] for whether the OS has hard link support - [symlink] for whether the OS has symbolic link support - [exec:prog] for whether prog is available for execution (found by exec.LookPath) + - [gc] for whether Go was built with gc + - [gccgo] for whether Go was built with gccgo + - [go1.x] for whether the Go version is 1.x or later A condition can be negated: [!short] means to run the rest of the line when testing.Short() is false. diff --git a/testscript/testdata/cond.txt b/testscript/testdata/cond.txt new file mode 100644 index 00000000..60b62c2a --- /dev/null +++ b/testscript/testdata/cond.txt @@ -0,0 +1,11 @@ +[!exec:sh] skip 'sh not found in $PATH' + +# test that exactly one of gc and gccgo is set +[gc] exec sh -c 'echo gc >> go-compiler' +[gccgo] exec sh -c 'echo gccgo >> go-compiler' +grep '\A(gc|gccgo)\n\z' go-compiler + +# test that go version build tags are set +[go1.1] exec sh -c 'echo go1.1 >> go-version' +[go2.1] exec sh -c 'echo go2.1 >> go-version' +grep '\Ago1\.1\n\z' go-version \ No newline at end of file diff --git a/testscript/testscript.go b/testscript/testscript.go index ea5f51e2..af752e3f 100644 --- a/testscript/testscript.go +++ b/testscript/testscript.go @@ -12,6 +12,7 @@ import ( "context" "flag" "fmt" + "go/build" "io/ioutil" "os" "os/exec" @@ -30,6 +31,8 @@ import ( "github.com/rogpeppe/go-internal/txtar" ) +var goVersionRegex = regexp.MustCompile(`^go([1-9][0-9]*)\.([1-9][0-9]*)$`) + var execCache par.Cache // If -testwork is specified, the test prints the name of the temp directory @@ -572,32 +575,41 @@ func (ts *TestScript) applyScriptUpdates() { // condition reports whether the given condition is satisfied. func (ts *TestScript) condition(cond string) (bool, error) { - switch cond { - case "short": + switch { + case cond == "short": return testing.Short(), nil - case "net": + case cond == "net": return testenv.HasExternalNetwork(), nil - case "link": + case cond == "link": return testenv.HasLink(), nil - case "symlink": + case cond == "symlink": return testenv.HasSymlink(), nil - case runtime.GOOS, runtime.GOARCH: - return true, nil - default: - if imports.KnownArch[cond] || imports.KnownOS[cond] { - return false, nil - } - if strings.HasPrefix(cond, "exec:") { - prog := cond[len("exec:"):] - ok := execCache.Do(prog, func() interface{} { - _, err := execpath.Look(prog, ts.Getenv) - return err == nil - }).(bool) - return ok, nil - } - if ts.params.Condition != nil { - return ts.params.Condition(cond) + case imports.KnownOS[cond]: + return cond == runtime.GOOS, nil + case imports.KnownArch[cond]: + return cond == runtime.GOARCH, nil + case strings.HasPrefix(cond, "exec:"): + prog := cond[len("exec:"):] + ok := execCache.Do(prog, func() interface{} { + _, err := execpath.Look(prog, ts.Getenv) + return err == nil + }).(bool) + return ok, nil + case cond == "gc" || cond == "gccgo": + // TODO this reflects the compiler that the current + // binary was built with but not necessarily the compiler + // that will be used. + return cond == runtime.Compiler, nil + case goVersionRegex.MatchString(cond): + for _, v := range build.Default.ReleaseTags { + if cond == v { + return true, nil + } } + return false, nil + case ts.params.Condition != nil: + return ts.params.Condition(cond) + default: ts.Fatalf("unknown condition %q", cond) panic("unreachable") }