]> Cypherpunks.ru repositories - gostls13.git/blob - src/cmd/go/internal/modget/get.go
cmd/go: additional doc-inspired tests and bug fixes
[gostls13.git] / src / cmd / go / internal / modget / get.go
1 // Copyright 2018 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 // Package modget implements the module-aware “go get” command.
6 package modget
7
8 // The arguments to 'go get' are patterns with optional version queries, with
9 // the version queries defaulting to "upgrade".
10 //
11 // The patterns are normally interpreted as package patterns. However, if a
12 // pattern cannot match a package, it is instead interpreted as a *module*
13 // pattern. For version queries such as "upgrade" and "patch" that depend on the
14 // selected version of a module (or of the module containing a package),
15 // whether a pattern denotes a package or module may change as updates are
16 // applied (see the example in mod_get_patchmod.txt).
17 //
18 // There are a few other ambiguous cases to resolve, too. A package can exist in
19 // two different modules at the same version: for example, the package
20 // example.com/foo might be found in module example.com and also in module
21 // example.com/foo, and those modules may have independent v0.1.0 tags — so the
22 // input 'example.com/foo@v0.1.0' could syntactically refer to the variant of
23 // the package loaded from either module! (See mod_get_ambiguous_pkg.txt.)
24 // If the argument is ambiguous, the user can often disambiguate by specifying
25 // explicit versions for *all* of the potential module paths involved.
26
27 import (
28         "context"
29         "errors"
30         "fmt"
31         "os"
32         "path/filepath"
33         "runtime"
34         "sort"
35         "strings"
36         "sync"
37
38         "cmd/go/internal/base"
39         "cmd/go/internal/cfg"
40         "cmd/go/internal/gover"
41         "cmd/go/internal/imports"
42         "cmd/go/internal/modfetch"
43         "cmd/go/internal/modload"
44         "cmd/go/internal/par"
45         "cmd/go/internal/search"
46         "cmd/go/internal/toolchain"
47         "cmd/go/internal/work"
48
49         "golang.org/x/mod/modfile"
50         "golang.org/x/mod/module"
51 )
52
53 var CmdGet = &base.Command{
54         // Note: flags below are listed explicitly because they're the most common.
55         // Do not send CLs removing them because they're covered by [get flags].
56         UsageLine: "go get [-t] [-u] [-v] [build flags] [packages]",
57         Short:     "add dependencies to current module and install them",
58         Long: `
59 Get resolves its command-line arguments to packages at specific module versions,
60 updates go.mod to require those versions, and downloads source code into the
61 module cache.
62
63 To add a dependency for a package or upgrade it to its latest version:
64
65         go get example.com/pkg
66
67 To upgrade or downgrade a package to a specific version:
68
69         go get example.com/pkg@v1.2.3
70
71 To remove a dependency on a module and downgrade modules that require it:
72
73         go get example.com/mod@none
74
75 To upgrade the minimum required Go version to the latest released Go version:
76
77         go get go@latest
78
79 To upgrade the Go toolchain to the latest patch release of the current Go toolchain:
80
81         go get toolchain@patch
82
83 See https://golang.org/ref/mod#go-get for details.
84
85 In earlier versions of Go, 'go get' was used to build and install packages.
86 Now, 'go get' is dedicated to adjusting dependencies in go.mod. 'go install'
87 may be used to build and install commands instead. When a version is specified,
88 'go install' runs in module-aware mode and ignores the go.mod file in the
89 current directory. For example:
90
91         go install example.com/pkg@v1.2.3
92         go install example.com/pkg@latest
93
94 See 'go help install' or https://golang.org/ref/mod#go-install for details.
95
96 'go get' accepts the following flags.
97
98 The -t flag instructs get to consider modules needed to build tests of
99 packages specified on the command line.
100
101 The -u flag instructs get to update modules providing dependencies
102 of packages named on the command line to use newer minor or patch
103 releases when available.
104
105 The -u=patch flag (not -u patch) also instructs get to update dependencies,
106 but changes the default to select patch releases.
107
108 When the -t and -u flags are used together, get will update
109 test dependencies as well.
110
111 The -x flag prints commands as they are executed. This is useful for
112 debugging version control commands when a module is downloaded directly
113 from a repository.
114
115 For more about modules, see https://golang.org/ref/mod.
116
117 For more about using 'go get' to update the minimum Go version and
118 suggested Go toolchain, see https://go.dev/doc/toolchain.
119
120 For more about specifying packages, see 'go help packages'.
121
122 This text describes the behavior of get using modules to manage source
123 code and dependencies. If instead the go command is running in GOPATH
124 mode, the details of get's flags and effects change, as does 'go help get'.
125 See 'go help gopath-get'.
126
127 See also: go build, go install, go clean, go mod.
128         `,
129 }
130
131 // Note that this help text is a stopgap to make the module-aware get help text
132 // available even in non-module settings. It should be deleted when the old get
133 // is deleted. It should NOT be considered to set a precedent of having hierarchical
134 // help names with dashes.
135 var HelpModuleGet = &base.Command{
136         UsageLine: "module-get",
137         Short:     "module-aware go get",
138         Long: `
139 The 'go get' command changes behavior depending on whether the
140 go command is running in module-aware mode or legacy GOPATH mode.
141 This help text, accessible as 'go help module-get' even in legacy GOPATH mode,
142 describes 'go get' as it operates in module-aware mode.
143
144 Usage: ` + CmdGet.UsageLine + `
145 ` + CmdGet.Long,
146 }
147
148 var HelpVCS = &base.Command{
149         UsageLine: "vcs",
150         Short:     "controlling version control with GOVCS",
151         Long: `
152 The 'go get' command can run version control commands like git
153 to download imported code. This functionality is critical to the decentralized
154 Go package ecosystem, in which code can be imported from any server,
155 but it is also a potential security problem, if a malicious server finds a
156 way to cause the invoked version control command to run unintended code.
157
158 To balance the functionality and security concerns, the 'go get' command
159 by default will only use git and hg to download code from public servers.
160 But it will use any known version control system (bzr, fossil, git, hg, svn)
161 to download code from private servers, defined as those hosting packages
162 matching the GOPRIVATE variable (see 'go help private'). The rationale behind
163 allowing only Git and Mercurial is that these two systems have had the most
164 attention to issues of being run as clients of untrusted servers. In contrast,
165 Bazaar, Fossil, and Subversion have primarily been used in trusted,
166 authenticated environments and are not as well scrutinized as attack surfaces.
167
168 The version control command restrictions only apply when using direct version
169 control access to download code. When downloading modules from a proxy,
170 'go get' uses the proxy protocol instead, which is always permitted.
171 By default, the 'go get' command uses the Go module mirror (proxy.golang.org)
172 for public packages and only falls back to version control for private
173 packages or when the mirror refuses to serve a public package (typically for
174 legal reasons). Therefore, clients can still access public code served from
175 Bazaar, Fossil, or Subversion repositories by default, because those downloads
176 use the Go module mirror, which takes on the security risk of running the
177 version control commands using a custom sandbox.
178
179 The GOVCS variable can be used to change the allowed version control systems
180 for specific packages (identified by a module or import path).
181 The GOVCS variable applies when building package in both module-aware mode
182 and GOPATH mode. When using modules, the patterns match against the module path.
183 When using GOPATH, the patterns match against the import path corresponding to
184 the root of the version control repository.
185
186 The general form of the GOVCS setting is a comma-separated list of
187 pattern:vcslist rules. The pattern is a glob pattern that must match
188 one or more leading elements of the module or import path. The vcslist
189 is a pipe-separated list of allowed version control commands, or "all"
190 to allow use of any known command, or "off" to disallow all commands.
191 Note that if a module matches a pattern with vcslist "off", it may still be
192 downloaded if the origin server uses the "mod" scheme, which instructs the
193 go command to download the module using the GOPROXY protocol.
194 The earliest matching pattern in the list applies, even if later patterns
195 might also match.
196
197 For example, consider:
198
199         GOVCS=github.com:git,evil.com:off,*:git|hg
200
201 With this setting, code with a module or import path beginning with
202 github.com/ can only use git; paths on evil.com cannot use any version
203 control command, and all other paths (* matches everything) can use
204 only git or hg.
205
206 The special patterns "public" and "private" match public and private
207 module or import paths. A path is private if it matches the GOPRIVATE
208 variable; otherwise it is public.
209
210 If no rules in the GOVCS variable match a particular module or import path,
211 the 'go get' command applies its default rule, which can now be summarized
212 in GOVCS notation as 'public:git|hg,private:all'.
213
214 To allow unfettered use of any version control system for any package, use:
215
216         GOVCS=*:all
217
218 To disable all use of version control, use:
219
220         GOVCS=*:off
221
222 The 'go env -w' command (see 'go help env') can be used to set the GOVCS
223 variable for future go command invocations.
224 `,
225 }
226
227 var (
228         getD        = CmdGet.Flag.Bool("d", true, "")
229         getF        = CmdGet.Flag.Bool("f", false, "")
230         getFix      = CmdGet.Flag.Bool("fix", false, "")
231         getM        = CmdGet.Flag.Bool("m", false, "")
232         getT        = CmdGet.Flag.Bool("t", false, "")
233         getU        upgradeFlag
234         getInsecure = CmdGet.Flag.Bool("insecure", false, "")
235         // -v is cfg.BuildV
236 )
237
238 // upgradeFlag is a custom flag.Value for -u.
239 type upgradeFlag struct {
240         rawVersion string
241         version    string
242 }
243
244 func (*upgradeFlag) IsBoolFlag() bool { return true } // allow -u
245
246 func (v *upgradeFlag) Set(s string) error {
247         if s == "false" {
248                 v.version = ""
249                 v.rawVersion = ""
250         } else if s == "true" {
251                 v.version = "upgrade"
252                 v.rawVersion = ""
253         } else {
254                 v.version = s
255                 v.rawVersion = s
256         }
257         return nil
258 }
259
260 func (v *upgradeFlag) String() string { return "" }
261
262 func init() {
263         work.AddBuildFlags(CmdGet, work.OmitModFlag)
264         CmdGet.Run = runGet // break init loop
265         CmdGet.Flag.Var(&getU, "u", "")
266 }
267
268 func runGet(ctx context.Context, cmd *base.Command, args []string) {
269         switch getU.version {
270         case "", "upgrade", "patch":
271                 // ok
272         default:
273                 base.Fatalf("go: unknown upgrade flag -u=%s", getU.rawVersion)
274         }
275         // TODO(#43684): in the future (Go 1.20), warn that -d is a no-op.
276         if !*getD {
277                 base.Fatalf("go: -d flag may not be disabled")
278         }
279         if *getF {
280                 fmt.Fprintf(os.Stderr, "go: -f flag is a no-op when using modules\n")
281         }
282         if *getFix {
283                 fmt.Fprintf(os.Stderr, "go: -fix flag is a no-op when using modules\n")
284         }
285         if *getM {
286                 base.Fatalf("go: -m flag is no longer supported")
287         }
288         if *getInsecure {
289                 base.Fatalf("go: -insecure flag is no longer supported; use GOINSECURE instead")
290         }
291
292         modload.ForceUseModules = true
293
294         // Do not allow any updating of go.mod until we've applied
295         // all the requested changes and checked that the result matches
296         // what was requested.
297         modload.ExplicitWriteGoMod = true
298
299         // Allow looking up modules for import paths when outside of a module.
300         // 'go get' is expected to do this, unlike other commands.
301         modload.AllowMissingModuleImports()
302
303         // 'go get' no longer builds or installs packages, so there's nothing to do
304         // if there's no go.mod file.
305         // TODO(#40775): make modload.Init return ErrNoModRoot instead of exiting.
306         // We could handle that here by printing a different message.
307         modload.Init()
308         if !modload.HasModRoot() {
309                 base.Fatalf("go: go.mod file not found in current directory or any parent directory.\n" +
310                         "\t'go get' is no longer supported outside a module.\n" +
311                         "\tTo build and install a command, use 'go install' with a version,\n" +
312                         "\tlike 'go install example.com/cmd@latest'\n" +
313                         "\tFor more information, see https://golang.org/doc/go-get-install-deprecation\n" +
314                         "\tor run 'go help get' or 'go help install'.")
315         }
316
317         dropToolchain, queries := parseArgs(ctx, args)
318         opts := modload.WriteOpts{
319                 DropToolchain: dropToolchain,
320         }
321         for _, q := range queries {
322                 if q.pattern == "toolchain" {
323                         opts.ExplicitToolchain = true
324                 }
325         }
326
327         r := newResolver(ctx, queries)
328         r.performLocalQueries(ctx)
329         r.performPathQueries(ctx)
330
331         for {
332                 r.performWildcardQueries(ctx)
333                 r.performPatternAllQueries(ctx)
334
335                 if changed := r.resolveQueries(ctx, queries); changed {
336                         // 'go get' arguments can be (and often are) package patterns rather than
337                         // (just) modules. A package can be provided by any module with a prefix
338                         // of its import path, and a wildcard can even match packages in modules
339                         // with totally different paths. Because of these effects, and because any
340                         // change to the selected version of a module can bring in entirely new
341                         // module paths as dependencies, we need to reissue queries whenever we
342                         // change the build list.
343                         //
344                         // The result of any version query for a given module — even "upgrade" or
345                         // "patch" — is always relative to the build list at the start of
346                         // the 'go get' command, not an intermediate state, and is therefore
347                         // dederministic and therefore cachable, and the constraints on the
348                         // selected version of each module can only narrow as we iterate.
349                         //
350                         // "all" is functionally very similar to a wildcard pattern. The set of
351                         // packages imported by the main module does not change, and the query
352                         // result for the module containing each such package also does not change
353                         // (it is always relative to the initial build list, before applying
354                         // queries). So the only way that the result of an "all" query can change
355                         // is if some matching package moves from one module in the build list
356                         // to another, which should not happen very often.
357                         continue
358                 }
359
360                 // When we load imports, we detect the following conditions:
361                 //
362                 // - missing transitive depencies that need to be resolved from outside the
363                 //   current build list (note that these may add new matches for existing
364                 //   pattern queries!)
365                 //
366                 // - transitive dependencies that didn't match any other query,
367                 //   but need to be upgraded due to the -u flag
368                 //
369                 // - ambiguous import errors.
370                 //   TODO(#27899): Try to resolve ambiguous import errors automatically.
371                 upgrades := r.findAndUpgradeImports(ctx, queries)
372                 if changed := r.applyUpgrades(ctx, upgrades); changed {
373                         continue
374                 }
375
376                 r.findMissingWildcards(ctx)
377                 if changed := r.resolveQueries(ctx, r.wildcardQueries); changed {
378                         continue
379                 }
380
381                 break
382         }
383
384         r.checkWildcardVersions(ctx)
385
386         var pkgPatterns []string
387         for _, q := range queries {
388                 if q.matchesPackages {
389                         pkgPatterns = append(pkgPatterns, q.pattern)
390                 }
391         }
392         r.checkPackageProblems(ctx, pkgPatterns)
393
394         // Everything succeeded. Update go.mod.
395         oldReqs := reqsFromGoMod(modload.ModFile())
396
397         if err := modload.WriteGoMod(ctx, opts); err != nil {
398                 // A TooNewError can happen for 'go get go@newversion'
399                 // when all the required modules are old enough
400                 // but the command line is not.
401                 // TODO(bcmills): modload.EditBuildList should catch this instead,
402                 // and then this can be changed to base.Fatal(err).
403                 toolchain.SwitchOrFatal(ctx, err)
404         }
405
406         newReqs := reqsFromGoMod(modload.ModFile())
407         r.reportChanges(oldReqs, newReqs)
408
409         if gowork := modload.FindGoWork(base.Cwd()); gowork != "" {
410                 wf, err := modload.ReadWorkFile(gowork)
411                 if err == nil && modload.UpdateWorkGoVersion(wf, modload.MainModules.GoVersion()) {
412                         modload.WriteWorkFile(gowork, wf)
413                 }
414         }
415 }
416
417 // parseArgs parses command-line arguments and reports errors.
418 //
419 // The command-line arguments are of the form path@version or simply path, with
420 // implicit @upgrade. path@none is "downgrade away".
421 func parseArgs(ctx context.Context, rawArgs []string) (dropToolchain bool, queries []*query) {
422         defer base.ExitIfErrors()
423
424         for _, arg := range search.CleanPatterns(rawArgs) {
425                 q, err := newQuery(arg)
426                 if err != nil {
427                         base.Error(err)
428                         continue
429                 }
430
431                 if q.version == "none" {
432                         switch q.pattern {
433                         case "go":
434                                 base.Errorf("go: cannot use go@none")
435                                 continue
436                         case "toolchain":
437                                 dropToolchain = true
438                                 continue
439                         }
440                 }
441
442                 // If there were no arguments, CleanPatterns returns ".". Set the raw
443                 // string back to "" for better errors.
444                 if len(rawArgs) == 0 {
445                         q.raw = ""
446                 }
447
448                 // Guard against 'go get x.go', a common mistake.
449                 // Note that package and module paths may end with '.go', so only print an error
450                 // if the argument has no version and either has no slash or refers to an existing file.
451                 if strings.HasSuffix(q.raw, ".go") && q.rawVersion == "" {
452                         if !strings.Contains(q.raw, "/") {
453                                 base.Errorf("go: %s: arguments must be package or module paths", q.raw)
454                                 continue
455                         }
456                         if fi, err := os.Stat(q.raw); err == nil && !fi.IsDir() {
457                                 base.Errorf("go: %s exists as a file, but 'go get' requires package arguments", q.raw)
458                                 continue
459                         }
460                 }
461
462                 queries = append(queries, q)
463         }
464
465         return dropToolchain, queries
466 }
467
468 type resolver struct {
469         localQueries      []*query // queries for absolute or relative paths
470         pathQueries       []*query // package path literal queries in original order
471         wildcardQueries   []*query // path wildcard queries in original order
472         patternAllQueries []*query // queries with the pattern "all"
473
474         // Indexed "none" queries. These are also included in the slices above;
475         // they are indexed here to speed up noneForPath.
476         nonesByPath   map[string]*query // path-literal "@none" queries indexed by path
477         wildcardNones []*query          // wildcard "@none" queries
478
479         // resolvedVersion maps each module path to the version of that module that
480         // must be selected in the final build list, along with the first query
481         // that resolved the module to that version (the “reason”).
482         resolvedVersion map[string]versionReason
483
484         buildList        []module.Version
485         buildListVersion map[string]string // index of buildList (module path → version)
486
487         initialVersion map[string]string // index of the initial build list at the start of 'go get'
488
489         missing []pathSet // candidates for missing transitive dependencies
490
491         work *par.Queue
492
493         matchInModuleCache par.ErrCache[matchInModuleKey, []string]
494 }
495
496 type versionReason struct {
497         version string
498         reason  *query
499 }
500
501 type matchInModuleKey struct {
502         pattern string
503         m       module.Version
504 }
505
506 func newResolver(ctx context.Context, queries []*query) *resolver {
507         // LoadModGraph also sets modload.Target, which is needed by various resolver
508         // methods.
509         mg, err := modload.LoadModGraph(ctx, "")
510         if err != nil {
511                 toolchain.SwitchOrFatal(ctx, err)
512         }
513
514         buildList := mg.BuildList()
515         initialVersion := make(map[string]string, len(buildList))
516         for _, m := range buildList {
517                 initialVersion[m.Path] = m.Version
518         }
519
520         r := &resolver{
521                 work:             par.NewQueue(runtime.GOMAXPROCS(0)),
522                 resolvedVersion:  map[string]versionReason{},
523                 buildList:        buildList,
524                 buildListVersion: initialVersion,
525                 initialVersion:   initialVersion,
526                 nonesByPath:      map[string]*query{},
527         }
528
529         for _, q := range queries {
530                 if q.pattern == "all" {
531                         r.patternAllQueries = append(r.patternAllQueries, q)
532                 } else if q.patternIsLocal {
533                         r.localQueries = append(r.localQueries, q)
534                 } else if q.isWildcard() {
535                         r.wildcardQueries = append(r.wildcardQueries, q)
536                 } else {
537                         r.pathQueries = append(r.pathQueries, q)
538                 }
539
540                 if q.version == "none" {
541                         // Index "none" queries to make noneForPath more efficient.
542                         if q.isWildcard() {
543                                 r.wildcardNones = append(r.wildcardNones, q)
544                         } else {
545                                 // All "<path>@none" queries for the same path are identical; we only
546                                 // need to index one copy.
547                                 r.nonesByPath[q.pattern] = q
548                         }
549                 }
550         }
551
552         return r
553 }
554
555 // initialSelected returns the version of the module with the given path that
556 // was selected at the start of this 'go get' invocation.
557 func (r *resolver) initialSelected(mPath string) (version string) {
558         v, ok := r.initialVersion[mPath]
559         if !ok {
560                 return "none"
561         }
562         return v
563 }
564
565 // selected returns the version of the module with the given path that is
566 // selected in the resolver's current build list.
567 func (r *resolver) selected(mPath string) (version string) {
568         v, ok := r.buildListVersion[mPath]
569         if !ok {
570                 return "none"
571         }
572         return v
573 }
574
575 // noneForPath returns a "none" query matching the given module path,
576 // or found == false if no such query exists.
577 func (r *resolver) noneForPath(mPath string) (nq *query, found bool) {
578         if nq = r.nonesByPath[mPath]; nq != nil {
579                 return nq, true
580         }
581         for _, nq := range r.wildcardNones {
582                 if nq.matchesPath(mPath) {
583                         return nq, true
584                 }
585         }
586         return nil, false
587 }
588
589 // queryModule wraps modload.Query, substituting r.checkAllowedOr to decide
590 // allowed versions.
591 func (r *resolver) queryModule(ctx context.Context, mPath, query string, selected func(string) string) (module.Version, error) {
592         current := r.initialSelected(mPath)
593         rev, err := modload.Query(ctx, mPath, query, current, r.checkAllowedOr(query, selected))
594         if err != nil {
595                 return module.Version{}, err
596         }
597         return module.Version{Path: mPath, Version: rev.Version}, nil
598 }
599
600 // queryPackages wraps modload.QueryPackage, substituting r.checkAllowedOr to
601 // decide allowed versions.
602 func (r *resolver) queryPackages(ctx context.Context, pattern, query string, selected func(string) string) (pkgMods []module.Version, err error) {
603         results, err := modload.QueryPackages(ctx, pattern, query, selected, r.checkAllowedOr(query, selected))
604         if len(results) > 0 {
605                 pkgMods = make([]module.Version, 0, len(results))
606                 for _, qr := range results {
607                         pkgMods = append(pkgMods, qr.Mod)
608                 }
609         }
610         return pkgMods, err
611 }
612
613 // queryPattern wraps modload.QueryPattern, substituting r.checkAllowedOr to
614 // decide allowed versions.
615 func (r *resolver) queryPattern(ctx context.Context, pattern, query string, selected func(string) string) (pkgMods []module.Version, mod module.Version, err error) {
616         results, modOnly, err := modload.QueryPattern(ctx, pattern, query, selected, r.checkAllowedOr(query, selected))
617         if len(results) > 0 {
618                 pkgMods = make([]module.Version, 0, len(results))
619                 for _, qr := range results {
620                         pkgMods = append(pkgMods, qr.Mod)
621                 }
622         }
623         if modOnly != nil {
624                 mod = modOnly.Mod
625         }
626         return pkgMods, mod, err
627 }
628
629 // checkAllowedOr is like modload.CheckAllowed, but it always allows the requested
630 // and current versions (even if they are retracted or otherwise excluded).
631 func (r *resolver) checkAllowedOr(requested string, selected func(string) string) modload.AllowedFunc {
632         return func(ctx context.Context, m module.Version) error {
633                 if m.Version == requested {
634                         return modload.CheckExclusions(ctx, m)
635                 }
636                 if (requested == "upgrade" || requested == "patch") && m.Version == selected(m.Path) {
637                         return nil
638                 }
639                 return modload.CheckAllowed(ctx, m)
640         }
641 }
642
643 // matchInModule is a caching wrapper around modload.MatchInModule.
644 func (r *resolver) matchInModule(ctx context.Context, pattern string, m module.Version) (packages []string, err error) {
645         return r.matchInModuleCache.Do(matchInModuleKey{pattern, m}, func() ([]string, error) {
646                 match := modload.MatchInModule(ctx, pattern, m, imports.AnyTags())
647                 if len(match.Errs) > 0 {
648                         return match.Pkgs, match.Errs[0]
649                 }
650                 return match.Pkgs, nil
651         })
652 }
653
654 // queryNone adds a candidate set to q for each module matching q.pattern.
655 // Each candidate set has only one possible module version: the matched
656 // module at version "none".
657 //
658 // We interpret arguments to 'go get' as packages first, and fall back to
659 // modules second. However, no module exists at version "none", and therefore no
660 // package exists at that version either: we know that the argument cannot match
661 // any packages, and thus it must match modules instead.
662 func (r *resolver) queryNone(ctx context.Context, q *query) {
663         if search.IsMetaPackage(q.pattern) {
664                 panic(fmt.Sprintf("internal error: queryNone called with pattern %q", q.pattern))
665         }
666
667         if !q.isWildcard() {
668                 q.pathOnce(q.pattern, func() pathSet {
669                         hasModRoot := modload.HasModRoot()
670                         if hasModRoot && modload.MainModules.Contains(q.pattern) {
671                                 v := module.Version{Path: q.pattern}
672                                 // The user has explicitly requested to downgrade their own module to
673                                 // version "none". This is not an entirely unreasonable request: it
674                                 // could plausibly mean “downgrade away everything that depends on any
675                                 // explicit version of the main module”, or “downgrade away the
676                                 // package with the same path as the main module, found in a module
677                                 // with a prefix of the main module's path”.
678                                 //
679                                 // However, neither of those behaviors would be consistent with the
680                                 // plain meaning of the query. To try to reduce confusion, reject the
681                                 // query explicitly.
682                                 return errSet(&modload.QueryMatchesMainModulesError{MainModules: []module.Version{v}, Pattern: q.pattern, Query: q.version})
683                         }
684
685                         return pathSet{mod: module.Version{Path: q.pattern, Version: "none"}}
686                 })
687         }
688
689         for _, curM := range r.buildList {
690                 if !q.matchesPath(curM.Path) {
691                         continue
692                 }
693                 q.pathOnce(curM.Path, func() pathSet {
694                         if modload.HasModRoot() && curM.Version == "" && modload.MainModules.Contains(curM.Path) {
695                                 return errSet(&modload.QueryMatchesMainModulesError{MainModules: []module.Version{curM}, Pattern: q.pattern, Query: q.version})
696                         }
697                         return pathSet{mod: module.Version{Path: curM.Path, Version: "none"}}
698                 })
699         }
700 }
701
702 func (r *resolver) performLocalQueries(ctx context.Context) {
703         for _, q := range r.localQueries {
704                 q.pathOnce(q.pattern, func() pathSet {
705                         absDetail := ""
706                         if !filepath.IsAbs(q.pattern) {
707                                 if absPath, err := filepath.Abs(q.pattern); err == nil {
708                                         absDetail = fmt.Sprintf(" (%s)", absPath)
709                                 }
710                         }
711
712                         // Absolute paths like C:\foo and relative paths like ../foo... are
713                         // restricted to matching packages in the main module.
714                         pkgPattern, mainModule := modload.MainModules.DirImportPath(ctx, q.pattern)
715                         if pkgPattern == "." {
716                                 modload.MustHaveModRoot()
717                                 var modRoots []string
718                                 for _, m := range modload.MainModules.Versions() {
719                                         modRoots = append(modRoots, modload.MainModules.ModRoot(m))
720                                 }
721                                 var plural string
722                                 if len(modRoots) != 1 {
723                                         plural = "s"
724                                 }
725                                 return errSet(fmt.Errorf("%s%s is not within module%s rooted at %s", q.pattern, absDetail, plural, strings.Join(modRoots, ", ")))
726                         }
727
728                         match := modload.MatchInModule(ctx, pkgPattern, mainModule, imports.AnyTags())
729                         if len(match.Errs) > 0 {
730                                 return pathSet{err: match.Errs[0]}
731                         }
732
733                         if len(match.Pkgs) == 0 {
734                                 if q.raw == "" || q.raw == "." {
735                                         return errSet(fmt.Errorf("no package to get in current directory"))
736                                 }
737                                 if !q.isWildcard() {
738                                         modload.MustHaveModRoot()
739                                         return errSet(fmt.Errorf("%s%s is not a package in module rooted at %s", q.pattern, absDetail, modload.MainModules.ModRoot(mainModule)))
740                                 }
741                                 search.WarnUnmatched([]*search.Match{match})
742                                 return pathSet{}
743                         }
744
745                         return pathSet{pkgMods: []module.Version{mainModule}}
746                 })
747         }
748 }
749
750 // performWildcardQueries populates the candidates for each query whose pattern
751 // is a wildcard.
752 //
753 // The candidates for a given module path matching (or containing a package
754 // matching) a wildcard query depend only on the initial build list, but the set
755 // of modules may be expanded by other queries, so wildcard queries need to be
756 // re-evaluated whenever a potentially-matching module path is added to the
757 // build list.
758 func (r *resolver) performWildcardQueries(ctx context.Context) {
759         for _, q := range r.wildcardQueries {
760                 q := q
761                 r.work.Add(func() {
762                         if q.version == "none" {
763                                 r.queryNone(ctx, q)
764                         } else {
765                                 r.queryWildcard(ctx, q)
766                         }
767                 })
768         }
769         <-r.work.Idle()
770 }
771
772 // queryWildcard adds a candidate set to q for each module for which:
773 //   - some version of the module is already in the build list, and
774 //   - that module exists at some version matching q.version, and
775 //   - either the module path itself matches q.pattern, or some package within
776 //     the module at q.version matches q.pattern.
777 func (r *resolver) queryWildcard(ctx context.Context, q *query) {
778         // For wildcard patterns, modload.QueryPattern only identifies modules
779         // matching the prefix of the path before the wildcard. However, the build
780         // list may already contain other modules with matching packages, and we
781         // should consider those modules to satisfy the query too.
782         // We want to match any packages in existing dependencies, but we only want to
783         // resolve new dependencies if nothing else turns up.
784         for _, curM := range r.buildList {
785                 if !q.canMatchInModule(curM.Path) {
786                         continue
787                 }
788                 q.pathOnce(curM.Path, func() pathSet {
789                         if _, hit := r.noneForPath(curM.Path); hit {
790                                 // This module is being removed, so it will no longer be in the build list
791                                 // (and thus will no longer match the pattern).
792                                 return pathSet{}
793                         }
794
795                         if modload.MainModules.Contains(curM.Path) && !versionOkForMainModule(q.version) {
796                                 if q.matchesPath(curM.Path) {
797                                         return errSet(&modload.QueryMatchesMainModulesError{
798                                                 MainModules: []module.Version{curM},
799                                                 Pattern:     q.pattern,
800                                                 Query:       q.version,
801                                         })
802                                 }
803
804                                 packages, err := r.matchInModule(ctx, q.pattern, curM)
805                                 if err != nil {
806                                         return errSet(err)
807                                 }
808                                 if len(packages) > 0 {
809                                         return errSet(&modload.QueryMatchesPackagesInMainModuleError{
810                                                 Pattern:  q.pattern,
811                                                 Query:    q.version,
812                                                 Packages: packages,
813                                         })
814                                 }
815
816                                 return r.tryWildcard(ctx, q, curM)
817                         }
818
819                         m, err := r.queryModule(ctx, curM.Path, q.version, r.initialSelected)
820                         if err != nil {
821                                 if !isNoSuchModuleVersion(err) {
822                                         // We can't tell whether a matching version exists.
823                                         return errSet(err)
824                                 }
825                                 // There is no version of curM.Path matching the query.
826
827                                 // We haven't checked whether curM contains any matching packages at its
828                                 // currently-selected version, or whether curM.Path itself matches q. If
829                                 // either of those conditions holds, *and* no other query changes the
830                                 // selected version of curM, then we will fail in checkWildcardVersions.
831                                 // (This could be an error, but it's too soon to tell.)
832                                 //
833                                 // However, even then the transitive requirements of some other query
834                                 // may downgrade this module out of the build list entirely, in which
835                                 // case the pattern will no longer include it and it won't be an error.
836                                 //
837                                 // Either way, punt on the query rather than erroring out just yet.
838                                 return pathSet{}
839                         }
840
841                         return r.tryWildcard(ctx, q, m)
842                 })
843         }
844
845         // Even if no modules matched, we shouldn't query for a new module to provide
846         // the pattern yet: some other query may yet induce a new requirement that
847         // will match the wildcard. Instead, we'll check in findMissingWildcards.
848 }
849
850 // tryWildcard returns a pathSet for module m matching query q.
851 // If m does not actually match q, tryWildcard returns an empty pathSet.
852 func (r *resolver) tryWildcard(ctx context.Context, q *query, m module.Version) pathSet {
853         mMatches := q.matchesPath(m.Path)
854         packages, err := r.matchInModule(ctx, q.pattern, m)
855         if err != nil {
856                 return errSet(err)
857         }
858         if len(packages) > 0 {
859                 return pathSet{pkgMods: []module.Version{m}}
860         }
861         if mMatches {
862                 return pathSet{mod: m}
863         }
864         return pathSet{}
865 }
866
867 // findMissingWildcards adds a candidate set for each query in r.wildcardQueries
868 // that has not yet resolved to any version containing packages.
869 func (r *resolver) findMissingWildcards(ctx context.Context) {
870         for _, q := range r.wildcardQueries {
871                 if q.version == "none" || q.matchesPackages {
872                         continue // q is not “missing”
873                 }
874                 r.work.Add(func() {
875                         q.pathOnce(q.pattern, func() pathSet {
876                                 pkgMods, mod, err := r.queryPattern(ctx, q.pattern, q.version, r.initialSelected)
877                                 if err != nil {
878                                         if isNoSuchPackageVersion(err) && len(q.resolved) > 0 {
879                                                 // q already resolved one or more modules but matches no packages.
880                                                 // That's ok: this pattern is just a module pattern, and we don't
881                                                 // need to add any more modules to satisfy it.
882                                                 return pathSet{}
883                                         }
884                                         return errSet(err)
885                                 }
886
887                                 return pathSet{pkgMods: pkgMods, mod: mod}
888                         })
889                 })
890         }
891         <-r.work.Idle()
892 }
893
894 // checkWildcardVersions reports an error if any module in the build list has a
895 // path (or contains a package) matching a query with a wildcard pattern, but
896 // has a selected version that does *not* match the query.
897 func (r *resolver) checkWildcardVersions(ctx context.Context) {
898         defer base.ExitIfErrors()
899
900         for _, q := range r.wildcardQueries {
901                 for _, curM := range r.buildList {
902                         if !q.canMatchInModule(curM.Path) {
903                                 continue
904                         }
905                         if !q.matchesPath(curM.Path) {
906                                 packages, err := r.matchInModule(ctx, q.pattern, curM)
907                                 if len(packages) == 0 {
908                                         if err != nil {
909                                                 reportError(q, err)
910                                         }
911                                         continue // curM is not relevant to q.
912                                 }
913                         }
914
915                         rev, err := r.queryModule(ctx, curM.Path, q.version, r.initialSelected)
916                         if err != nil {
917                                 reportError(q, err)
918                                 continue
919                         }
920                         if rev.Version == curM.Version {
921                                 continue // curM already matches q.
922                         }
923
924                         if !q.matchesPath(curM.Path) {
925                                 m := module.Version{Path: curM.Path, Version: rev.Version}
926                                 packages, err := r.matchInModule(ctx, q.pattern, m)
927                                 if err != nil {
928                                         reportError(q, err)
929                                         continue
930                                 }
931                                 if len(packages) == 0 {
932                                         // curM at its original version contains a path matching q.pattern,
933                                         // but at rev.Version it does not, so (somewhat paradoxically) if
934                                         // we changed the version of curM it would no longer match the query.
935                                         var version any = m
936                                         if rev.Version != q.version {
937                                                 version = fmt.Sprintf("%s@%s (%s)", m.Path, q.version, m.Version)
938                                         }
939                                         reportError(q, fmt.Errorf("%v matches packages in %v but not %v: specify a different version for module %s", q, curM, version, m.Path))
940                                         continue
941                                 }
942                         }
943
944                         // Since queryModule succeeded and either curM or one of the packages it
945                         // contains matches q.pattern, we should have either selected the version
946                         // of curM matching q, or reported a conflict error (and exited).
947                         // If we're still here and the version doesn't match,
948                         // something has gone very wrong.
949                         reportError(q, fmt.Errorf("internal error: selected %v instead of %v", curM, rev.Version))
950                 }
951         }
952 }
953
954 // performPathQueries populates the candidates for each query whose pattern is
955 // a path literal.
956 //
957 // The candidate packages and modules for path literals depend only on the
958 // initial build list, not the current build list, so we only need to query path
959 // literals once.
960 func (r *resolver) performPathQueries(ctx context.Context) {
961         for _, q := range r.pathQueries {
962                 q := q
963                 r.work.Add(func() {
964                         if q.version == "none" {
965                                 r.queryNone(ctx, q)
966                         } else {
967                                 r.queryPath(ctx, q)
968                         }
969                 })
970         }
971         <-r.work.Idle()
972 }
973
974 // queryPath adds a candidate set to q for the package with path q.pattern.
975 // The candidate set consists of all modules that could provide q.pattern
976 // and have a version matching q, plus (if it exists) the module whose path
977 // is itself q.pattern (at a matching version).
978 func (r *resolver) queryPath(ctx context.Context, q *query) {
979         q.pathOnce(q.pattern, func() pathSet {
980                 if search.IsMetaPackage(q.pattern) || q.isWildcard() {
981                         panic(fmt.Sprintf("internal error: queryPath called with pattern %q", q.pattern))
982                 }
983                 if q.version == "none" {
984                         panic(`internal error: queryPath called with version "none"`)
985                 }
986
987                 if search.IsStandardImportPath(q.pattern) {
988                         stdOnly := module.Version{}
989                         packages, _ := r.matchInModule(ctx, q.pattern, stdOnly)
990                         if len(packages) > 0 {
991                                 if q.rawVersion != "" {
992                                         return errSet(fmt.Errorf("can't request explicit version %q of standard library package %s", q.version, q.pattern))
993                                 }
994
995                                 q.matchesPackages = true
996                                 return pathSet{} // No module needed for standard library.
997                         }
998                 }
999
1000                 pkgMods, mod, err := r.queryPattern(ctx, q.pattern, q.version, r.initialSelected)
1001                 if err != nil {
1002                         return errSet(err)
1003                 }
1004                 return pathSet{pkgMods: pkgMods, mod: mod}
1005         })
1006 }
1007
1008 // performPatternAllQueries populates the candidates for each query whose
1009 // pattern is "all".
1010 //
1011 // The candidate modules for a given package in "all" depend only on the initial
1012 // build list, but we cannot follow the dependencies of a given package until we
1013 // know which candidate is selected — and that selection may depend on the
1014 // results of other queries. We need to re-evaluate the "all" queries whenever
1015 // the module for one or more packages in "all" are resolved.
1016 func (r *resolver) performPatternAllQueries(ctx context.Context) {
1017         if len(r.patternAllQueries) == 0 {
1018                 return
1019         }
1020
1021         findPackage := func(ctx context.Context, path string, m module.Version) (versionOk bool) {
1022                 versionOk = true
1023                 for _, q := range r.patternAllQueries {
1024                         q.pathOnce(path, func() pathSet {
1025                                 pkgMods, err := r.queryPackages(ctx, path, q.version, r.initialSelected)
1026                                 if len(pkgMods) != 1 || pkgMods[0] != m {
1027                                         // There are candidates other than m for the given path, so we can't
1028                                         // be certain that m will actually be the module selected to provide
1029                                         // the package. Don't load its dependencies just yet, because they
1030                                         // might no longer be dependencies after we resolve the correct
1031                                         // version.
1032                                         versionOk = false
1033                                 }
1034                                 return pathSet{pkgMods: pkgMods, err: err}
1035                         })
1036                 }
1037                 return versionOk
1038         }
1039
1040         r.loadPackages(ctx, []string{"all"}, findPackage)
1041
1042         // Since we built up the candidate lists concurrently, they may be in a
1043         // nondeterministic order. We want 'go get' to be fully deterministic,
1044         // including in which errors it chooses to report, so sort the candidates
1045         // into a deterministic-but-arbitrary order.
1046         for _, q := range r.patternAllQueries {
1047                 sort.Slice(q.candidates, func(i, j int) bool {
1048                         return q.candidates[i].path < q.candidates[j].path
1049                 })
1050         }
1051 }
1052
1053 // findAndUpgradeImports returns a pathSet for each package that is not yet
1054 // in the build list but is transitively imported by the packages matching the
1055 // given queries (which must already have been resolved).
1056 //
1057 // If the getU flag ("-u") is set, findAndUpgradeImports also returns a
1058 // pathSet for each module that is not constrained by any other
1059 // command-line argument and has an available matching upgrade.
1060 func (r *resolver) findAndUpgradeImports(ctx context.Context, queries []*query) (upgrades []pathSet) {
1061         patterns := make([]string, 0, len(queries))
1062         for _, q := range queries {
1063                 if q.matchesPackages {
1064                         patterns = append(patterns, q.pattern)
1065                 }
1066         }
1067         if len(patterns) == 0 {
1068                 return nil
1069         }
1070
1071         // mu guards concurrent writes to upgrades, which will be sorted
1072         // (to restore determinism) after loading.
1073         var mu sync.Mutex
1074
1075         findPackage := func(ctx context.Context, path string, m module.Version) (versionOk bool) {
1076                 version := "latest"
1077                 if m.Path != "" {
1078                         if getU.version == "" {
1079                                 // The user did not request that we upgrade transitive dependencies.
1080                                 return true
1081                         }
1082                         if _, ok := r.resolvedVersion[m.Path]; ok {
1083                                 // We cannot upgrade m implicitly because its version is determined by
1084                                 // an explicit pattern argument.
1085                                 return true
1086                         }
1087                         version = getU.version
1088                 }
1089
1090                 // Unlike other queries, the "-u" flag upgrades relative to the build list
1091                 // after applying changes so far, not the initial build list.
1092                 // This is for two reasons:
1093                 //
1094                 //      - The "-u" flag intentionally applies to transitive dependencies,
1095                 //        which may not be known or even resolved in advance of applying
1096                 //        other version changes.
1097                 //
1098                 //      - The "-u" flag, unlike other arguments, does not cause version
1099                 //        conflicts with other queries. (The other query always wins.)
1100
1101                 pkgMods, err := r.queryPackages(ctx, path, version, r.selected)
1102                 for _, u := range pkgMods {
1103                         if u == m {
1104                                 // The selected package version is already upgraded appropriately; there
1105                                 // is no need to change it.
1106                                 return true
1107                         }
1108                 }
1109
1110                 if err != nil {
1111                         if isNoSuchPackageVersion(err) || (m.Path == "" && module.CheckPath(path) != nil) {
1112                                 // We can't find the package because it doesn't — or can't — even exist
1113                                 // in any module at the latest version. (Note that invalid module paths
1114                                 // could in general exist due to replacements, so we at least need to
1115                                 // run the query to check those.)
1116                                 //
1117                                 // There is no version change we can make to fix the package, so leave
1118                                 // it unresolved. Either some other query (perhaps a wildcard matching a
1119                                 // newly-added dependency for some other missing package) will fill in
1120                                 // the gaps, or we will report an error (with a better import stack) in
1121                                 // the final LoadPackages call.
1122                                 return true
1123                         }
1124                 }
1125
1126                 mu.Lock()
1127                 upgrades = append(upgrades, pathSet{path: path, pkgMods: pkgMods, err: err})
1128                 mu.Unlock()
1129                 return false
1130         }
1131
1132         r.loadPackages(ctx, patterns, findPackage)
1133
1134         // Since we built up the candidate lists concurrently, they may be in a
1135         // nondeterministic order. We want 'go get' to be fully deterministic,
1136         // including in which errors it chooses to report, so sort the candidates
1137         // into a deterministic-but-arbitrary order.
1138         sort.Slice(upgrades, func(i, j int) bool {
1139                 return upgrades[i].path < upgrades[j].path
1140         })
1141         return upgrades
1142 }
1143
1144 // loadPackages loads the packages matching the given patterns, invoking the
1145 // findPackage function for each package that may require a change to the
1146 // build list.
1147 //
1148 // loadPackages invokes the findPackage function for each package loaded from a
1149 // module outside the main module. If the module or version that supplies that
1150 // package needs to be changed due to a query, findPackage may return false
1151 // and the imports of that package will not be loaded.
1152 //
1153 // loadPackages also invokes the findPackage function for each imported package
1154 // that is neither present in the standard library nor in any module in the
1155 // build list.
1156 func (r *resolver) loadPackages(ctx context.Context, patterns []string, findPackage func(ctx context.Context, path string, m module.Version) (versionOk bool)) {
1157         opts := modload.PackageOpts{
1158                 Tags:                     imports.AnyTags(),
1159                 VendorModulesInGOROOTSrc: true,
1160                 LoadTests:                *getT,
1161                 AssumeRootsImported:      true, // After 'go get foo', imports of foo should build.
1162                 SilencePackageErrors:     true, // May be fixed by subsequent upgrades or downgrades.
1163                 Switcher:                 new(toolchain.Switcher),
1164         }
1165
1166         opts.AllowPackage = func(ctx context.Context, path string, m module.Version) error {
1167                 if m.Path == "" || m.Version == "" {
1168                         // Packages in the standard library and main modules are already at their
1169                         // latest (and only) available versions.
1170                         return nil
1171                 }
1172                 if ok := findPackage(ctx, path, m); !ok {
1173                         return errVersionChange
1174                 }
1175                 return nil
1176         }
1177
1178         _, pkgs := modload.LoadPackages(ctx, opts, patterns...)
1179         for _, path := range pkgs {
1180                 const (
1181                         parentPath  = ""
1182                         parentIsStd = false
1183                 )
1184                 _, _, err := modload.Lookup(parentPath, parentIsStd, path)
1185                 if err == nil {
1186                         continue
1187                 }
1188                 if errors.Is(err, errVersionChange) {
1189                         // We already added candidates during loading.
1190                         continue
1191                 }
1192
1193                 var (
1194                         importMissing *modload.ImportMissingError
1195                         ambiguous     *modload.AmbiguousImportError
1196                 )
1197                 if !errors.As(err, &importMissing) && !errors.As(err, &ambiguous) {
1198                         // The package, which is a dependency of something we care about, has some
1199                         // problem that we can't resolve with a version change.
1200                         // Leave the error for the final LoadPackages call.
1201                         continue
1202                 }
1203
1204                 path := path
1205                 r.work.Add(func() {
1206                         findPackage(ctx, path, module.Version{})
1207                 })
1208         }
1209         <-r.work.Idle()
1210 }
1211
1212 // errVersionChange is a sentinel error indicating that a module's version needs
1213 // to be updated before its dependencies can be loaded.
1214 var errVersionChange = errors.New("version change needed")
1215
1216 // resolveQueries resolves candidate sets that are attached to the given
1217 // queries and/or needed to provide the given missing-package dependencies.
1218 //
1219 // resolveQueries starts by resolving one module version from each
1220 // unambiguous pathSet attached to the given queries.
1221 //
1222 // If no unambiguous query results in a change to the build list,
1223 // resolveQueries revisits the ambiguous query candidates and resolves them
1224 // arbitrarily in order to guarantee forward progress.
1225 //
1226 // If all pathSets are resolved without any changes to the build list,
1227 // resolveQueries returns with changed=false.
1228 func (r *resolver) resolveQueries(ctx context.Context, queries []*query) (changed bool) {
1229         defer base.ExitIfErrors()
1230
1231         // Note: this is O(N²) with the number of pathSets in the worst case.
1232         //
1233         // We could perhaps get it down to O(N) if we were to index the pathSets
1234         // by module path, so that we only revisit a given pathSet when the
1235         // version of some module in its containingPackage list has been determined.
1236         //
1237         // However, N tends to be small, and most candidate sets will include only one
1238         // candidate module (so they will be resolved in the first iteration), so for
1239         // now we'll stick to the simple O(N²) approach.
1240
1241         resolved := 0
1242         for {
1243                 prevResolved := resolved
1244
1245                 // If we found modules that were too new, find the max of the required versions
1246                 // and then try to switch to a newer toolchain.
1247                 var sw toolchain.Switcher
1248                 for _, q := range queries {
1249                         for _, cs := range q.candidates {
1250                                 sw.Error(cs.err)
1251                         }
1252                 }
1253                 // Only switch if we need a newer toolchain.
1254                 // Otherwise leave the cs.err for reporting later.
1255                 if sw.NeedSwitch() {
1256                         sw.Switch(ctx)
1257                         // If NeedSwitch is true and Switch returns, Switch has failed to locate a newer toolchain.
1258                         // It printed the errors along with one more about not finding a good toolchain.
1259                         base.Exit()
1260                 }
1261
1262                 for _, q := range queries {
1263                         unresolved := q.candidates[:0]
1264
1265                         for _, cs := range q.candidates {
1266                                 if cs.err != nil {
1267                                         reportError(q, cs.err)
1268                                         resolved++
1269                                         continue
1270                                 }
1271
1272                                 filtered, isPackage, m, unique := r.disambiguate(cs)
1273                                 if !unique {
1274                                         unresolved = append(unresolved, filtered)
1275                                         continue
1276                                 }
1277
1278                                 if m.Path == "" {
1279                                         // The query is not viable. Choose an arbitrary candidate from
1280                                         // before filtering and “resolve” it to report a conflict.
1281                                         isPackage, m = r.chooseArbitrarily(cs)
1282                                 }
1283                                 if isPackage {
1284                                         q.matchesPackages = true
1285                                 }
1286                                 r.resolve(q, m)
1287                                 resolved++
1288                         }
1289
1290                         q.candidates = unresolved
1291                 }
1292
1293                 base.ExitIfErrors()
1294                 if resolved == prevResolved {
1295                         break // No unambiguous candidate remains.
1296                 }
1297         }
1298
1299         if resolved > 0 {
1300                 if changed = r.updateBuildList(ctx, nil); changed {
1301                         // The build list has changed, so disregard any remaining ambiguous queries:
1302                         // they might now be determined by requirements in the build list, which we
1303                         // would prefer to use instead of arbitrary versions.
1304                         return true
1305                 }
1306         }
1307
1308         // The build list will be the same on the next iteration as it was on this
1309         // iteration, so any ambiguous queries will remain so. In order to make
1310         // progress, resolve them arbitrarily but deterministically.
1311         //
1312         // If that results in conflicting versions, the user can re-run 'go get'
1313         // with additional explicit versions for the conflicting packages or
1314         // modules.
1315         resolvedArbitrarily := 0
1316         for _, q := range queries {
1317                 for _, cs := range q.candidates {
1318                         isPackage, m := r.chooseArbitrarily(cs)
1319                         if isPackage {
1320                                 q.matchesPackages = true
1321                         }
1322                         r.resolve(q, m)
1323                         resolvedArbitrarily++
1324                 }
1325         }
1326         if resolvedArbitrarily > 0 {
1327                 changed = r.updateBuildList(ctx, nil)
1328         }
1329         return changed
1330 }
1331
1332 // applyUpgrades disambiguates candidate sets that are needed to upgrade (or
1333 // provide) transitive dependencies imported by previously-resolved packages.
1334 //
1335 // applyUpgrades modifies the build list by adding one module version from each
1336 // pathSet in upgrades, then downgrading (or further upgrading) those modules as
1337 // needed to maintain any already-resolved versions of other modules.
1338 // applyUpgrades does not mark the new versions as resolved, so they can still
1339 // be further modified by other queries (such as wildcards).
1340 //
1341 // If all pathSets are resolved without any changes to the build list,
1342 // applyUpgrades returns with changed=false.
1343 func (r *resolver) applyUpgrades(ctx context.Context, upgrades []pathSet) (changed bool) {
1344         defer base.ExitIfErrors()
1345
1346         // Arbitrarily add a "latest" version that provides each missing package, but
1347         // do not mark the version as resolved: we still want to allow the explicit
1348         // queries to modify the resulting versions.
1349         var tentative []module.Version
1350         for _, cs := range upgrades {
1351                 if cs.err != nil {
1352                         base.Error(cs.err)
1353                         continue
1354                 }
1355
1356                 filtered, _, m, unique := r.disambiguate(cs)
1357                 if !unique {
1358                         _, m = r.chooseArbitrarily(filtered)
1359                 }
1360                 if m.Path == "" {
1361                         // There is no viable candidate for the missing package.
1362                         // Leave it unresolved.
1363                         continue
1364                 }
1365                 tentative = append(tentative, m)
1366         }
1367         base.ExitIfErrors()
1368
1369         changed = r.updateBuildList(ctx, tentative)
1370         return changed
1371 }
1372
1373 // disambiguate eliminates candidates from cs that conflict with other module
1374 // versions that have already been resolved. If there is only one (unique)
1375 // remaining candidate, disambiguate returns that candidate, along with
1376 // an indication of whether that result interprets cs.path as a package
1377 //
1378 // Note: we're only doing very simple disambiguation here. The goal is to
1379 // reproduce the user's intent, not to find a solution that a human couldn't.
1380 // In the vast majority of cases, we expect only one module per pathSet,
1381 // but we want to give some minimal additional tools so that users can add an
1382 // extra argument or two on the command line to resolve simple ambiguities.
1383 func (r *resolver) disambiguate(cs pathSet) (filtered pathSet, isPackage bool, m module.Version, unique bool) {
1384         if len(cs.pkgMods) == 0 && cs.mod.Path == "" {
1385                 panic("internal error: resolveIfUnambiguous called with empty pathSet")
1386         }
1387
1388         for _, m := range cs.pkgMods {
1389                 if _, ok := r.noneForPath(m.Path); ok {
1390                         // A query with version "none" forces the candidate module to version
1391                         // "none", so we cannot use any other version for that module.
1392                         continue
1393                 }
1394
1395                 if modload.MainModules.Contains(m.Path) {
1396                         if m.Version == "" {
1397                                 return pathSet{}, true, m, true
1398                         }
1399                         // A main module can only be set to its own version.
1400                         continue
1401                 }
1402
1403                 vr, ok := r.resolvedVersion[m.Path]
1404                 if !ok {
1405                         // m is a viable answer to the query, but other answers may also
1406                         // still be viable.
1407                         filtered.pkgMods = append(filtered.pkgMods, m)
1408                         continue
1409                 }
1410
1411                 if vr.version != m.Version {
1412                         // Some query forces the candidate module to a version other than this
1413                         // one.
1414                         //
1415                         // The command could be something like
1416                         //
1417                         //      go get example.com/foo/bar@none example.com/foo/bar/baz@latest
1418                         //
1419                         // in which case we *cannot* resolve the package from
1420                         // example.com/foo/bar (because it is constrained to version
1421                         // "none") and must fall through to module example.com/foo@latest.
1422                         continue
1423                 }
1424
1425                 // Some query forces the candidate module *to* the candidate version.
1426                 // As a result, this candidate is the only viable choice to provide
1427                 // its package(s): any other choice would result in an ambiguous import
1428                 // for this path.
1429                 //
1430                 // For example, consider the command
1431                 //
1432                 //      go get example.com/foo@latest example.com/foo/bar/baz@latest
1433                 //
1434                 // If modules example.com/foo and example.com/foo/bar both provide
1435                 // package example.com/foo/bar/baz, then we *must* resolve the package
1436                 // from example.com/foo: if we instead resolved it from
1437                 // example.com/foo/bar, we would have two copies of the package.
1438                 return pathSet{}, true, m, true
1439         }
1440
1441         if cs.mod.Path != "" {
1442                 vr, ok := r.resolvedVersion[cs.mod.Path]
1443                 if !ok || vr.version == cs.mod.Version {
1444                         filtered.mod = cs.mod
1445                 }
1446         }
1447
1448         if len(filtered.pkgMods) == 1 &&
1449                 (filtered.mod.Path == "" || filtered.mod == filtered.pkgMods[0]) {
1450                 // Exactly one viable module contains the package with the given path
1451                 // (by far the common case), so we can resolve it unambiguously.
1452                 return pathSet{}, true, filtered.pkgMods[0], true
1453         }
1454
1455         if len(filtered.pkgMods) == 0 {
1456                 // All modules that could provide the path as a package conflict with other
1457                 // resolved arguments. If it can refer to a module instead, return that;
1458                 // otherwise, this pathSet cannot be resolved (and we will return the
1459                 // zero module.Version).
1460                 return pathSet{}, false, filtered.mod, true
1461         }
1462
1463         // The query remains ambiguous: there are at least two different modules
1464         // to which cs.path could refer.
1465         return filtered, false, module.Version{}, false
1466 }
1467
1468 // chooseArbitrarily returns an arbitrary (but deterministic) module version
1469 // from among those in the given set.
1470 //
1471 // chooseArbitrarily prefers module paths that were already in the build list at
1472 // the start of 'go get', prefers modules that provide packages over those that
1473 // do not, and chooses the first module meeting those criteria (so biases toward
1474 // longer paths).
1475 func (r *resolver) chooseArbitrarily(cs pathSet) (isPackage bool, m module.Version) {
1476         // Prefer to upgrade some module that was already in the build list.
1477         for _, m := range cs.pkgMods {
1478                 if r.initialSelected(m.Path) != "none" {
1479                         return true, m
1480                 }
1481         }
1482
1483         // Otherwise, arbitrarily choose the first module that provides the package.
1484         if len(cs.pkgMods) > 0 {
1485                 return true, cs.pkgMods[0]
1486         }
1487
1488         return false, cs.mod
1489 }
1490
1491 // checkPackageProblems reloads packages for the given patterns and reports
1492 // missing and ambiguous package errors. It also reports retractions and
1493 // deprecations for resolved modules and modules needed to build named packages.
1494 // It also adds a sum for each updated module in the build list if we had one
1495 // before and didn't get one while loading packages.
1496 //
1497 // We skip missing-package errors earlier in the process, since we want to
1498 // resolve pathSets ourselves, but at that point, we don't have enough context
1499 // to log the package-import chains leading to each error.
1500 func (r *resolver) checkPackageProblems(ctx context.Context, pkgPatterns []string) {
1501         defer base.ExitIfErrors()
1502
1503         // Gather information about modules we might want to load retractions and
1504         // deprecations for. Loading this metadata requires at least one version
1505         // lookup per module, and we don't want to load information that's neither
1506         // relevant nor actionable.
1507         type modFlags int
1508         const (
1509                 resolved modFlags = 1 << iota // version resolved by 'go get'
1510                 named                         // explicitly named on command line or provides a named package
1511                 hasPkg                        // needed to build named packages
1512                 direct                        // provides a direct dependency of the main module
1513         )
1514         relevantMods := make(map[module.Version]modFlags)
1515         for path, reason := range r.resolvedVersion {
1516                 m := module.Version{Path: path, Version: reason.version}
1517                 relevantMods[m] |= resolved
1518         }
1519
1520         // Reload packages, reporting errors for missing and ambiguous imports.
1521         if len(pkgPatterns) > 0 {
1522                 // LoadPackages will print errors (since it has more context) but will not
1523                 // exit, since we need to load retractions later.
1524                 pkgOpts := modload.PackageOpts{
1525                         VendorModulesInGOROOTSrc: true,
1526                         LoadTests:                *getT,
1527                         ResolveMissingImports:    false,
1528                         AllowErrors:              true,
1529                         SilenceNoGoErrors:        true,
1530                 }
1531                 matches, pkgs := modload.LoadPackages(ctx, pkgOpts, pkgPatterns...)
1532                 for _, m := range matches {
1533                         if len(m.Errs) > 0 {
1534                                 base.SetExitStatus(1)
1535                                 break
1536                         }
1537                 }
1538                 for _, pkg := range pkgs {
1539                         if dir, _, err := modload.Lookup("", false, pkg); err != nil {
1540                                 if dir != "" && errors.Is(err, imports.ErrNoGo) {
1541                                         // Since dir is non-empty, we must have located source files
1542                                         // associated with either the package or its test — ErrNoGo must
1543                                         // indicate that none of those source files happen to apply in this
1544                                         // configuration. If we are actually building the package (no -d
1545                                         // flag), we will report the problem then; otherwise, assume that the
1546                                         // user is going to build or test this package in some other
1547                                         // configuration and suppress the error.
1548                                         continue
1549                                 }
1550
1551                                 base.SetExitStatus(1)
1552                                 if ambiguousErr := (*modload.AmbiguousImportError)(nil); errors.As(err, &ambiguousErr) {
1553                                         for _, m := range ambiguousErr.Modules {
1554                                                 relevantMods[m] |= hasPkg
1555                                         }
1556                                 }
1557                         }
1558                         if m := modload.PackageModule(pkg); m.Path != "" {
1559                                 relevantMods[m] |= hasPkg
1560                         }
1561                 }
1562                 for _, match := range matches {
1563                         for _, pkg := range match.Pkgs {
1564                                 m := modload.PackageModule(pkg)
1565                                 relevantMods[m] |= named
1566                         }
1567                 }
1568         }
1569
1570         reqs := modload.LoadModFile(ctx)
1571         for m := range relevantMods {
1572                 if reqs.IsDirect(m.Path) {
1573                         relevantMods[m] |= direct
1574                 }
1575         }
1576
1577         // Load retractions for modules mentioned on the command line and modules
1578         // needed to build named packages. We care about retractions of indirect
1579         // dependencies, since we might be able to upgrade away from them.
1580         type modMessage struct {
1581                 m       module.Version
1582                 message string
1583         }
1584         retractions := make([]modMessage, 0, len(relevantMods))
1585         for m, flags := range relevantMods {
1586                 if flags&(resolved|named|hasPkg) != 0 {
1587                         retractions = append(retractions, modMessage{m: m})
1588                 }
1589         }
1590         sort.Slice(retractions, func(i, j int) bool { return retractions[i].m.Path < retractions[j].m.Path })
1591         for i := range retractions {
1592                 i := i
1593                 r.work.Add(func() {
1594                         err := modload.CheckRetractions(ctx, retractions[i].m)
1595                         if retractErr := (*modload.ModuleRetractedError)(nil); errors.As(err, &retractErr) {
1596                                 retractions[i].message = err.Error()
1597                         }
1598                 })
1599         }
1600
1601         // Load deprecations for modules mentioned on the command line. Only load
1602         // deprecations for indirect dependencies if they're also direct dependencies
1603         // of the main module. Deprecations of purely indirect dependencies are
1604         // not actionable.
1605         deprecations := make([]modMessage, 0, len(relevantMods))
1606         for m, flags := range relevantMods {
1607                 if flags&(resolved|named) != 0 || flags&(hasPkg|direct) == hasPkg|direct {
1608                         deprecations = append(deprecations, modMessage{m: m})
1609                 }
1610         }
1611         sort.Slice(deprecations, func(i, j int) bool { return deprecations[i].m.Path < deprecations[j].m.Path })
1612         for i := range deprecations {
1613                 i := i
1614                 r.work.Add(func() {
1615                         deprecation, err := modload.CheckDeprecation(ctx, deprecations[i].m)
1616                         if err != nil || deprecation == "" {
1617                                 return
1618                         }
1619                         deprecations[i].message = modload.ShortMessage(deprecation, "")
1620                 })
1621         }
1622
1623         // Load sums for updated modules that had sums before. When we update a
1624         // module, we may update another module in the build list that provides a
1625         // package in 'all' that wasn't loaded as part of this 'go get' command.
1626         // If we don't add a sum for that module, builds may fail later.
1627         // Note that an incidentally updated package could still import packages
1628         // from unknown modules or from modules in the build list that we didn't
1629         // need previously. We can't handle that case without loading 'all'.
1630         sumErrs := make([]error, len(r.buildList))
1631         for i := range r.buildList {
1632                 i := i
1633                 m := r.buildList[i]
1634                 mActual := m
1635                 if mRepl := modload.Replacement(m); mRepl.Path != "" {
1636                         mActual = mRepl
1637                 }
1638                 old := module.Version{Path: m.Path, Version: r.initialVersion[m.Path]}
1639                 if old.Version == "" {
1640                         continue
1641                 }
1642                 oldActual := old
1643                 if oldRepl := modload.Replacement(old); oldRepl.Path != "" {
1644                         oldActual = oldRepl
1645                 }
1646                 if mActual == oldActual || mActual.Version == "" || !modfetch.HaveSum(oldActual) {
1647                         continue
1648                 }
1649                 r.work.Add(func() {
1650                         if _, err := modfetch.DownloadZip(ctx, mActual); err != nil {
1651                                 verb := "upgraded"
1652                                 if gover.ModCompare(m.Path, m.Version, old.Version) < 0 {
1653                                         verb = "downgraded"
1654                                 }
1655                                 replaced := ""
1656                                 if mActual != m {
1657                                         replaced = fmt.Sprintf(" (replaced by %s)", mActual)
1658                                 }
1659                                 err = fmt.Errorf("%s %s %s => %s%s: error finding sum for %s: %v", verb, m.Path, old.Version, m.Version, replaced, mActual, err)
1660                                 sumErrs[i] = err
1661                         }
1662                 })
1663         }
1664
1665         <-r.work.Idle()
1666
1667         // Report deprecations, then retractions, then errors fetching sums.
1668         // Only errors fetching sums are hard errors.
1669         for _, mm := range deprecations {
1670                 if mm.message != "" {
1671                         fmt.Fprintf(os.Stderr, "go: module %s is deprecated: %s\n", mm.m.Path, mm.message)
1672                 }
1673         }
1674         var retractPath string
1675         for _, mm := range retractions {
1676                 if mm.message != "" {
1677                         fmt.Fprintf(os.Stderr, "go: warning: %v\n", mm.message)
1678                         if retractPath == "" {
1679                                 retractPath = mm.m.Path
1680                         } else {
1681                                 retractPath = "<module>"
1682                         }
1683                 }
1684         }
1685         if retractPath != "" {
1686                 fmt.Fprintf(os.Stderr, "go: to switch to the latest unretracted version, run:\n\tgo get %s@latest\n", retractPath)
1687         }
1688         for _, err := range sumErrs {
1689                 if err != nil {
1690                         base.Error(err)
1691                 }
1692         }
1693         base.ExitIfErrors()
1694 }
1695
1696 // reportChanges logs version changes to os.Stderr.
1697 //
1698 // reportChanges only logs changes to modules named on the command line and to
1699 // explicitly required modules in go.mod. Most changes to indirect requirements
1700 // are not relevant to the user and are not logged.
1701 //
1702 // reportChanges should be called after WriteGoMod.
1703 func (r *resolver) reportChanges(oldReqs, newReqs []module.Version) {
1704         type change struct {
1705                 path, old, new string
1706         }
1707         changes := make(map[string]change)
1708
1709         // Collect changes in modules matched by command line arguments.
1710         for path, reason := range r.resolvedVersion {
1711                 if gover.IsToolchain(path) {
1712                         continue
1713                 }
1714                 old := r.initialVersion[path]
1715                 new := reason.version
1716                 if old != new && (old != "" || new != "none") {
1717                         changes[path] = change{path, old, new}
1718                 }
1719         }
1720
1721         // Collect changes to explicit requirements in go.mod.
1722         for _, req := range oldReqs {
1723                 if gover.IsToolchain(req.Path) {
1724                         continue
1725                 }
1726                 path := req.Path
1727                 old := req.Version
1728                 new := r.buildListVersion[path]
1729                 if old != new {
1730                         changes[path] = change{path, old, new}
1731                 }
1732         }
1733         for _, req := range newReqs {
1734                 if gover.IsToolchain(req.Path) {
1735                         continue
1736                 }
1737                 path := req.Path
1738                 old := r.initialVersion[path]
1739                 new := req.Version
1740                 if old != new {
1741                         changes[path] = change{path, old, new}
1742                 }
1743         }
1744
1745         // Toolchain diffs are easier than requirements: diff old and new directly.
1746         toolchainVersions := func(reqs []module.Version) (goV, toolchain string) {
1747                 for _, req := range reqs {
1748                         if req.Path == "go" {
1749                                 goV = req.Version
1750                         }
1751                         if req.Path == "toolchain" {
1752                                 toolchain = req.Version
1753                         }
1754                 }
1755                 return
1756         }
1757         oldGo, oldToolchain := toolchainVersions(oldReqs)
1758         newGo, newToolchain := toolchainVersions(newReqs)
1759         if oldGo != newGo {
1760                 changes["go"] = change{"go", oldGo, newGo}
1761         }
1762         if oldToolchain != newToolchain {
1763                 changes["toolchain"] = change{"toolchain", oldToolchain, newToolchain}
1764         }
1765
1766         sortedChanges := make([]change, 0, len(changes))
1767         for _, c := range changes {
1768                 sortedChanges = append(sortedChanges, c)
1769         }
1770         sort.Slice(sortedChanges, func(i, j int) bool {
1771                 pi := sortedChanges[i].path
1772                 pj := sortedChanges[j].path
1773                 if pi == pj {
1774                         return false
1775                 }
1776                 // go first; toolchain second
1777                 switch {
1778                 case pi == "go":
1779                         return true
1780                 case pj == "go":
1781                         return false
1782                 case pi == "toolchain":
1783                         return true
1784                 case pj == "toolchain":
1785                         return false
1786                 }
1787                 return pi < pj
1788         })
1789
1790         for _, c := range sortedChanges {
1791                 if c.old == "" {
1792                         fmt.Fprintf(os.Stderr, "go: added %s %s\n", c.path, c.new)
1793                 } else if c.new == "none" || c.new == "" {
1794                         fmt.Fprintf(os.Stderr, "go: removed %s %s\n", c.path, c.old)
1795                 } else if gover.ModCompare(c.path, c.new, c.old) > 0 {
1796                         fmt.Fprintf(os.Stderr, "go: upgraded %s %s => %s\n", c.path, c.old, c.new)
1797                         if c.path == "go" && gover.Compare(c.old, gover.ExplicitIndirectVersion) < 0 && gover.Compare(c.new, gover.ExplicitIndirectVersion) >= 0 {
1798                                 fmt.Fprintf(os.Stderr, "\tnote: expanded dependencies to upgrade to go %s or higher; run 'go mod tidy' to clean up\n", gover.ExplicitIndirectVersion)
1799                         }
1800
1801                 } else {
1802                         fmt.Fprintf(os.Stderr, "go: downgraded %s %s => %s\n", c.path, c.old, c.new)
1803                 }
1804         }
1805
1806         // TODO(golang.org/issue/33284): attribute changes to command line arguments.
1807         // For modules matched by command line arguments, this probably isn't
1808         // necessary, but it would be useful for unmatched direct dependencies of
1809         // the main module.
1810 }
1811
1812 // resolve records that module m must be at its indicated version (which may be
1813 // "none") due to query q. If some other query forces module m to be at a
1814 // different version, resolve reports a conflict error.
1815 func (r *resolver) resolve(q *query, m module.Version) {
1816         if m.Path == "" {
1817                 panic("internal error: resolving a module.Version with an empty path")
1818         }
1819
1820         if modload.MainModules.Contains(m.Path) && m.Version != "" {
1821                 reportError(q, &modload.QueryMatchesMainModulesError{
1822                         MainModules: []module.Version{{Path: m.Path}},
1823                         Pattern:     q.pattern,
1824                         Query:       q.version,
1825                 })
1826                 return
1827         }
1828
1829         vr, ok := r.resolvedVersion[m.Path]
1830         if ok && vr.version != m.Version {
1831                 reportConflict(q, m, vr)
1832                 return
1833         }
1834         r.resolvedVersion[m.Path] = versionReason{m.Version, q}
1835         q.resolved = append(q.resolved, m)
1836 }
1837
1838 // updateBuildList updates the module loader's global build list to be
1839 // consistent with r.resolvedVersion, and to include additional modules
1840 // provided that they do not conflict with the resolved versions.
1841 //
1842 // If the additional modules conflict with the resolved versions, they will be
1843 // downgraded to a non-conflicting version (possibly "none").
1844 //
1845 // If the resulting build list is the same as the one resulting from the last
1846 // call to updateBuildList, updateBuildList returns with changed=false.
1847 func (r *resolver) updateBuildList(ctx context.Context, additions []module.Version) (changed bool) {
1848         defer base.ExitIfErrors()
1849
1850         resolved := make([]module.Version, 0, len(r.resolvedVersion))
1851         for mPath, rv := range r.resolvedVersion {
1852                 if !modload.MainModules.Contains(mPath) {
1853                         resolved = append(resolved, module.Version{Path: mPath, Version: rv.version})
1854                 }
1855         }
1856
1857         changed, err := modload.EditBuildList(ctx, additions, resolved)
1858         if err != nil {
1859                 if errors.Is(err, gover.ErrTooNew) {
1860                         toolchain.SwitchOrFatal(ctx, err)
1861                 }
1862
1863                 var constraint *modload.ConstraintError
1864                 if !errors.As(err, &constraint) {
1865                         base.Fatal(err)
1866                 }
1867
1868                 if cfg.BuildV {
1869                         // Log complete paths for the conflicts before we summarize them.
1870                         for _, c := range constraint.Conflicts {
1871                                 fmt.Fprintf(os.Stderr, "go: %v\n", c.String())
1872                         }
1873                 }
1874
1875                 // modload.EditBuildList reports constraint errors at
1876                 // the module level, but 'go get' operates on packages.
1877                 // Rewrite the errors to explain them in terms of packages.
1878                 reason := func(m module.Version) string {
1879                         rv, ok := r.resolvedVersion[m.Path]
1880                         if !ok {
1881                                 return fmt.Sprintf("(INTERNAL ERROR: no reason found for %v)", m)
1882                         }
1883                         return rv.reason.ResolvedString(module.Version{Path: m.Path, Version: rv.version})
1884                 }
1885                 for _, c := range constraint.Conflicts {
1886                         adverb := ""
1887                         if len(c.Path) > 2 {
1888                                 adverb = "indirectly "
1889                         }
1890                         firstReason := reason(c.Path[0])
1891                         last := c.Path[len(c.Path)-1]
1892                         if c.Err != nil {
1893                                 base.Errorf("go: %v %srequires %v: %v", firstReason, adverb, last, c.UnwrapModuleError())
1894                         } else {
1895                                 base.Errorf("go: %v %srequires %v, not %v", firstReason, adverb, last, reason(c.Constraint))
1896                         }
1897                 }
1898                 return false
1899         }
1900         if !changed {
1901                 return false
1902         }
1903
1904         mg, err := modload.LoadModGraph(ctx, "")
1905         if err != nil {
1906                 toolchain.SwitchOrFatal(ctx, err)
1907         }
1908
1909         r.buildList = mg.BuildList()
1910         r.buildListVersion = make(map[string]string, len(r.buildList))
1911         for _, m := range r.buildList {
1912                 r.buildListVersion[m.Path] = m.Version
1913         }
1914         return true
1915 }
1916
1917 func reqsFromGoMod(f *modfile.File) []module.Version {
1918         reqs := make([]module.Version, len(f.Require), 2+len(f.Require))
1919         for i, r := range f.Require {
1920                 reqs[i] = r.Mod
1921         }
1922         if f.Go != nil {
1923                 reqs = append(reqs, module.Version{Path: "go", Version: f.Go.Version})
1924         }
1925         if f.Toolchain != nil {
1926                 reqs = append(reqs, module.Version{Path: "toolchain", Version: f.Toolchain.Name})
1927         }
1928         return reqs
1929 }
1930
1931 // isNoSuchModuleVersion reports whether err indicates that the requested module
1932 // does not exist at the requested version, either because the module does not
1933 // exist at all or because it does not include that specific version.
1934 func isNoSuchModuleVersion(err error) bool {
1935         var noMatch *modload.NoMatchingVersionError
1936         return errors.Is(err, os.ErrNotExist) || errors.As(err, &noMatch)
1937 }
1938
1939 // isNoSuchPackageVersion reports whether err indicates that the requested
1940 // package does not exist at the requested version, either because no module
1941 // that could contain it exists at that version, or because every such module
1942 // that does exist does not actually contain the package.
1943 func isNoSuchPackageVersion(err error) bool {
1944         var noPackage *modload.PackageNotInModuleError
1945         return isNoSuchModuleVersion(err) || errors.As(err, &noPackage)
1946 }