-
Notifications
You must be signed in to change notification settings - Fork 17.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
x/tools/go/packages: overlay does not work properly with external module files #71075
Comments
This error comes directly from GOROOT= GOPATH=/home/mateusz/go GO111MODULE= GOPROXY= PWD=. go list -overlay=/tmp/gocommand-417420243/overlay.json -e -json=Name,ImportPath,Error,Dir,GoFiles,IgnoredGoFiles,IgnoredOtherFiles,CFiles,CgoFiles,CXXFiles,MFiles,HFiles,FFiles,SFiles,SwigFiles,SwigCXXFiles,SysoFiles,CompiledGoFiles,Export,DepOnly,Imports,ImportMap,Module -compiled=true -test=false -export=true -deps=true -find=false -pgo=off -- . {
"Dir": "/home/mateusz/go/pkg/mod/golang.org/x/tools@v0.28.0/go/packages",
"ImportPath": "golang.org/x/tools/go/packages",
"Name": "packages",
"Module": {
"Path": "golang.org/x/tools",
"Version": "v0.28.0",
"Time": "2024-12-04T22:20:41Z",
"Dir": "/home/mateusz/go/pkg/mod/golang.org/x/tools@v0.28.0",
"GoMod": "/home/mateusz/go/pkg/mod/cache/download/golang.org/x/tools/@v/v0.28.0.mod",
"GoVersion": "1.22.0",
"Sum": "h1:WuB6qZ4RPCQo5aP3WdKZS7i595EdWqWR8vqJTlwTVK8=",
"GoModSum": "h1:dcIOrVd3mfQKTgrDVQHqCPMWy6lnhfhtX3hLXYVLfRw="
},
"DepOnly": true,
"GoFiles": [
"doc.go",
"external.go",
"golist.go",
"golist_overlay.go",
"loadmode_string.go",
"packages.go",
"visit.go"
],
"CompiledGoFiles": [
"doc.go",
"external.go",
"golist.go",
"golist_overlay.go",
"loadmode_string.go",
"packages.go",
"visit.go"
],
"Imports": [
"bytes",
"context",
"encoding/json",
"errors",
"fmt",
"go/ast",
"go/parser",
"go/scanner",
"go/token",
"go/types",
"golang.org/x/sync/errgroup",
"golang.org/x/tools/go/gcexportdata",
"golang.org/x/tools/internal/gocommand",
"golang.org/x/tools/internal/packagesinternal",
"golang.org/x/tools/internal/typesinternal",
"encoding/json",
"errors",
"fmt",
"go/ast",
"go/parser",
"go/scanner",
"go/token",
"go/types",
"golang.org/x/sync/errgroup",
"golang.org/x/tools/go/gcexportdata",
"golang.org/x/tools/internal/gocommand",
"golang.org/x/tools/internal/packagesinternal",
"golang.org/x/tools/internal/typesinternal",
"log",
"os",
"os/exec",
"path",
"path/filepath",
"reflect",
"runtime",
"slices",
"sort",
"strconv",
"strings",
"sync",
"sync/atomic",
"time",
"unicode"
],
"Error": {
"ImportStack": null,
"Pos": "",
"Err": "# golang.org/x/tools/go/packages\n/tmp/gocommand-417420243/3-loadmode_string.go:10:2: could not import unicode/utf8 (open : no such file or directory)\n"
}
} |
Doing the same thing, but with the GOROOT= GOPATH=/home/mateusz/go GO111MODULE= GOPROXY= PWD=. go list -overlay=/tmp/gocommand-2002914138/overlay.json -e -json=Name,ImportPath,Error,Dir,GoFiles,IgnoredGoFiles,IgnoredOtherFiles,CFiles,CgoFiles,CXXFiles,MFiles,HFiles,FFiles,SFiles,SwigFiles,SwigCXXFiles,SysoFiles,CompiledGoFiles,Export,DepOnly,Imports,ImportMap,Module -compiled=true -test=false -export=true -deps=true -find=false -pgo=off -- . {
"Dir": "/tmp/aa/tools/go/packages",
"ImportPath": "golang.org/x/tools/go/packages",
"Name": "packages",
"Export": "/home/mateusz/.cache/go-build/66/66d1428ddfbc9ee5f6e0c00f1827659c07e965a523f71ce88981612ced939ddd-d",
"Module": {
"Path": "golang.org/x/tools",
"Main": true,
"Dir": "/tmp/aa/tools",
"GoMod": "/tmp/aa/tools/go.mod",
"GoVersion": "1.22.0"
},
"DepOnly": true,
"GoFiles": [
"doc.go",
"external.go",
"golist.go",
"golist_overlay.go",
"loadmode_string.go",
"nonExistent.go",
"packages.go",
"visit.go"
],
"CompiledGoFiles": [
"doc.go",
"external.go",
"golist.go",
"golist_overlay.go",
"loadmode_string.go",
"nonExistent.go",
"packages.go",
"visit.go"
],
"Imports": [
"bytes",
"context",
"encoding/json",
"errors",
"fmt",
"go/ast",
"go/parser",
"go/scanner",
"go/token",
"go/types",
"golang.org/x/sync/errgroup",
"golang.org/x/tools/go/gcexportdata",
"golang.org/x/tools/internal/gocommand",
"golang.org/x/tools/internal/packagesinternal",
"golang.org/x/tools/internal/typesinternal",
"log",
"os",
"os/exec",
"path",
"path/filepath",
"reflect",
"runtime",
"slices",
"sort",
"strconv",
"strings",
"sync",
"sync/atomic",
"time",
"unicode",
"unicode/utf8"
]
} |
Hi, I'd like to understand your use case better, but in general this is not supported. We expect the module cache to be immutable (and we write all the files and directories in the cache readonly), and I think it would be impractical to change that expectation. One thing we could do is to detect if files were overlaid in the module cache and explicitly reject that at the beginning. We could also do the same, with, for example the build cache. |
I don't have any particular use case, i just mistakenly overridden the module cache files (in the overlay) and spotted this behavior. I am fine if it didn't worked at all. The current behavior and the error message I am not entirely sure what did you mean by "and explicitly reject that at the beginning"? |
I meant to return an error. I'm thinking of things from the go command perspective: go/packages invokes go list to get the information it needs. I'm proposing that the go command returns an error, which is in turn is returned by go/packages. |
Directly by |
cc @findleyr Oh, that's a good point. I was thinking directly by Load, but you're right that that would cause problems. It would be more complicated to figure out how to set the error on the package from Alternatively we can maybe have gopls check for overlay files in the modcache before calling packages.Load and filtering those out. |
Gopls can definitely filter out overlays from the module cache (perhaps reporting an error back to the user). Then it would be safe for the Go command to fail in that case. |
Change https://go.dev/cl/650475 mentions this issue: |
The go command assumes that GOMODCACHE is immutable. As an example of one place the assumption is made, the modindex won't stat the files in GOMODCACHE when getting the cache key for the index entry and just uses the path of the module in the modcache (basically the module's name and version). Explicitly reject overlays affecting GOMODCACHE to avoid surprising and incorrect behavior. For #71783 For #71075 Change-Id: I21dd5d39d71037de473b09ac8482a1867864e11f Reviewed-on: https://go-review.googlesource.com/c/go/+/650475 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Alan Donovan <adonovan@google.com> Reviewed-by: Robert Findley <rfindley@google.com>
Consider:
This program runs
packages.Load
on a./test
package, with three overlay files on thegolang.org/x/tools/go/packages
package.nonExistent.go
- File does not exist, so this is a new file with a new funcTestFunc
.doc.go
- File already exists, it defines a new funcTestFunc2
.loadmode_string.go
- File already exists, it defines a new funcTestFunc3
and importsunicode/utf8
(this package is not imported without overlays).The
./test
package contains following file:So:
unicode/utf8
(probablygo list
does not return it togo/packages
).nonExistent.go
).Opened this issue, because i think that this behavior is wrong, it should either work without any error for the example above, or just ignore the overlay completely.
CC @matloob (per https://dev.golang.org/owners) @adonovan
The text was updated successfully, but these errors were encountered: