onsi / ginkgo

A Modern Testing Framework for Go
http://onsi.github.io/ginkgo/
MIT License
8.09k stars 643 forks source link

cannot support multi version of go #1348

Open ccbhj opened 5 months ago

ccbhj commented 5 months ago

ginkgo version: v2.15.0 custom go version for my project: go1.21 default go version(system-wide): go1.19 Issue description: When I want to use go1.21 to build and test my project, I had encountered the following error:

Failed to compile xxxx:

# github.com/onsi/gomega/internal
../vendor/github.com/onsi/gomega/internal/async_assertion.go:556:19: undefined: context.Cause
note: module requires Go 1.20
# github.com/onsi/ginkgo/v2/internal
../vendor/github.com/onsi/ginkgo/v2/internal/spec_context.go:20:17: undefined: context.CancelCauseFunc
../vendor/github.com/onsi/ginkgo/v2/internal/spec_context.go:33:25: undefined: context.WithCancelCause
note: module requires Go 1.20

Looks like this is because ginkgo can only use the default go command whose version is 1.19 for building although I use go1.21 for my project. I wonder there is any work around for this ?

ccbhj commented 5 months ago

For more information, after I change the go command in the ginkgo/internal/compile.go like this, I was able to build and run my test suite in my project. image

onsi commented 5 months ago

the workaround here would be to use go test -c to compile the binary you want with your desired version of Go and then pass that binary in to the ginkgo CLI. FWIW - I haven’t seen this use-case before so I’m curious what, if anything, prevents you from upgrading your system-wide go to 1.21?

ccbhj commented 5 months ago

Thanks for the reply. The workaround you suggest works but seems inconvenient(can't use ginkgo watch any more), so maybe we can make it a feature to support multi go version? To answer the question why I don't upgrade my system-wide go to 1.21 is that:

  1. This device I use is mainly for work(but sometimes I would also use it for my personal project) and my company strictly requires go1.19 so I make go1.19 system-wide to avoid inconsistency in my daily work.
  2. Sometimes I would like to try some new feature(like the exciting generic feature) provided by the latest go version so I had installed a lot of go sdk in my devices.
onsi commented 5 months ago

if you’re up for working on a PR I can pull it in. I’d propose defining an environment variable that the ginkgo CLI picks up on to set the name of the go binary. If the variable is not defined it should fall back to just go.

Can you check and see if there’s a standardized name for such an env var within the go community?

ccbhj commented 5 months ago

Great, have the same thought on the environment variable😄. Let me do some research and create a PR for this.

ccbhj commented 5 months ago

I haven't found any tools that had implement this use-case after some research. Maybe I should use some kind of go version manager(like gvm) for this ?

onsi commented 5 months ago

give gvm a try. that sounds like the right solution for you.

blgm commented 5 months ago

I use gimme that does a similar thing. I don’t know the pros and cons of the two tools, but just thought I’d mention the alternative in case there are issues with gvm.

BorzdeG commented 5 months ago

I use asdf to separate Go versions and have no problems, since asdf shares not only the Go library, but also downloadable and executable utilities image

ccbhj commented 4 months ago

Thanks you guys for all your advice. I had tried all that solutions(not thoroughly) you guys suggested and I found that asdf is the one that most suitable for my use-case. The reason is that asdf can manage golang version based on your projects config and I think that is the feature that gvm and gimme lack of(or maybe I had missed it in their usage). However, It is a pity that I found all of them not set the $GOPATH, $GOROOT and $GOBIN correctly, but I found this comment useful. Here is a snippet that set some go env var in my .zshrc based on asdf and asdf-direnv, I hope that it would be of some help for those who might need it.

# put this in the .envrc in your project root
export GOPATH=$(asdf where golang)/packages
export GOROOT=$(asdf where golang)/go
export GOBIN=$(asdf where golang)/go/bin
export PATH="${PATH}:${GOBIN}"
use asdf