diff options
Diffstat (limited to 'src/cmd')
| -rw-r--r-- | src/cmd/go/internal/modcmd/vendor.go | 38 | ||||
| -rw-r--r-- | src/cmd/go/testdata/script/mod_vendor.txt | 9 |
2 files changed, 40 insertions, 7 deletions
diff --git a/src/cmd/go/internal/modcmd/vendor.go b/src/cmd/go/internal/modcmd/vendor.go index b70f25cec3..7265e62a2f 100644 --- a/src/cmd/go/internal/modcmd/vendor.go +++ b/src/cmd/go/internal/modcmd/vendor.go @@ -15,6 +15,7 @@ import ( "cmd/go/internal/base" "cmd/go/internal/cfg" + "cmd/go/internal/imports" "cmd/go/internal/modload" "cmd/go/internal/module" ) @@ -100,7 +101,7 @@ func vendorPkg(vdir, pkg string) { if src == "" { fmt.Fprintf(os.Stderr, "internal error: no pkg for %s -> %s\n", pkg, realPath) } - copyDir(dst, src, matchNonTest) + copyDir(dst, src, matchPotentialSourceFile) if m := modload.PackageModule(realPath); m.Path != "" { copyMetadata(m.Path, realPath, dst, src) } @@ -153,7 +154,7 @@ var metaPrefixes = []string{ } // matchMetadata reports whether info is a metadata file. -func matchMetadata(info os.FileInfo) bool { +func matchMetadata(dir string, info os.FileInfo) bool { name := info.Name() for _, p := range metaPrefixes { if strings.HasPrefix(name, p) { @@ -163,13 +164,36 @@ func matchMetadata(info os.FileInfo) bool { return false } -// matchNonTest reports whether info is any non-test file (including non-Go files). -func matchNonTest(info os.FileInfo) bool { - return !strings.HasSuffix(info.Name(), "_test.go") +var anyTagsExceptIgnore = map[string]bool{"*": true} + +// matchPotentialSourceFile reports whether info may be relevant to a build operation. +func matchPotentialSourceFile(dir string, info os.FileInfo) bool { + if strings.HasSuffix(info.Name(), "_test.go") { + return false + } + if strings.HasSuffix(info.Name(), ".go") { + f, err := os.Open(filepath.Join(dir, info.Name())) + if err != nil { + base.Fatalf("go mod vendor: %v", err) + } + defer f.Close() + + content, err := imports.ReadImports(f, false, nil) + if err == nil && !imports.ShouldBuild(content, anyTagsExceptIgnore) { + // The file is explicitly tagged "ignore", so it can't affect the build. + // Leave it out. + return false + } + return true + } + + // We don't know anything about this file, so optimistically assume that it is + // needed. + return true } // copyDir copies all regular files satisfying match(info) from src to dst. -func copyDir(dst, src string, match func(os.FileInfo) bool) { +func copyDir(dst, src string, match func(dir string, info os.FileInfo) bool) { files, err := ioutil.ReadDir(src) if err != nil { base.Fatalf("go mod vendor: %v", err) @@ -178,7 +202,7 @@ func copyDir(dst, src string, match func(os.FileInfo) bool) { base.Fatalf("go mod vendor: %v", err) } for _, file := range files { - if file.IsDir() || !file.Mode().IsRegular() || !match(file) { + if file.IsDir() || !file.Mode().IsRegular() || !match(src, file) { continue } r, err := os.Open(filepath.Join(src, file.Name())) diff --git a/src/cmd/go/testdata/script/mod_vendor.txt b/src/cmd/go/testdata/script/mod_vendor.txt index 203183be88..25a77a3670 100644 --- a/src/cmd/go/testdata/script/mod_vendor.txt +++ b/src/cmd/go/testdata/script/mod_vendor.txt @@ -38,6 +38,7 @@ stdout 'src[\\/]w' stderr 'src[\\/]vendor[\\/]w' ! exists vendor/x/testdata +! exists vendor/a/foo/bar/b/ignored.go ! exists vendor/a/foo/bar/b/main_test.go exists vendor/a/foo/AUTHORS.txt @@ -102,6 +103,14 @@ replace ( -- a/foo/bar/b/main.go -- package b +-- a/foo/bar/b/ignored.go -- +// This file is intended for use with "go run"; it isn't really part of the package. + +// +build ignore + +package main + +func main() {} -- a/foo/bar/b/main_test.go -- package b |
