diff options
Diffstat (limited to 'tools/constraintutil')
-rw-r--r-- | tools/constraintutil/BUILD | 18 | ||||
-rw-r--r-- | tools/constraintutil/constraintutil.go | 169 | ||||
-rw-r--r-- | tools/constraintutil/constraintutil_test.go | 138 |
3 files changed, 0 insertions, 325 deletions
diff --git a/tools/constraintutil/BUILD b/tools/constraintutil/BUILD deleted file mode 100644 index 004b708c4..000000000 --- a/tools/constraintutil/BUILD +++ /dev/null @@ -1,18 +0,0 @@ -load("//tools:defs.bzl", "go_library", "go_test") - -package(licenses = ["notice"]) - -go_library( - name = "constraintutil", - srcs = ["constraintutil.go"], - marshal = False, - stateify = False, - visibility = ["//tools:__subpackages__"], -) - -go_test( - name = "constraintutil_test", - size = "small", - srcs = ["constraintutil_test.go"], - library = ":constraintutil", -) diff --git a/tools/constraintutil/constraintutil.go b/tools/constraintutil/constraintutil.go deleted file mode 100644 index fb3fbe5c2..000000000 --- a/tools/constraintutil/constraintutil.go +++ /dev/null @@ -1,169 +0,0 @@ -// Copyright 2021 The gVisor Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Package constraintutil provides utilities for working with Go build -// constraints. -package constraintutil - -import ( - "bufio" - "bytes" - "fmt" - "go/build/constraint" - "io" - "os" - "strings" -) - -// FromReader extracts the build constraint from the Go source or assembly file -// whose contents are read by r. -func FromReader(r io.Reader) (constraint.Expr, error) { - // See go/build.parseFileHeader() for the "official" logic that this is - // derived from. - const ( - slashStar = "/*" - starSlash = "*/" - gobuildPrefix = "//go:build" - ) - s := bufio.NewScanner(r) - var ( - inSlashStar = false // between /* and */ - haveGobuild = false - e constraint.Expr - ) -Lines: - for s.Scan() { - line := bytes.TrimSpace(s.Bytes()) - if !inSlashStar && constraint.IsGoBuild(string(line)) { - if haveGobuild { - return nil, fmt.Errorf("multiple go:build directives") - } - haveGobuild = true - var err error - e, err = constraint.Parse(string(line)) - if err != nil { - return nil, err - } - } - ThisLine: - for len(line) > 0 { - if inSlashStar { - if i := bytes.Index(line, []byte(starSlash)); i >= 0 { - inSlashStar = false - line = bytes.TrimSpace(line[i+len(starSlash):]) - continue ThisLine - } - continue Lines - } - if bytes.HasPrefix(line, []byte("//")) { - continue Lines - } - // Note that if /* appears in the line, but not at the beginning, - // then the line is still non-empty, so skipping this and - // terminating below is correct. - if bytes.HasPrefix(line, []byte(slashStar)) { - inSlashStar = true - line = bytes.TrimSpace(line[len(slashStar):]) - continue ThisLine - } - // A non-empty non-comment line terminates scanning for go:build. - break Lines - } - } - return e, s.Err() -} - -// FromString extracts the build constraint from the Go source or assembly file -// containing the given data. If no build constraint applies to the file, it -// returns nil. -func FromString(str string) (constraint.Expr, error) { - return FromReader(strings.NewReader(str)) -} - -// FromFile extracts the build constraint from the Go source or assembly file -// at the given path. If no build constraint applies to the file, it returns -// nil. -func FromFile(path string) (constraint.Expr, error) { - f, err := os.Open(path) - if err != nil { - return nil, err - } - defer f.Close() - return FromReader(f) -} - -// Combine returns a constraint.Expr that evaluates to true iff all expressions -// in es evaluate to true. If es is empty, Combine returns nil. -// -// Preconditions: All constraint.Exprs in es are non-nil. -func Combine(es []constraint.Expr) constraint.Expr { - switch len(es) { - case 0: - return nil - case 1: - return es[0] - default: - a := &constraint.AndExpr{es[0], es[1]} - for i := 2; i < len(es); i++ { - a = &constraint.AndExpr{a, es[i]} - } - return a - } -} - -// CombineFromFiles returns a build constraint expression that evaluates to -// true iff the build constraints from all of the given Go source or assembly -// files evaluate to true. If no build constraints apply to any of the given -// files, it returns nil. -func CombineFromFiles(paths []string) (constraint.Expr, error) { - var es []constraint.Expr - for _, path := range paths { - e, err := FromFile(path) - if err != nil { - return nil, fmt.Errorf("failed to read build constraints from %q: %v", path, err) - } - if e != nil { - es = append(es, e) - } - } - return Combine(es), nil -} - -// Lines returns a string containing build constraint directives for the given -// constraint.Expr, including two trailing newlines, as appropriate for a Go -// source or assembly file. At least a go:build directive will be emitted; if -// the constraint is expressible using +build directives as well, then +build -// directives will also be emitted. -// -// If e is nil, Lines returns the empty string. -func Lines(e constraint.Expr) string { - if e == nil { - return "" - } - - var b strings.Builder - b.WriteString("//go:build ") - b.WriteString(e.String()) - b.WriteByte('\n') - - if pblines, err := constraint.PlusBuildLines(e); err == nil { - for _, line := range pblines { - b.WriteString(line) - b.WriteByte('\n') - } - } - - b.WriteByte('\n') - return b.String() -} diff --git a/tools/constraintutil/constraintutil_test.go b/tools/constraintutil/constraintutil_test.go deleted file mode 100644 index eeabd8dcf..000000000 --- a/tools/constraintutil/constraintutil_test.go +++ /dev/null @@ -1,138 +0,0 @@ -// Copyright 2021 The gVisor Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package constraintutil - -import ( - "go/build/constraint" - "testing" -) - -func TestFileParsing(t *testing.T) { - for _, test := range []struct { - name string - data string - expr string - }{ - { - name: "Empty", - }, - { - name: "NoConstraint", - data: "// copyright header\n\npackage main", - }, - { - name: "ConstraintOnFirstLine", - data: "//go:build amd64\n#include \"textflag.h\"", - expr: "amd64", - }, - { - name: "ConstraintAfterSlashSlashComment", - data: "// copyright header\n\n//go:build linux\n\npackage newlib", - expr: "linux", - }, - { - name: "ConstraintAfterSlashStarComment", - data: "/*\ncopyright header\n*/\n\n//go:build !race\n\npackage oldlib", - expr: "!race", - }, - { - name: "ConstraintInSlashSlashComment", - data: "// blah blah //go:build windows", - }, - { - name: "ConstraintInSlashStarComment", - data: "/*\n//go:build windows\n*/", - }, - { - name: "ConstraintAfterPackageClause", - data: "package oops\n//go:build race", - }, - { - name: "ConstraintAfterCppInclude", - data: "#include \"textflag.h\"\n//go:build arm64", - }, - } { - t.Run(test.name, func(t *testing.T) { - e, err := FromString(test.data) - if err != nil { - t.Fatalf("FromString(%q) failed: %v", test.data, err) - } - if e == nil { - if len(test.expr) != 0 { - t.Errorf("FromString(%q): got no constraint, wanted %q", test.data, test.expr) - } - } else { - got := e.String() - if len(test.expr) == 0 { - t.Errorf("FromString(%q): got %q, wanted no constraint", test.data, got) - } else if got != test.expr { - t.Errorf("FromString(%q): got %q, wanted %q", test.data, got, test.expr) - } - } - }) - } -} - -func TestCombine(t *testing.T) { - for _, test := range []struct { - name string - in []string - out string - }{ - { - name: "0", - }, - { - name: "1", - in: []string{"amd64 || arm64"}, - out: "amd64 || arm64", - }, - { - name: "2", - in: []string{"amd64", "amd64 && linux"}, - out: "amd64 && amd64 && linux", - }, - { - name: "3", - in: []string{"amd64", "amd64 || arm64", "amd64 || riscv64"}, - out: "amd64 && (amd64 || arm64) && (amd64 || riscv64)", - }, - } { - t.Run(test.name, func(t *testing.T) { - inexprs := make([]constraint.Expr, 0, len(test.in)) - for _, estr := range test.in { - line := "//go:build " + estr - e, err := constraint.Parse(line) - if err != nil { - t.Fatalf("constraint.Parse(%q) failed: %v", line, err) - } - inexprs = append(inexprs, e) - } - outexpr := Combine(inexprs) - if outexpr == nil { - if len(test.out) != 0 { - t.Errorf("Combine(%v): got no constraint, wanted %q", test.in, test.out) - } - } else { - got := outexpr.String() - if len(test.out) == 0 { - t.Errorf("Combine(%v): got %q, wanted no constraint", test.in, got) - } else if got != test.out { - t.Errorf("Combine(%v): got %q, wanted %q", test.in, got, test.out) - } - } - }) - } -} |