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