Description
As part of my analysis tests, I have the following testdata
structure:
└── testdata
├── go1.0
│ ├── CheckStructTags
│ │ └── CheckStructTags.go
│ ├── CheckStructTags2
│ │ └── CheckStructTags2.go
│ └── vendor
│ └── ...
└── go1.18
└── CheckStructTags
└── generics.go
Each directory in testdata
specifies the Go language version to test with and is conceptually its own Go module. I don't want to check in actual go.mod
files, so instead I use go/package's overlays to synthesize them. The vendor directory contains stubs for third party packages that my analyses have special handling for. Because I specify Go versions older than 1.14, I also set GOFLAGS=-mod=vendor
to explicitly enable vendoring.
packages.Config.Dir
is set to these modules, e.g. testdata/go1.0
. go/packages
invokes go list
three times:
2024/05/24 22:58:13 3.253809ms for GOROOT= GOPATH=/home/dominikh/prj GO111MODULE=off GOPROXY=off PWD=testdata/go1.0 go list -e -f {{context.ReleaseTags}} -- unsafe
2024/05/24 22:58:13 3.46024ms for GOROOT= GOPATH=/home/dominikh/prj GO111MODULE= GOPROXY=off PWD=testdata/go1.0 go list -f "{{context.GOARCH}} {{context.Compiler}}" -- unsafe
2024/05/24 22:58:13 65.806626ms for GOROOT= GOPATH=/home/dominikh/prj GO111MODULE= GOPROXY=off PWD=testdata/go1.0 go list -overlay=/tmp/gocommand-2395062716/overlay.json -e -json=Name,ImportPath,Error,Dir,GoFiles,IgnoredGoFiles,IgnoredOtherFiles,CFiles,CgoFiles,CXXFiles,MFiles,HFiles,FFiles,SFiles,SwigFiles,SwigCXXFiles,SysoFiles,TestGoFiles,XTestGoFiles,CompiledGoFiles,Export,DepOnly,Imports,ImportMap,TestImports,XTestImports,Module -compiled=true -test=true -export=true -deps=true -find=false -pgo=off -- ./...
Only the third call passes the overlay. The second call runs with modules enabled, but without the overlay. However, it still sees GOFLAGS=-mod=vendor. go
now walks up the directory tree to find the outer, real module and complains about its "inconsistent vendoring":
err: exit status 1: stderr: go: inconsistent vendoring in /home/dominikh/prj/src/honnef.co/go/tools:
[...]
because the outer module isn't actually using vendoring.
This can be avoided by passing the overlay to the second invocation also, in which case it treats testdata/go1.0
as its own module.