mirror of
https://github.com/golang/go
synced 2024-11-25 19:47:58 -07:00
test/run: process build tags like go/build
R=bradfitz, dave, rsc, r CC=golang-dev https://golang.org/cl/10001045
This commit is contained in:
parent
71c6da39ce
commit
a538558003
83
test/run.go
83
test/run.go
@ -27,6 +27,7 @@ import (
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"unicode"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -299,14 +300,17 @@ func goDirPackages(longdir string) ([][]string, error) {
|
||||
return pkgs, nil
|
||||
}
|
||||
|
||||
type context struct {
|
||||
GOOS string
|
||||
GOARCH string
|
||||
}
|
||||
|
||||
// shouldTest looks for build tags in a source file and returns
|
||||
// whether the file should be used according to the tags.
|
||||
func shouldTest(src string, goos, goarch string) (ok bool, whyNot string) {
|
||||
if idx := strings.Index(src, "\npackage"); idx >= 0 {
|
||||
src = src[:idx]
|
||||
}
|
||||
notgoos := "!" + goos
|
||||
notgoarch := "!" + goarch
|
||||
for _, line := range strings.Split(src, "\n") {
|
||||
line = strings.TrimSpace(line)
|
||||
if strings.HasPrefix(line, "//") {
|
||||
@ -318,29 +322,59 @@ func shouldTest(src string, goos, goarch string) (ok bool, whyNot string) {
|
||||
if len(line) == 0 || line[0] != '+' {
|
||||
continue
|
||||
}
|
||||
ctxt := &context{
|
||||
GOOS: goos,
|
||||
GOARCH: goarch,
|
||||
}
|
||||
words := strings.Fields(line)
|
||||
if words[0] == "+build" {
|
||||
for _, word := range words {
|
||||
switch word {
|
||||
case goos, goarch:
|
||||
return true, ""
|
||||
case notgoos, notgoarch:
|
||||
continue
|
||||
default:
|
||||
if word[0] == '!' {
|
||||
// NOT something-else
|
||||
return true, ""
|
||||
}
|
||||
ok := false
|
||||
for _, word := range words[1:] {
|
||||
if ctxt.match(word) {
|
||||
ok = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !ok {
|
||||
// no matching tag found.
|
||||
return false, line
|
||||
}
|
||||
}
|
||||
// no build tags.
|
||||
}
|
||||
// no build tags
|
||||
return true, ""
|
||||
}
|
||||
|
||||
func (ctxt *context) match(name string) bool {
|
||||
if name == "" {
|
||||
return false
|
||||
}
|
||||
if i := strings.Index(name, ","); i >= 0 {
|
||||
// comma-separated list
|
||||
return ctxt.match(name[:i]) && ctxt.match(name[i+1:])
|
||||
}
|
||||
if strings.HasPrefix(name, "!!") { // bad syntax, reject always
|
||||
return false
|
||||
}
|
||||
if strings.HasPrefix(name, "!") { // negation
|
||||
return len(name) > 1 && !ctxt.match(name[1:])
|
||||
}
|
||||
|
||||
// Tags must be letters, digits, underscores or dots.
|
||||
// Unlike in Go identifiers, all digits are fine (e.g., "386").
|
||||
for _, c := range name {
|
||||
if !unicode.IsLetter(c) && !unicode.IsDigit(c) && c != '_' && c != '.' {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
if name == ctxt.GOOS || name == ctxt.GOARCH {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func init() { checkShouldTest() }
|
||||
|
||||
// run runs a test.
|
||||
@ -815,7 +849,7 @@ func defaultRunOutputLimit() int {
|
||||
return cpu
|
||||
}
|
||||
|
||||
// checkShouldTest runs canity checks on the shouldTest function.
|
||||
// checkShouldTest runs sanity checks on the shouldTest function.
|
||||
func checkShouldTest() {
|
||||
assert := func(ok bool, _ string) {
|
||||
if !ok {
|
||||
@ -823,11 +857,28 @@ func checkShouldTest() {
|
||||
}
|
||||
}
|
||||
assertNot := func(ok bool, _ string) { assert(!ok, "") }
|
||||
|
||||
// Simple tests.
|
||||
assert(shouldTest("// +build linux", "linux", "arm"))
|
||||
assert(shouldTest("// +build !windows", "linux", "arm"))
|
||||
assertNot(shouldTest("// +build !windows", "windows", "amd64"))
|
||||
assertNot(shouldTest("// +build arm 386", "linux", "amd64"))
|
||||
|
||||
// A file with no build tags will always be tested.
|
||||
assert(shouldTest("// This is a test.", "os", "arch"))
|
||||
|
||||
// Build tags separated by a space are OR-ed together.
|
||||
assertNot(shouldTest("// +build arm 386", "linux", "amd64"))
|
||||
|
||||
// Build tags seperated by a comma are AND-ed together.
|
||||
assertNot(shouldTest("// +build !windows,!plan9", "windows", "amd64"))
|
||||
assertNot(shouldTest("// +build !windows,!plan9", "plan9", "386"))
|
||||
|
||||
// Build tags on multiple lines are AND-ed together.
|
||||
assert(shouldTest("// +build !windows\n// +build amd64", "linux", "amd64"))
|
||||
assertNot(shouldTest("// +build !windows\n// +build amd64", "windows", "amd64"))
|
||||
|
||||
// Test that (!a OR !b) matches anything.
|
||||
assert(shouldTest("// +build !windows !plan9", "windows", "amd64"))
|
||||
}
|
||||
|
||||
// envForDir returns a copy of the environment
|
||||
|
49
test/testlib
49
test/testlib
@ -16,29 +16,50 @@ pkgs() {
|
||||
done | sort
|
||||
}
|
||||
|
||||
_match() {
|
||||
case $1 in
|
||||
*,*)
|
||||
#echo >&2 "match comma separated $1"
|
||||
first=$(echo $1 | sed 's/,.*//')
|
||||
rest=$(echo $1 | sed 's/[^,]*,//')
|
||||
if _match $first && _match $rest; then
|
||||
return 0
|
||||
fi
|
||||
return 1
|
||||
;;
|
||||
'!'*)
|
||||
#echo >&2 "match negation $1"
|
||||
neg=$(echo $1 | sed 's/^!//')
|
||||
if _match $neg; then
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
;;
|
||||
$GOARCH|$GOOS)
|
||||
#echo >&2 "match GOARCH or GOOS $1"
|
||||
return 0
|
||||
;;
|
||||
esac
|
||||
return 1
|
||||
}
|
||||
|
||||
# +build aborts execution if the supplied tags don't match,
|
||||
# i.e. none of the tags (x or !x) matches GOARCH or GOOS.
|
||||
+build() {
|
||||
if (( $# == 0 )); then
|
||||
return
|
||||
fi
|
||||
m=0
|
||||
for tag; do
|
||||
case $tag in
|
||||
$GOARCH|$GOOS)
|
||||
#echo >&2 "match $tag in $1"
|
||||
return # don't exclude.
|
||||
;;
|
||||
'!'$GOARCH|'!'$GOOS)
|
||||
;;
|
||||
'!'*)
|
||||
# not x where x is neither GOOS nor GOARCH.
|
||||
#echo >&2 "match $tag in $1"
|
||||
return # don't exclude
|
||||
;;
|
||||
esac
|
||||
if _match $tag; then
|
||||
m=1
|
||||
fi
|
||||
done
|
||||
# no match.
|
||||
if [ $m = 0 ]; then
|
||||
#echo >&2 no match
|
||||
exit 0
|
||||
fi
|
||||
unset m
|
||||
}
|
||||
|
||||
compile() {
|
||||
|
Loading…
Reference in New Issue
Block a user