diff --git a/imports/build.go b/imports/build.go index 9e1f41b6..5fd0106e 100644 --- a/imports/build.go +++ b/imports/build.go @@ -195,17 +195,28 @@ func MatchFile(name string, tags map[string]bool) bool { return true } -var KnownOS = make(map[string]bool) -var KnownArch = make(map[string]bool) +var ( + KnownOS = make(map[string]bool) + UnixOS = make(map[string]bool) + KnownArch = make(map[string]bool) +) func init() { for _, v := range strings.Fields(goosList) { KnownOS[v] = true } + for _, v := range strings.Fields(unixList) { + UnixOS[v] = true + } for _, v := range strings.Fields(goarchList) { KnownArch[v] = true } } -const goosList = "aix android darwin dragonfly freebsd hurd illumos ios js linux nacl netbsd openbsd plan9 solaris windows zos " -const goarchList = "386 amd64 amd64p32 arm armbe arm64 arm64be loong64 mips mipsle mips64 mips64le mips64p32 mips64p32le ppc ppc64 ppc64le riscv riscv64 s390 s390x sparc sparc64 wasm " +// These values come from Go's src/go/build/syslist.go and should be kept in +// sync with that file. +const ( + goosList = "aix android darwin dragonfly freebsd hurd illumos ios js linux nacl netbsd openbsd plan9 solaris windows zos " + unixList = "aix android darwin dragonfly freebsd hurd illumos ios linux netbsd openbsd solaris " + goarchList = "386 amd64 amd64p32 arm armbe arm64 arm64be loong64 mips mipsle mips64 mips64le mips64p32 mips64p32le ppc ppc64 ppc64le riscv riscv64 s390 s390x sparc sparc64 wasm " +) diff --git a/testscript/doc.go b/testscript/doc.go index 10ae6ace..5cee2023 100644 --- a/testscript/doc.go +++ b/testscript/doc.go @@ -108,6 +108,12 @@ should only run when the condition is satisfied. The predefined conditions are: - [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 + - [unix] for whether the OS is Unix-like (that is, would match the 'unix' build + constraint) + +Any known values of GOOS and GOARCH can also be used as conditions. They will be +satisfied if the target OS or architecture match the specified value. For example, +the condition [darwin] is true if GOOS=darwin, and [amd64] is true if GOARCH=amd64. 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 index 60b62c2a..05612d64 100644 --- a/testscript/testdata/cond.txt +++ b/testscript/testdata/cond.txt @@ -1,11 +1,23 @@ -[!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 +[gc] mkdir gc_true +[gccgo] mkdir gccgo_true + +[gc] ! exists gccgo_true +[!gc] exists gccgo_true +[gccgo] ! exists gc_true +[!gccgo] exists gc_true # 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 +[go1.1] mkdir go1.x +[go2.1] mkdir go2.x + +exists go1.x +! exists go2.x + +# unix should be true on Linux and MacOS, but not on Windows. +# Both platforms are tested on CI. +[unix] mkdir unix_true + +[linux] exists unix_true +[darwin] exists unix_true +[windows] ! exists unix_true diff --git a/testscript/testscript.go b/testscript/testscript.go index bd05977a..a04ca81d 100644 --- a/testscript/testscript.go +++ b/testscript/testscript.go @@ -601,6 +601,8 @@ func (ts *TestScript) condition(cond string) (bool, error) { return testenv.HasSymlink(), nil case imports.KnownOS[cond]: return cond == runtime.GOOS, nil + case cond == "unix": + return imports.UnixOS[runtime.GOOS], nil case imports.KnownArch[cond]: return cond == runtime.GOARCH, nil case strings.HasPrefix(cond, "exec:"):