mirror of
https://github.com/golang/go.git
synced 2025-05-28 19:02:22 +00:00
go/build: add ctxt.MatchFile
Fixes #6369. R=dsymonds, r CC=golang-dev https://golang.org/cl/13708043
This commit is contained in:
parent
1385e394cf
commit
aa53b37fa6
@ -408,6 +408,14 @@ func (e *NoGoError) Error() string {
|
|||||||
return "no buildable Go source files in " + e.Dir
|
return "no buildable Go source files in " + e.Dir
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func nameExt(name string) string {
|
||||||
|
i := strings.LastIndex(name, ".")
|
||||||
|
if i < 0 {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return name[i:]
|
||||||
|
}
|
||||||
|
|
||||||
// Import returns details about the Go package named by the import path,
|
// Import returns details about the Go package named by the import path,
|
||||||
// interpreting local import paths relative to the srcDir directory.
|
// interpreting local import paths relative to the srcDir directory.
|
||||||
// If the path is a local import path naming a package that can be imported
|
// If the path is a local import path naming a package that can be imported
|
||||||
@ -591,58 +599,15 @@ Found:
|
|||||||
if d.IsDir() {
|
if d.IsDir() {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
name := d.Name()
|
name := d.Name()
|
||||||
if strings.HasPrefix(name, "_") ||
|
ext := nameExt(name)
|
||||||
strings.HasPrefix(name, ".") {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
i := strings.LastIndex(name, ".")
|
match, data, filename, err := ctxt.matchFile(p.Dir, name, true, allTags)
|
||||||
if i < 0 {
|
|
||||||
i = len(name)
|
|
||||||
}
|
|
||||||
ext := name[i:]
|
|
||||||
|
|
||||||
if !ctxt.goodOSArchFile(name, allTags) && !ctxt.UseAllFiles {
|
|
||||||
if ext == ".go" {
|
|
||||||
p.IgnoredGoFiles = append(p.IgnoredGoFiles, name)
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
switch ext {
|
|
||||||
case ".go", ".c", ".cc", ".cxx", ".cpp", ".s", ".h", ".hh", ".hpp", ".hxx", ".S", ".swig", ".swigcxx":
|
|
||||||
// tentatively okay - read to make sure
|
|
||||||
case ".syso":
|
|
||||||
// binary objects to add to package archive
|
|
||||||
// Likely of the form foo_windows.syso, but
|
|
||||||
// the name was vetted above with goodOSArchFile.
|
|
||||||
p.SysoFiles = append(p.SysoFiles, name)
|
|
||||||
continue
|
|
||||||
default:
|
|
||||||
// skip
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
filename := ctxt.joinPath(p.Dir, name)
|
|
||||||
f, err := ctxt.openFile(filename)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return p, err
|
return p, err
|
||||||
}
|
}
|
||||||
|
if !match {
|
||||||
var data []byte
|
|
||||||
if strings.HasSuffix(filename, ".go") {
|
|
||||||
data, err = readImports(f, false)
|
|
||||||
} else {
|
|
||||||
data, err = readComments(f)
|
|
||||||
}
|
|
||||||
f.Close()
|
|
||||||
if err != nil {
|
|
||||||
return p, fmt.Errorf("read %s: %v", filename, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Look for +build comments to accept or reject the file.
|
|
||||||
if !ctxt.shouldBuild(data, allTags) && !ctxt.UseAllFiles {
|
|
||||||
if ext == ".go" {
|
if ext == ".go" {
|
||||||
p.IgnoredGoFiles = append(p.IgnoredGoFiles, name)
|
p.IgnoredGoFiles = append(p.IgnoredGoFiles, name)
|
||||||
}
|
}
|
||||||
@ -672,6 +637,12 @@ Found:
|
|||||||
case ".swigcxx":
|
case ".swigcxx":
|
||||||
p.SwigCXXFiles = append(p.SwigCXXFiles, name)
|
p.SwigCXXFiles = append(p.SwigCXXFiles, name)
|
||||||
continue
|
continue
|
||||||
|
case ".syso":
|
||||||
|
// binary objects to add to package archive
|
||||||
|
// Likely of the form foo_windows.syso, but
|
||||||
|
// the name was vetted above with goodOSArchFile.
|
||||||
|
p.SysoFiles = append(p.SysoFiles, name)
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
pf, err := parser.ParseFile(fset, filename, data, parser.ImportsOnly|parser.ParseComments)
|
pf, err := parser.ParseFile(fset, filename, data, parser.ImportsOnly|parser.ParseComments)
|
||||||
@ -782,6 +753,79 @@ Found:
|
|||||||
return p, pkgerr
|
return p, pkgerr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MatchFile reports whether the file with the given name in the given directory
|
||||||
|
// matches the context and would be included in a Package created by ImportDir
|
||||||
|
// of that directory.
|
||||||
|
//
|
||||||
|
// MatchFile considers the name of the file and may use ctxt.OpenFile to
|
||||||
|
// read some or all of the file's content.
|
||||||
|
func (ctxt *Context) MatchFile(dir, name string) (match bool, err error) {
|
||||||
|
match, _, _, err = ctxt.matchFile(dir, name, false, nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// matchFile determines whether the file with the given name in the given directory
|
||||||
|
// should be included in the package being constructed.
|
||||||
|
// It returns the data read from the file.
|
||||||
|
// If returnImports is true and name denotes a Go program, matchFile reads
|
||||||
|
// until the end of the imports (and returns that data) even though it only
|
||||||
|
// considers text until the first non-comment.
|
||||||
|
// If allTags is non-nil, matchFile records any encountered build tag
|
||||||
|
// by setting allTags[tag] = true.
|
||||||
|
func (ctxt *Context) matchFile(dir, name string, returnImports bool, allTags map[string]bool) (match bool, data []byte, filename string, err error) {
|
||||||
|
if strings.HasPrefix(name, "_") ||
|
||||||
|
strings.HasPrefix(name, ".") {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
i := strings.LastIndex(name, ".")
|
||||||
|
if i < 0 {
|
||||||
|
i = len(name)
|
||||||
|
}
|
||||||
|
ext := name[i:]
|
||||||
|
|
||||||
|
if !ctxt.goodOSArchFile(name, allTags) && !ctxt.UseAllFiles {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
switch ext {
|
||||||
|
case ".go", ".c", ".cc", ".cxx", ".cpp", ".s", ".h", ".hh", ".hpp", ".hxx", ".S", ".swig", ".swigcxx":
|
||||||
|
// tentatively okay - read to make sure
|
||||||
|
case ".syso":
|
||||||
|
// binary, no reading
|
||||||
|
match = true
|
||||||
|
return
|
||||||
|
default:
|
||||||
|
// skip
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
filename = ctxt.joinPath(dir, name)
|
||||||
|
f, err := ctxt.openFile(filename)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if strings.HasSuffix(filename, ".go") {
|
||||||
|
data, err = readImports(f, false)
|
||||||
|
} else {
|
||||||
|
data, err = readComments(f)
|
||||||
|
}
|
||||||
|
f.Close()
|
||||||
|
if err != nil {
|
||||||
|
err = fmt.Errorf("read %s: %v", filename, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Look for +build comments to accept or reject the file.
|
||||||
|
if !ctxt.shouldBuild(data, allTags) && !ctxt.UseAllFiles {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
match = true
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func cleanImports(m map[string][]token.Position) ([]string, map[string][]token.Position) {
|
func cleanImports(m map[string][]token.Position) ([]string, map[string][]token.Position) {
|
||||||
all := make([]string, 0, len(m))
|
all := make([]string, 0, len(m))
|
||||||
for path := range m {
|
for path := range m {
|
||||||
@ -1114,16 +1158,22 @@ func (ctxt *Context) goodOSArchFile(name string, allTags map[string]bool) bool {
|
|||||||
}
|
}
|
||||||
n := len(l)
|
n := len(l)
|
||||||
if n >= 2 && knownOS[l[n-2]] && knownArch[l[n-1]] {
|
if n >= 2 && knownOS[l[n-2]] && knownArch[l[n-1]] {
|
||||||
allTags[l[n-2]] = true
|
if allTags != nil {
|
||||||
allTags[l[n-1]] = true
|
allTags[l[n-2]] = true
|
||||||
|
allTags[l[n-1]] = true
|
||||||
|
}
|
||||||
return l[n-2] == ctxt.GOOS && l[n-1] == ctxt.GOARCH
|
return l[n-2] == ctxt.GOOS && l[n-1] == ctxt.GOARCH
|
||||||
}
|
}
|
||||||
if n >= 1 && knownOS[l[n-1]] {
|
if n >= 1 && knownOS[l[n-1]] {
|
||||||
allTags[l[n-1]] = true
|
if allTags != nil {
|
||||||
|
allTags[l[n-1]] = true
|
||||||
|
}
|
||||||
return l[n-1] == ctxt.GOOS
|
return l[n-1] == ctxt.GOOS
|
||||||
}
|
}
|
||||||
if n >= 1 && knownArch[l[n-1]] {
|
if n >= 1 && knownArch[l[n-1]] {
|
||||||
allTags[l[n-1]] = true
|
if allTags != nil {
|
||||||
|
allTags[l[n-1]] = true
|
||||||
|
}
|
||||||
return l[n-1] == ctxt.GOARCH
|
return l[n-1] == ctxt.GOARCH
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
|
@ -5,10 +5,12 @@
|
|||||||
package build
|
package build
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"reflect"
|
"reflect"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -142,3 +144,43 @@ func TestShouldBuild(t *testing.T) {
|
|||||||
t.Errorf("shoudBuild(file3) tags = %v, want %v", m, want3)
|
t.Errorf("shoudBuild(file3) tags = %v, want %v", m, want3)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type readNopCloser struct {
|
||||||
|
io.Reader
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r readNopCloser) Close() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var matchFileTests = []struct {
|
||||||
|
name string
|
||||||
|
data string
|
||||||
|
match bool
|
||||||
|
}{
|
||||||
|
{"foo_arm.go", "", true},
|
||||||
|
{"foo1_arm.go", "// +build linux\n\npackage main\n", false},
|
||||||
|
{"foo_darwin.go", "", false},
|
||||||
|
{"foo.go", "", true},
|
||||||
|
{"foo1.go", "// +build linux\n\npackage main\n", false},
|
||||||
|
{"foo.badsuffix", "", false},
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMatchFile(t *testing.T) {
|
||||||
|
for _, tt := range matchFileTests {
|
||||||
|
ctxt := Context{GOARCH: "arm", GOOS: "plan9"}
|
||||||
|
ctxt.OpenFile = func(path string) (r io.ReadCloser, err error) {
|
||||||
|
if path != "x+"+tt.name {
|
||||||
|
t.Fatalf("OpenFile asked for %q, expected %q", path, "x+"+tt.name)
|
||||||
|
}
|
||||||
|
return &readNopCloser{strings.NewReader(tt.data)}, nil
|
||||||
|
}
|
||||||
|
ctxt.JoinPath = func(elem ...string) string {
|
||||||
|
return strings.Join(elem, "+")
|
||||||
|
}
|
||||||
|
match, err := ctxt.MatchFile("x", tt.name)
|
||||||
|
if match != tt.match || err != nil {
|
||||||
|
t.Fatalf("MatchFile(%q) = %v, %v, want %v, nil", tt.name, match, err, tt.match)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user