golang / go

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

cmd/go: allow versioned 'go list' commands #44203

Open mvdan opened 3 years ago

mvdan commented 3 years ago

https://github.com/golang/go/issues/40276 allows using go install path@version to install a package at a specific version, ignoring the current module.

https://github.com/golang/go/issues/42088 is an accepted proposal to allow go run path@version with similar semantics - run a main package at a specific version, ignoring the current module.

While I agree that these semantics are most often useful for go install and go run, I argue that they would also be useful for other cmd/go commands. In this proposal, I want to make a case for go list path@version.

The main use case I want to bring forth is to list the packages included in a specific version of a module. Right now, I can only accomplish this via:

go mod init tmp
go get -d ${module}@${version}
go list ${module}/...
rm go.mod go.sum

It could instead be just go list ${module}/...@${version}.

For reference, I'm using this to generate static HTML pages to serve go get and browser requests for vanity import paths; see https://github.com/mvdan/mvdan.cc/blob/572593964513b20649c474cc9a6559405ec9cc29/gen-go-modules.bash#L49-L53.

I think this feature would also make go list a bit more consistent, since go list -m path@version currently works just fine.

/cc @dominikh @bcmills @jayconrod @myitcv @eliasnaur

bcmills commented 3 years ago

I can see some use for this feature, it's consistent with the recent change to go install and the approved go run proposal, and I don't see anything fundamentally problematic about it.

I'm curious to see what @jayconrod and @matloob think, but at this point it seems ok to me.

jayconrod commented 3 years ago

Seems fine to me. Though I think we should talk about allowing @version on all commands that take packages (where it makes sense; not go generate).

The main difference is that go install pkg@version and go run pkg@version both require main packages, and they require those packages to come from the same module at the same version. That would be overly restrictive for go list. So how should the arguments be interpreted?

As a starting point, I think it should do what go get does when run outside of a module: start with an empty build list, add those specific versions, run MVS, and verify we didn't upgrade beyond those versions.

mvdan commented 3 years ago

Though I think we should talk about allowing @version on all commands that take packages (where it makes sense; not go generate).

I think that makes sense too, and @dominikh seemed to also agree on Slack. I thought we could start with just go list, as it seems like the next clear win to me, after go install and go run, but I'm also fine with doing many at once.

As a starting point, I think it should do what go get does when run outside of a module: start with an empty build list, add those specific versions, run MVS, and verify we didn't upgrade beyond those versions.

Sounds good to me. From the caller's point of view, if they want to do MVS resolution separately for a number of arguments, they could just use separate go list calls. The module download cache should keep that reasonably fast.

hyangah commented 3 years ago

Somewhat related to the version suffix support: As some tools age and go through many releases, the output length of go list -m -versions is getting longer. Today, I wished I could use the version query to limit the number of versions. For example, if I query go list -m -versions golang.org/x/tools/gopls@'>v0.6.5, I hope to get only the list of available versions that satisfy the version query.

peebs commented 3 years ago

The main difference is that go install pkg@version and go run pkg@version both require main packages, and they require those packages to come from the same module at the same version. That would be overly restrictive for go list. So how should the arguments be interpreted?

If the required semantics of the go list pkg@version differ from that of install and run, then I'd hope go list doesn't share the @version syntax for consistency of UX.

jayconrod commented 3 years ago

If the required semantics of the go list pkg@version differ from that of install and run, then I'd hope go list doesn't share the @version syntax for consistency of UX.

I think it's okay for go list to share the @version syntax, as long as the arguments would be interpreted the same way for all commands.

go list would allow non-main packages, so I don't think go list pkg@version does anything unexpected; that's an error with go install.

In @hyangah's example of go list -m -versions golang.org/x/tools/gopls@'>v0.6.5, there's nothing equivalent to the go list -m flag in go install, so it doesn't seem inconsistent. That said, allowing a version query like @>v0.6.5 to match multiple versions is pretty different than any command today. I wonder if we should track that separately and keep this issue focused on the equivalent forms in go install and go run?