golang / go

The Go programming language
https://go.dev
BSD 3-Clause "New" or "Revised" License
122.74k stars 17.5k forks source link

x/tools/gopls: document how to run the daemon in docker #41332

Open ninja18 opened 3 years ago

ninja18 commented 3 years ago

What version of Go are you using (go version)?

go1.12.17 darwin/amd64

Does this issue reproduce with the latest release?

YES recent version of gopls 0.4.4

What operating system and processor architecture are you using (go env)?

GOARCH="amd64"
GOBIN=""
GOCACHE="/Users/ninja/Library/Caches/go-build"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOOS="darwin"
GOPATH="/Users/ninja/go"
GOPROXY=""
GORACE=""
GOROOT="/usr/local/go"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/darwin_amd64"
GCCGO="gccgo"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD="/Users/ninja/Documents/<name>/<project>/go.mod"
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 -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/65/7_p4zdgn2llfqf6fvn1zymjw0000gn/T/go-build716194075=/tmp/go-build -gno-record-gcc-switches -fno-common"

What did you do?

I am trying to setup gopls for neovim with the builtin lsp. But I have a dependency on linux to build the source I cannot build it on mac. So I tried setting up docker gopls server to listen at 7050.

Dockerfile

FROM golang:1.12.16-stretch
RUN apt-get update && apt-get install -y libudev-dev

ARG GOPATH
ENV GOPATH $GOPATH

ARG MY_PWD
ENV MY_PWD ${MY_PWD}

RUN mkdir -p $GOPATH
RUN mkdir -p $MY_PWD

ENV PATH="/usr/local/go/bin:$GOPATH/bin:${PATH}"
RUN GOPROXY=https://proxy.golang.org GO111MODULE=on go get golang.org/x/tools/gopls@latest
WORKDIR $MY_PWD

CMD /go/bin/gopls  -listen=":7050"

I opened nvim and it throws the same build error as the one I got on mac.

Neovim config

:lua << EOF
require'nvim_lsp'.gopls.setup{
cmd = {"gopls","-remote","localhost:7050"};
}
EOF

I initially tried this docker setup for a simple hello world example and that worked. But now I am not sure whether it actually compiled inside docker and communicated the results outside or it just compiled in mac itself. Gopls listen inside docker doesn't give any logs other than connected and exited (atleast when I run docker logs ).

PS: I execed into docker and built the source and it worked as expected.

What did you expect to see?

I expect gopls -remote to build the source inside docker and give back the results to the client.

What did you see instead?

I see the same build error which I got on mac, which might mean gopls is not forwarding the commands to the remote and doing it locally.

stamblerre commented 3 years ago

/cc @findleyr

findleyr commented 3 years ago

If you're seeing connection logging from the daemon inside docker, then you are indeed connecting to the daemon and gopls should be forwarding the LSP.

What is the nature of your build error? My guess is that this may be related to the fact that the gopls forwarder also forwards go env, meaning it forwards GOOS. If this is likely to be the problem, you can try running neovim with GOOS=linux to confirm.

Once we figure this out, we should update the env forwarding logic: what you're trying to do seems like a valuable use-case to support.

I'll also note that there may be issues using gopls on go1.12. Our support for Go versions older than the last two releases is best-effort, though we do make sure gopls compiles and tests pass (this is a recent addition to our CI).

findleyr commented 3 years ago

BTW, I would expect there to be other problems running the gopls daemon in docker. Namely that the file URIs would be incorrect. However, for darwin->linux it could probably be made to work. I assume you've mounted your workspace at the exact same absolute path.

Links to outside your workspace (in GOROOT or GOPATH) will probably break.

ninja18 commented 3 years ago

Thanks for the help! GOOS=linux worked. Yeah on the paths, I have created absolute paths inside docker to make it work and also in docker go is installed in /usr/local/go and the GOROOT=/usr/local/go but in my mac since I have to install a older go it is installed in /usr/local/Cellar/go@1.12/1.12.17/libexec/. Right now I have symlinked to /usr/local/go and changed GOROOT in mac so that both work. But it will be helpful if the go env of the docker is getting used inside except for GOPATH instead of sending it from the host which I don't think makes sense.

findleyr commented 3 years ago

Great, thanks for confirming. You've done something I had wanted to experiment with for a while :)

Repurposing this issue to track documenting and streamlining this use-case for the daemon.