golang / go

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

cmd/go: add a flag to set (or exclude) release tags #52078

Open findleyr opened 2 years ago

findleyr commented 2 years ago

In #50825, we want to allow developers to build gopls with a recent version of Go while still developing for older versions of Go. One blocker to doing this properly is that the set of release tags used in go list is not configurable: they are implied by the version of cmd/go.

We had speculated that #42504 (ignore all build constraints) could help here, but the amount of post-processing required by gopls in that case is prohibitive.

Can we add a flag to cmd/go that allows us to mutate the set of release tags? For example, could we:

I defer entirely to the cmd/go team for flag design, but it would be great to have some way to achieve this.

CC @bcmills @matloob

bcmills commented 2 years ago

I've been thinking about this some more, but I'm not sure that I really grokked the problem space.

If the user has a gopls built with, say, go 1.18, and they're trying to develop against go 1.17, won't the go command itself (and its GOROOT) be 1.17? In that case, go list will have the correct flags by default.

(I don't see how users can realistically target an older Go version that they don't even have installed, given that the packages and identifiers in the Go standard library also change from one release to the next — are we planning to have gopls also filter out packages and identifiers based on GOROOT/api or similar?)

findleyr commented 2 years ago

are we planning to have gopls also filter out packages and identifiers based on GOROOT/api or similar?

Yes, that's part of the plan (see #50825) - add an analyzer to allow developers to preserve compatibility with older go versions independent of their installed version. For example, we frequently have this problem while working on gopls, that one doesn't discover that one has used a disallowed API until after mailing the CL and getting a build failure. Presumably this would also be useful for working on the compiler, which has a bootstrap requirement.

But maybe we can insist that if users want the extra accuracy of building packages exactly as go 1.N, they must use go 1.N for go list. In that case the current request become unnecessary. It's also the case that if we analyzed function bodies for non-workspace packages, we'd want to have an accurate GOROOT (lest we infer inaccurate facts for the target Go version)

I trust your intuition if you think this feature request is a bad idea. In light of the preceding paragraph I'm inclined to agree. Please feel free to close this based on your judgement.

adonovan commented 2 years ago

(I don't see how users can realistically target an older Go version that they don't even have installed, given that the packages and identifiers in the Go standard library also change from one release to the next — are we planning to have gopls also filter out packages and identifiers based on GOROOT/api or similar?)

What if the user builds gopls with an older toolchain (say 1.17) then later updates the go on the PATH to 1.18? Ideally the tool should be able to process files that don't use 1.18 features, and should instruct the go command to select files according to go1.17 release tags. But it may fail to process a tree that depends on go1.18 features, just as a compiler would. That requires a way for the application to tell the go command to behave "no newer than" its own go version.

gopherbot commented 2 years ago

Change https://go.dev/cl/435356 mentions this issue: go/packages: warn if 'go list' on PATH is too new