Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

testscript: add go:version condition #149

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions testscript/doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ 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)
- [go:version] for whether the Go version is at least the given version

A condition can be negated: [!short] means to run the rest of the line
when testing.Short() is false.
Expand Down
8 changes: 8 additions & 0 deletions testscript/testdata/goversion.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[!exec:sh] skip 'sh not found in $PATH'

# test that the go: condition works for minimum supported versions of Go
[go:1.16] exec sh -c 'exit 0'
[go:1.17.1] exec sh -c 'exit 0'

# test that the go:condition works for future versions of Go
[go:2] exec sh -c 'exit 1'
50 changes: 30 additions & 20 deletions testscript/testscript.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
"github.com/rogpeppe/go-internal/imports"
"github.com/rogpeppe/go-internal/internal/os/execpath"
"github.com/rogpeppe/go-internal/par"
"github.com/rogpeppe/go-internal/semver"
"github.com/rogpeppe/go-internal/testenv"
"github.com/rogpeppe/go-internal/txtar"
)
Expand Down Expand Up @@ -552,32 +553,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] {
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 strings.HasPrefix(cond, "go:"):
runtimeVersion := runtime.Version()
if !strings.HasPrefix(runtimeVersion, "go") {
// If the runtime version does not start with "go", then it is a
// commit hash and date at the time of the build, so we have no way
// to know if the runtime version is greater than or equal to the
// minimum version. So, conservatively assume that it is not.
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)
}
goVersion := "v" + strings.TrimPrefix(runtimeVersion, "go")
minVersion := "v" + strings.TrimPrefix(cond, "go:")
return semver.Compare(goVersion, minVersion) >= 0, nil
case ts.params.Condition != nil:
return ts.params.Condition(cond)
default:
ts.Fatalf("unknown condition %q", cond)
panic("unreachable")
}
Expand Down