fatih / vim-go

Go development plugin for Vim
https://www.patreon.com/bhcleek
Other
16.01k stars 1.45k forks source link

Current PWD info lost causing goenv to not know what version to shim #3683

Closed jaitaiwan closed 1 month ago

jaitaiwan commented 1 month ago

What did you do? (required: The issue will be closed when not provided)

Opened vim, ran :GoInstallBinaries

What did you expect to happen?

Environment passed into vim so the goenv shim knows version of go it should be running.

What happened instead?

I’m using goenv with no system default go installed. I’m opening vim in a local git repo where there’s a .go-version file that specifies the version of go the goenv shim should point towards. Running go version shows the correctly selected version in the terminal. When running vim and then performing :GoInstallBinaries it seems that something about the shell environment isn’t being passed into vim-go somehow as when vim-go attempts to install binaries the response from the goenv shim is that it doesn’t know what version is set.

Configuration:

vim-go version: Master (f365d961)

vimrc you used to reproduce:

vimrc ```vim filetype off set nocompatible set rtp+=~/.vim/bundle/vundle call vundle#begin() Plugin 'VundleVim/Vundle.vim', {'name': 'vundle'} Plugin 'fatih/vim-go' " End Setup call vundle#end() filetype plugin indent on syntax on ```

Vim version (first three lines from :version):

VIM - Vi IMproved 9.1 (2024 Jan 02, compiled Jul 29 2024 23:49:12)
Included patches: 1-636
Compiled by daniel@gw

Go version (go version):

go version go1.22.5 linux/amd64

Go version (goenv -v):

goenv 2.2.4

Go environment

go env Output:

GO111MODULE=''
GOARCH='amd64'
GOBIN=''
GOCACHE='/home/daniel/.cache/go-build'
GOENV='/home/daniel/.config/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
GOHOSTARCH='amd64'
GOHOSTOS='linux'
GOINSECURE=''
GOMODCACHE='/home/daniel/go/1.22.5/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='linux'
GOPATH='/home/daniel/go/1.22.5'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/home/daniel/.goenv/versions/1.22.5'
GOSUMDB='sum.golang.org'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/home/daniel/.goenv/versions/1.22.5/pkg/tool/linux_amd64'
GOVCS=''
GOVERSION='go1.22.5'
GCCGO='gccgo'
GOAMD64='v1'
AR='ar'
CC='gcc'
CXX='g++'
CGO_ENABLED='1'
GOMOD='/home/daniel/Repositories/sensaweb/monorepo/go.mod'
GOWORK=''
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
PKG_CONFIG='pkg-config'
GOGCCFLAGS='-fPIC -m64 -pthread -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/tmp/go-build1886598715=/tmp/go-build -gno-record-gcc-switches'

gopls version

gopls version Output:

gopls: command not found
jaitaiwan commented 1 month ago

So to be clear, in the terminal I can run: go version

And receive the output as specified in the ticket description. I can run :!go version in vim and the same output happens but when running :GoInstallBinaries there's an error from goenv not knowing what version to use:

goenv: 'go' command not found

The 'go' command exists in these Go versions:
  1.22.5
bhcleek commented 1 month ago

I don't know how goenv actually works, but vim-go simply expects go to be in PATH. I suspect that one of your environment variables that goenv expects either isn't exported (and therefore isn't seen by vim) or else isn't set at the time vim is started.

I'd recommend comparing the output of :echo environ() in vim with the output of :!set in vim to see if you can isolate what's different and topical.

Environment passed into vim so the goenv shim knows version of go it should be running.

It's up to you to pass the environment needed to vim. The particulars of how to do that will depend on your system and vim environment.

jaitaiwan commented 1 month ago

I've confirmed they're equivalent. Go is in path so I wonder if when vim-go executes go it executes it in the context of PWD that vim was opened in?

bhcleek commented 1 month ago

The PWD that vim-go uses when executing go will vary a bit depending on what's being done. When executing most functions, vim-go will use the directory in which the current buffer resides. However, for :GoInstallBinaries and :GoUpdateBinaries, vim-go will use a temporary directory.

edit: corrected :GoInstallBinaries and :GoUpdateBinaries explanation.

jaitaiwan commented 1 month ago

Perfect thank you @bhcleek, that then is the root cause of the issue. If I'm running in a directory /project/a where a contains a file .go-version, then when :GoInstallBinaries or :GoUpdateBinaries is run it then goes to (in theory) /tmp/somefolder where there's no .go-version which causes the goenv shim to not know what version of go it should be shimming to.

Is this something that can be configurable? e.g. have it set so that it will just use the current pwd?

bhcleek commented 1 month ago

No, that's not configurable. Given that you're using goenv, I'd recommend using GOENV_VERSION if my reading of their docs is correct.

But I'm also not sure you need to use goenv at all. Only two version of Go are supported at a time: the current and previous major releases. And with the go and toolchain directives, it's possible (likely) that you have all you need and goenv is merely adding complexity to your setup.

jaitaiwan commented 1 month ago

@bhcleek that's a fair statement for most circumstances. There's a lot of legacy projects that I and others have to maintain, so goenv allows for testing versions which are no longer supported by go but still supported by others. I guess the toolchain for those older versions can be manually installed at a pinned version which means the need for the vim-go commands is moot at that point though.

In the meantime I can confirm that doing GOENV_VERSION=1.22.5 vim and then running the :GoInstallBinaries command works.

I created this alias, seems like the best way to sort things right now alias vim='GOENV_VERSION=$(go version | grep "[0-9]\.[0-9]*\.[0-9]*" -o1) vim'

bhcleek commented 1 month ago

You could also do this in your session (perhaps in your vimrc or an after/plugin/vim-go?): let $GOENV_VERSION=split(system('/bin/bash -c "go env GOVERSION | grep -o -m 1.*"'), "\n")[0]. 🤷

jaitaiwan commented 1 month ago

That’d be good, even better if one could track the error message from running the go command when the shim can’t find a version.