]> Cypherpunks repositories - gostls13.git/commitdiff
internal/goroot: in IsStandardPackage check for go source files
authorMichael Matloob <matloob@golang.org>
Mon, 5 Feb 2024 17:20:45 +0000 (12:20 -0500)
committerMichael Matloob <matloob@golang.org>
Thu, 8 Feb 2024 18:16:28 +0000 (18:16 +0000)
Be more strict in IsStandardPackage: before this change we'd just
check for the existence of the directory, but now we check to see that
there's at least one .go file in the directory.

Also update some comments in the modindex package to reflect the fact
that an IndexPackage might represent a directory that does not contain
any source files.

Fixes #65406
Cq-Include-Trybots: luci.golang.try:gotip-linux-amd64-longtest,gotip-windows-amd64-longtest

Change-Id: I82f0c0e7bfcd5bb4df0195c4c8c7fc7c67fae53e
Reviewed-on: https://go-review.googlesource.com/c/go/+/561338
Reviewed-by: Bryan Mills <bcmills@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>

src/cmd/go/internal/modindex/read.go
src/cmd/go/testdata/script/list_testdata.txt [new file with mode: 0644]
src/cmd/go/testdata/script/mod_list.txt
src/internal/goroot/gc.go
src/internal/goroot/gccgo.go

index 83d5faf28fbefafe201dc869e5be72a30a9c74f0..bda3fb4338c49ee73d89976d54ca0ce1ec54dcb1 100644 (file)
@@ -124,7 +124,7 @@ var (
        errNotFromModuleCache = fmt.Errorf("%w: not from module cache", ErrNotIndexed)
 )
 
-// GetPackage returns the IndexPackage for the package at the given path.
+// GetPackage returns the IndexPackage for the directory at the given path.
 // It will return ErrNotIndexed if the directory should be read without
 // using the index, for instance because the index is disabled, or the package
 // is not in a module.
@@ -669,11 +669,9 @@ func IsStandardPackage(goroot_, compiler, path string) bool {
                reldir = str.TrimFilePathPrefix(reldir, "cmd")
                modroot = filepath.Join(modroot, "cmd")
        }
-       if _, err := GetPackage(modroot, filepath.Join(modroot, reldir)); err == nil {
-               // Note that goroot.IsStandardPackage doesn't check that the directory
-               // actually contains any go files-- merely that it exists. GetPackage
-               // returning a nil error is enough for us to know the directory exists.
-               return true
+       if pkg, err := GetPackage(modroot, filepath.Join(modroot, reldir)); err == nil {
+               hasGo, err := pkg.IsDirWithGoFiles()
+               return err == nil && hasGo
        } else if errors.Is(err, ErrNotIndexed) {
                // Fall back because package isn't indexable. (Probably because
                // a file was modified recently)
@@ -786,8 +784,8 @@ func shouldBuild(sf *sourceFile, tags map[string]bool) bool {
        return true
 }
 
-// IndexPackage holds the information needed to access information in the
-// index needed to load a package in a specific directory.
+// IndexPackage holds the information in the index
+// needed to load a package in a specific directory.
 type IndexPackage struct {
        error error
        dir   string // directory of the package relative to the modroot
diff --git a/src/cmd/go/testdata/script/list_testdata.txt b/src/cmd/go/testdata/script/list_testdata.txt
new file mode 100644 (file)
index 0000000..d62dd55
--- /dev/null
@@ -0,0 +1,11 @@
+# Issue 65406. The testdata directory in GOROOT/src
+# shouldn't be treated as a standard package.
+
+go list -f '{{.ImportPath}} {{.Dir}}' testdata
+! stderr 'found package testdata in multiple modules'
+stdout 'testdata '$WORK${/}'gopath'${/}'src'
+
+-- go.mod --
+module testdata
+-- p.go --
+package p
\ No newline at end of file
index 06316cc335ed677e32cc0647f3b0f3d2d975d0b1..40820b3bb5aed5c8e182febda4f2492543b85f2c 100644 (file)
@@ -44,9 +44,9 @@ stderr '^go: module rsc.io/quote/buggy: not a known dependency'
 
 # Module loader does not interfere with list -e (golang.org/issue/24149).
 go list -e -f '{{.Error.Err}}' database
-stdout 'no Go files in '
+stdout 'package database is not in std'
 ! go list database
-stderr 'no Go files in '
+stderr 'package database is not in std'
 
 -- go.mod --
 module x
index c0216f4ea53d728f711b02c3af748110fe46812b..6b37dfa4c75efd032d0ae64565f14a785c3136ac 100644 (file)
@@ -20,8 +20,16 @@ func IsStandardPackage(goroot, compiler, path string) bool {
        switch compiler {
        case "gc":
                dir := filepath.Join(goroot, "src", path)
-               info, err := os.Stat(dir)
-               return err == nil && info.IsDir()
+               dirents, err := os.ReadDir(dir)
+               if err != nil {
+                       return false
+               }
+               for _, dirent := range dirents {
+                       if strings.HasSuffix(dirent.Name(), ".go") {
+                               return true
+                       }
+               }
+               return false
        case "gccgo":
                return gccgoSearch.isStandard(path)
        default:
index 62841222a7efdbf9d24d8ed14801c162109760df..2bbf4cda2b3ec97e5b6d6ef275748e04ebf693f0 100644 (file)
@@ -9,6 +9,7 @@ package goroot
 import (
        "os"
        "path/filepath"
+       "strings"
 )
 
 // IsStandardPackage reports whether path is a standard package,
@@ -17,8 +18,16 @@ func IsStandardPackage(goroot, compiler, path string) bool {
        switch compiler {
        case "gc":
                dir := filepath.Join(goroot, "src", path)
-               _, err := os.Stat(dir)
-               return err == nil
+               dirents, err := os.ReadDir(dir)
+               if err != nil {
+                       return false
+               }
+               for _, dirent := range dirents {
+                       if strings.HasSuffix(dirent.Name(), ".go") {
+                               return true
+                       }
+               }
+               return false
        case "gccgo":
                return stdpkg[path]
        default: