cmd/go: add support for go get -u tool

Change-Id: I14d20c6c77d0d0a83cb547d954ba7f244166bc43
Reviewed-on: https://go-review.googlesource.com/c/go/+/563176
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Sam Thanawalla <samthanawalla@google.com>
Reviewed-by: Michael Matloob <matloob@golang.org>
This commit is contained in:
Conrad Irwin 2024-02-10 21:51:12 -07:00 committed by Michael Matloob
parent 4a1167dfe1
commit 8c8948c375
4 changed files with 49 additions and 2 deletions

View File

@ -342,6 +342,7 @@ func runGet(ctx context.Context, cmd *base.Command, args []string) {
r := newResolver(ctx, queries)
r.performLocalQueries(ctx)
r.performPathQueries(ctx)
r.performToolQueries(ctx)
for {
r.performWildcardQueries(ctx)
@ -515,6 +516,7 @@ type resolver struct {
pathQueries []*query // package path literal queries in original order
wildcardQueries []*query // path wildcard queries in original order
patternAllQueries []*query // queries with the pattern "all"
toolQueries []*query // queries with the pattern "tool"
// Indexed "none" queries. These are also included in the slices above;
// they are indexed here to speed up noneForPath.
@ -574,6 +576,8 @@ func newResolver(ctx context.Context, queries []*query) *resolver {
for _, q := range queries {
if q.pattern == "all" {
r.patternAllQueries = append(r.patternAllQueries, q)
} else if q.pattern == "tool" {
r.toolQueries = append(r.toolQueries, q)
} else if q.patternIsLocal {
r.localQueries = append(r.localQueries, q)
} else if q.isWildcard() {
@ -1050,6 +1054,19 @@ func (r *resolver) queryPath(ctx context.Context, q *query) {
})
}
// performToolQueries populates the candidates for each query whose
// pattern is "tool".
func (r *resolver) performToolQueries(ctx context.Context) {
for _, q := range r.toolQueries {
for tool := range modload.MainModules.Tools() {
q.pathOnce(tool, func() pathSet {
pkgMods, err := r.queryPackages(ctx, tool, q.version, r.initialSelected)
return pathSet{pkgMods: pkgMods, err: err}
})
}
}
}
// performPatternAllQueries populates the candidates for each query whose
// pattern is "all".
//

View File

@ -199,6 +199,9 @@ func (q *query) validate() error {
if search.IsMetaPackage(q.pattern) && q.pattern != "all" {
if q.pattern != q.raw {
if q.pattern == "tool" {
return fmt.Errorf("can't request explicit version of \"tool\" pattern")
}
return fmt.Errorf("can't request explicit version of standard-library pattern %q", q.pattern)
}
}

View File

@ -0,0 +1,12 @@
-- .info --
{"Version": "v1.1.0"}
-- .mod --
module example.com/tools
-- cmd/hello/hello.go --
package main
import "fmt"
func main() {
fmt.Println("hello v1.1")
}

View File

@ -1,7 +1,10 @@
# test go get -tool
go get -tool example.com/tools/cmd/hello
go get -tool example.com/tools/cmd/hello@v1.0.0
cmp go.mod go.mod.want
go get -u tool
cmp go.mod go.mod.upgraded
# test -tool with @none
go get -tool example.com/tools/cmd/hello@none
cmp go.mod go.mod.gone
@ -19,6 +22,10 @@ stderr 'can''t request explicit version "none" of path "./cmd/..." in main modul
! go get -tool all
stderr 'go get -tool does not work with "all"'
# test tool@none
! go get tool@none
stderr 'can''t request explicit version of "tool" pattern'
-- main.go --
package main
@ -36,12 +43,20 @@ go 1.24
tool example.com/tools/cmd/hello
require example.com/tools v1.0.0 // indirect
-- go.mod.upgraded --
module example.com/foo
go 1.24
tool example.com/tools/cmd/hello
require example.com/tools v1.1.0 // indirect
-- go.mod.gone --
module example.com/foo
go 1.24
require example.com/tools v1.0.0 // indirect
require example.com/tools v1.1.0 // indirect
-- go.mod.empty --
module example.com/foo