]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/go: include module root in package index key
authorBryan C. Mills <bcmills@google.com>
Thu, 30 Jun 2022 17:39:57 +0000 (13:39 -0400)
committerGopher Robot <gobot@golang.org>
Thu, 30 Jun 2022 18:20:39 +0000 (18:20 +0000)
The package index format includes the directory relative to the module
root. The module root for a given directory can change even if the
contents of the directory itself do not (by adding or removing a
go.mod file in some parent directory).

Thus, we need to invalidate the index for a package when its module
root location changes.

Fixes #53586 (I think).

Change-Id: I2d9f4de80e16bce75b3106a2bad4a11d8378d037
Reviewed-on: https://go-review.googlesource.com/c/go/+/415475
Reviewed-by: Russ Cox <rsc@golang.org>
Auto-Submit: Bryan Mills <bcmills@google.com>
Run-TryBot: Bryan Mills <bcmills@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>

src/cmd/go/internal/modindex/read.go
src/cmd/go/testdata/script/issue53586.txt [new file with mode: 0644]

index 65a1ecf6dc7179c16e387aa20697c375335abd2d..2603ade0fbd67ac5750caa599fae246850ba9bde 100644 (file)
@@ -73,6 +73,10 @@ func moduleHash(modroot string, ismodcache bool) (cache.ActionID, error) {
        }
 
        h := cache.NewHash("moduleIndex")
+       // TODO(bcmills): Since modules in the index are checksummed, we could
+       // probably improve the cache hit rate by keying off of the module
+       // path@version (perhaps including the checksum?) instead of the module root
+       // directory.
        fmt.Fprintf(h, "module index %s %s %v\n", runtime.Version(), indexVersion, modroot)
        return h.Sum(), nil
 }
@@ -81,8 +85,9 @@ const modTimeCutoff = 2 * time.Second
 
 // dirHash returns an ActionID corresponding to the state of the package
 // located at filesystem path pkgdir.
-func dirHash(pkgdir string) (cache.ActionID, error) {
+func dirHash(modroot, pkgdir string) (cache.ActionID, error) {
        h := cache.NewHash("moduleIndex")
+       fmt.Fprintf(h, "modroot %s\n", modroot)
        fmt.Fprintf(h, "package %s %s %v\n", runtime.Version(), indexVersion, pkgdir)
        entries, err := fsys.ReadDir(pkgdir)
        if err != nil {
@@ -206,8 +211,8 @@ func openIndexPackage(modroot, pkgdir string) (*IndexPackage, error) {
                pkg *IndexPackage
                err error
        }
-       r := pcache.Do(pkgdir, func() any {
-               id, err := dirHash(pkgdir)
+       r := pcache.Do([2]string{modroot, pkgdir}, func() any {
+               id, err := dirHash(modroot, pkgdir)
                if err != nil {
                        return result{nil, err}
                }
diff --git a/src/cmd/go/testdata/script/issue53586.txt b/src/cmd/go/testdata/script/issue53586.txt
new file mode 100644 (file)
index 0000000..db405cd
--- /dev/null
@@ -0,0 +1,18 @@
+[short] skip  # sleeps to make mtime cacheable
+
+go mod init example
+
+cd subdir
+go mod init example/subdir
+sleep 2s  # allow go.mod mtime to be cached
+
+go list -f '{{.Dir}}: {{.ImportPath}}' ./pkg
+stdout $PWD${/}pkg': example/subdir/pkg$'
+
+rm go.mod  # expose ../go.mod
+
+go list -f '{{.Dir}}: {{.ImportPath}}' ./pkg
+stdout $PWD${/}pkg': example/subdir/pkg$'
+
+-- subdir/pkg/pkg.go --
+package pkg