Description
Go version
go version go1.20.7 linux/amd64
Output of go env
in your module/workspace:
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/thomas/.cache/go-build"
GOENV="/home/thomas/.config/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GOMODCACHE="/home/thomas/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/home/thomas/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/home/thomas/.gvm/gos/go1.16.3"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/home/thomas/.gvm/gos/go1.16.3/pkg/tool/linux_amd64"
GOVCS=""
GOVERSION="go1.16.3"
GCCGO="gccgo"
AR="ar"
CC="/home/linuxbrew/.linuxbrew/bin/gcc-12"
CXX="g++"
CGO_ENABLED="1"
GOMOD="/dev/null"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build1390062972=/tmp/go-build -gno-record-gcc-switches"
What did you do?
This is tricky to replicate but easy to prove. I am using rules_go, which integrates Go into the bazel ecosystem.
That becomes important here because it seems to be following go.mod
more strictly than Go itself. The short version is that gopls declares a dep on golang.org/x/tools v0.14.1
and in gopls/internal/lsp/source/options.go
imports golang.org/x/tools/go/analysis/passes/appends . However, golang.org/x/tools/go/analysis/passes/appends does not exist at v1.14.1. This breaks the build.
I think that gopls compiling under Go successfully right now might come down to a bug.
If you create the following tools.go:
//go:build tools
// +build tools
package tools // import "example.com/fake"
import (
_ "golang.org/x/tools/gopls"
)
and run go mod init; go mod tidy
, it will make something like this:
module example.com/fake
go 1.20
require golang.org/x/tools/gopls v0.14.2
require (
github.com/BurntSushi/toml v1.2.1 // indirect
github.com/google/go-cmp v0.5.9 // indirect
github.com/sergi/go-diff v1.1.0 // indirect
golang.org/x/exp/typeparams v0.0.0-20221212164502-fae10dda9338 // indirect
golang.org/x/mod v0.14.0 // indirect
golang.org/x/sync v0.4.0 // indirect
golang.org/x/sys v0.14.0 // indirect
golang.org/x/telemetry v0.0.0-20231114163143-69313e640400 // indirect
golang.org/x/text v0.13.0 // indirect
golang.org/x/tools v0.14.1-0.20231114185516-c9d3e7de13fd // indirect
golang.org/x/vuln v1.0.1 // indirect
honnef.co/go/tools v0.4.5 // indirect
mvdan.cc/gofumpt v0.4.0 // indirect
mvdan.cc/xurls/v2 v2.4.0 // indirect
)
Where you can see the incorrect transitive dependency. Trying to build with rules_go
gives:
INFO: Invocation ID: c06c3ff9-38ba-4df2-88e4-29cadb34659d
ERROR: /home/thomas/.cache/bazel/_bazel_thomas/a41610ee02ad9c69b13020a7f1cf3deb/external/org_golang_x_tools_gopls/internal/lsp/source/BUILD.bazel:3:11: no such package '@org_golang_x_tools//go/analysis/passes/appends': BUILD file not found in directory 'go/analysis/passes/appends' of external repository @org_golang_x_tools. Add a BUILD file to a directory to mark it as a package. and referenced by '@org_golang_x_tools_gopls//internal/lsp/source:source'
I think a retraction of some version will be needed.
What did you see happen?
Successful build.
What did you expect to see?
Broken build
Workarounds
I have not been able to work around this issue so far. I intend to use a patch to fix it. I think the replace directive is intended to fix this kind of thing, but replace golang.org/x/tools v0.14.1 => golang.org/x/tools v0.14.0
does not work as it appears replace
ignores patch versions.