aboutsummaryrefslogtreecommitdiff
path: root/src/cmd
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd')
-rw-r--r--src/cmd/go/internal/modcmd/vendor.go38
-rw-r--r--src/cmd/go/testdata/script/mod_vendor.txt9
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