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.
5 // Package modget implements the module-aware “go get” command.
8 // The arguments to 'go get' are patterns with optional version queries, with
9 // the version queries defaulting to "upgrade".
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).
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.
38 "cmd/go/internal/base"
40 "cmd/go/internal/gover"
41 "cmd/go/internal/imports"
42 "cmd/go/internal/modfetch"
43 "cmd/go/internal/modload"
45 "cmd/go/internal/search"
46 "cmd/go/internal/toolchain"
47 "cmd/go/internal/work"
49 "golang.org/x/mod/modfile"
50 "golang.org/x/mod/module"
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",
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
63 To add a dependency for a package or upgrade it to its latest version:
65 go get example.com/pkg
67 To upgrade or downgrade a package to a specific version:
69 go get example.com/pkg@v1.2.3
71 To remove a dependency on a module and downgrade modules that require it:
73 go get example.com/mod@none
75 To upgrade the minimum required Go version to the latest released Go version:
79 To upgrade the Go toolchain to the latest patch release of the current Go toolchain:
81 go get toolchain@patch
83 See https://golang.org/ref/mod#go-get for details.
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:
91 go install example.com/pkg@v1.2.3
92 go install example.com/pkg@latest
94 See 'go help install' or https://golang.org/ref/mod#go-install for details.
96 'go get' accepts the following flags.
98 The -t flag instructs get to consider modules needed to build tests of
99 packages specified on the command line.
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.
105 The -u=patch flag (not -u patch) also instructs get to update dependencies,
106 but changes the default to select patch releases.
108 When the -t and -u flags are used together, get will update
109 test dependencies as well.
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
115 For more about modules, see https://golang.org/ref/mod.
117 For more about using 'go get' to update the minimum Go version and
118 suggested Go toolchain, see https://go.dev/doc/toolchain.
120 For more about specifying packages, see 'go help packages'.
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'.
127 See also: go build, go install, go clean, go mod.
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",
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.
144 Usage: ` + CmdGet.UsageLine + `
148 var HelpVCS = &base.Command{
150 Short: "controlling version control with GOVCS",
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.
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.
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.
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.
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
197 For example, consider:
199 GOVCS=github.com:git,evil.com:off,*:git|hg
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
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.
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'.
214 To allow unfettered use of any version control system for any package, use:
218 To disable all use of version control, use:
222 The 'go env -w' command (see 'go help env') can be used to set the GOVCS
223 variable for future go command invocations.
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, "")
234 getInsecure = CmdGet.Flag.Bool("insecure", false, "")
238 // upgradeFlag is a custom flag.Value for -u.
239 type upgradeFlag struct {
244 func (*upgradeFlag) IsBoolFlag() bool { return true } // allow -u
246 func (v *upgradeFlag) Set(s string) error {
250 } else if s == "true" {
251 v.version = "upgrade"
260 func (v *upgradeFlag) String() string { return "" }
263 work.AddBuildFlags(CmdGet, work.OmitModFlag)
264 CmdGet.Run = runGet // break init loop
265 CmdGet.Flag.Var(&getU, "u", "")
268 func runGet(ctx context.Context, cmd *base.Command, args []string) {
269 switch getU.version {
270 case "", "upgrade", "patch":
273 base.Fatalf("go: unknown upgrade flag -u=%s", getU.rawVersion)
275 // TODO(#43684): in the future (Go 1.20), warn that -d is a no-op.
277 base.Fatalf("go: -d flag may not be disabled")
280 fmt.Fprintf(os.Stderr, "go: -f flag is a no-op when using modules\n")
283 fmt.Fprintf(os.Stderr, "go: -fix flag is a no-op when using modules\n")
286 base.Fatalf("go: -m flag is no longer supported")
289 base.Fatalf("go: -insecure flag is no longer supported; use GOINSECURE instead")
292 modload.ForceUseModules = true
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
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()
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.
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'.")
317 dropToolchain, queries := parseArgs(ctx, args)
318 opts := modload.WriteOpts{
319 DropToolchain: dropToolchain,
321 for _, q := range queries {
322 if q.pattern == "toolchain" {
323 opts.ExplicitToolchain = true
327 r := newResolver(ctx, queries)
328 r.performLocalQueries(ctx)
329 r.performPathQueries(ctx)
332 r.performWildcardQueries(ctx)
333 r.performPatternAllQueries(ctx)
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.
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.
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.
360 // When we load imports, we detect the following conditions:
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
366 // - transitive dependencies that didn't match any other query,
367 // but need to be upgraded due to the -u flag
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 {
376 r.findMissingWildcards(ctx)
377 if changed := r.resolveQueries(ctx, r.wildcardQueries); changed {
384 r.checkWildcardVersions(ctx)
386 var pkgPatterns []string
387 for _, q := range queries {
388 if q.matchesPackages {
389 pkgPatterns = append(pkgPatterns, q.pattern)
392 r.checkPackageProblems(ctx, pkgPatterns)
394 // Everything succeeded. Update go.mod.
395 oldReqs := reqsFromGoMod(modload.ModFile())
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)
406 newReqs := reqsFromGoMod(modload.ModFile())
407 r.reportChanges(oldReqs, newReqs)
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)
417 // parseArgs parses command-line arguments and reports errors.
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()
424 for _, arg := range search.CleanPatterns(rawArgs) {
425 q, err := newQuery(arg)
431 if q.version == "none" {
434 base.Errorf("go: cannot use go@none")
442 // If there were no arguments, CleanPatterns returns ".". Set the raw
443 // string back to "" for better errors.
444 if len(rawArgs) == 0 {
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)
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)
462 queries = append(queries, q)
465 return dropToolchain, queries
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"
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
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
484 buildList []module.Version
485 buildListVersion map[string]string // index of buildList (module path → version)
487 initialVersion map[string]string // index of the initial build list at the start of 'go get'
489 missing []pathSet // candidates for missing transitive dependencies
493 matchInModuleCache par.ErrCache[matchInModuleKey, []string]
496 type versionReason struct {
501 type matchInModuleKey struct {
506 func newResolver(ctx context.Context, queries []*query) *resolver {
507 // LoadModGraph also sets modload.Target, which is needed by various resolver
509 mg, err := modload.LoadModGraph(ctx, "")
511 toolchain.SwitchOrFatal(ctx, err)
514 buildList := mg.BuildList()
515 initialVersion := make(map[string]string, len(buildList))
516 for _, m := range buildList {
517 initialVersion[m.Path] = m.Version
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{},
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)
537 r.pathQueries = append(r.pathQueries, q)
540 if q.version == "none" {
541 // Index "none" queries to make noneForPath more efficient.
543 r.wildcardNones = append(r.wildcardNones, q)
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
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]
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]
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 {
581 for _, nq := range r.wildcardNones {
582 if nq.matchesPath(mPath) {
589 // queryModule wraps modload.Query, substituting r.checkAllowedOr to decide
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))
595 return module.Version{}, err
597 return module.Version{Path: mPath, Version: rev.Version}, nil
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)
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)
626 return pkgMods, mod, err
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)
636 if (requested == "upgrade" || requested == "patch") && m.Version == selected(m.Path) {
639 return modload.CheckAllowed(ctx, m)
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]
650 return match.Pkgs, nil
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".
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))
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”.
679 // However, neither of those behaviors would be consistent with the
680 // plain meaning of the query. To try to reduce confusion, reject the
682 return errSet(&modload.QueryMatchesMainModulesError{MainModules: []module.Version{v}, Pattern: q.pattern, Query: q.version})
685 return pathSet{mod: module.Version{Path: q.pattern, Version: "none"}}
689 for _, curM := range r.buildList {
690 if !q.matchesPath(curM.Path) {
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})
697 return pathSet{mod: module.Version{Path: curM.Path, Version: "none"}}
702 func (r *resolver) performLocalQueries(ctx context.Context) {
703 for _, q := range r.localQueries {
704 q.pathOnce(q.pattern, func() pathSet {
706 if !filepath.IsAbs(q.pattern) {
707 if absPath, err := filepath.Abs(q.pattern); err == nil {
708 absDetail = fmt.Sprintf(" (%s)", absPath)
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))
722 if len(modRoots) != 1 {
725 return errSet(fmt.Errorf("%s%s is not within module%s rooted at %s", q.pattern, absDetail, plural, strings.Join(modRoots, ", ")))
728 match := modload.MatchInModule(ctx, pkgPattern, mainModule, imports.AnyTags())
729 if len(match.Errs) > 0 {
730 return pathSet{err: match.Errs[0]}
733 if len(match.Pkgs) == 0 {
734 if q.raw == "" || q.raw == "." {
735 return errSet(fmt.Errorf("no package to get in current directory"))
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)))
741 search.WarnUnmatched([]*search.Match{match})
745 return pathSet{pkgMods: []module.Version{mainModule}}
750 // performWildcardQueries populates the candidates for each query whose pattern
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
758 func (r *resolver) performWildcardQueries(ctx context.Context) {
759 for _, q := range r.wildcardQueries {
762 if q.version == "none" {
765 r.queryWildcard(ctx, q)
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) {
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).
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},
804 packages, err := r.matchInModule(ctx, q.pattern, curM)
808 if len(packages) > 0 {
809 return errSet(&modload.QueryMatchesPackagesInMainModuleError{
816 return r.tryWildcard(ctx, q, curM)
819 m, err := r.queryModule(ctx, curM.Path, q.version, r.initialSelected)
821 if !isNoSuchModuleVersion(err) {
822 // We can't tell whether a matching version exists.
825 // There is no version of curM.Path matching the query.
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.)
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.
837 // Either way, punt on the query rather than erroring out just yet.
841 return r.tryWildcard(ctx, q, m)
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.
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)
858 if len(packages) > 0 {
859 return pathSet{pkgMods: []module.Version{m}}
862 return pathSet{mod: m}
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”
875 q.pathOnce(q.pattern, func() pathSet {
876 pkgMods, mod, err := r.queryPattern(ctx, q.pattern, q.version, r.initialSelected)
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.
887 return pathSet{pkgMods: pkgMods, mod: mod}
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()
900 for _, q := range r.wildcardQueries {
901 for _, curM := range r.buildList {
902 if !q.canMatchInModule(curM.Path) {
905 if !q.matchesPath(curM.Path) {
906 packages, err := r.matchInModule(ctx, q.pattern, curM)
907 if len(packages) == 0 {
911 continue // curM is not relevant to q.
915 rev, err := r.queryModule(ctx, curM.Path, q.version, r.initialSelected)
920 if rev.Version == curM.Version {
921 continue // curM already matches q.
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)
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.
936 if rev.Version != q.version {
937 version = fmt.Sprintf("%s@%s (%s)", m.Path, q.version, m.Version)
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))
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))
954 // performPathQueries populates the candidates for each query whose pattern is
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
960 func (r *resolver) performPathQueries(ctx context.Context) {
961 for _, q := range r.pathQueries {
964 if q.version == "none" {
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))
983 if q.version == "none" {
984 panic(`internal error: queryPath called with version "none"`)
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))
995 q.matchesPackages = true
996 return pathSet{} // No module needed for standard library.
1000 pkgMods, mod, err := r.queryPattern(ctx, q.pattern, q.version, r.initialSelected)
1004 return pathSet{pkgMods: pkgMods, mod: mod}
1008 // performPatternAllQueries populates the candidates for each query whose
1009 // pattern is "all".
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 {
1021 findPackage := func(ctx context.Context, path string, m module.Version) (versionOk bool) {
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
1034 return pathSet{pkgMods: pkgMods, err: err}
1040 r.loadPackages(ctx, []string{"all"}, findPackage)
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
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).
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)
1067 if len(patterns) == 0 {
1071 // mu guards concurrent writes to upgrades, which will be sorted
1072 // (to restore determinism) after loading.
1075 findPackage := func(ctx context.Context, path string, m module.Version) (versionOk bool) {
1078 if getU.version == "" {
1079 // The user did not request that we upgrade transitive dependencies.
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.
1087 version = getU.version
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:
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.
1098 // - The "-u" flag, unlike other arguments, does not cause version
1099 // conflicts with other queries. (The other query always wins.)
1101 pkgMods, err := r.queryPackages(ctx, path, version, r.selected)
1102 for _, u := range pkgMods {
1104 // The selected package version is already upgraded appropriately; there
1105 // is no need to change it.
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.)
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.
1127 upgrades = append(upgrades, pathSet{path: path, pkgMods: pkgMods, err: err})
1132 r.loadPackages(ctx, patterns, findPackage)
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
1144 // loadPackages loads the packages matching the given patterns, invoking the
1145 // findPackage function for each package that may require a change to the
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.
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
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,
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),
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.
1172 if ok := findPackage(ctx, path, m); !ok {
1173 return errVersionChange
1178 _, pkgs := modload.LoadPackages(ctx, opts, patterns...)
1179 for _, path := range pkgs {
1184 _, _, err := modload.Lookup(parentPath, parentIsStd, path)
1188 if errors.Is(err, errVersionChange) {
1189 // We already added candidates during loading.
1194 importMissing *modload.ImportMissingError
1195 ambiguous *modload.AmbiguousImportError
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.
1206 findPackage(ctx, path, module.Version{})
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")
1216 // resolveQueries resolves candidate sets that are attached to the given
1217 // queries and/or needed to provide the given missing-package dependencies.
1219 // resolveQueries starts by resolving one module version from each
1220 // unambiguous pathSet attached to the given queries.
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.
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()
1231 // Note: this is O(N²) with the number of pathSets in the worst case.
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.
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.
1243 prevResolved := resolved
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 {
1253 // Only switch if we need a newer toolchain.
1254 // Otherwise leave the cs.err for reporting later.
1255 if sw.NeedSwitch() {
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.
1262 for _, q := range queries {
1263 unresolved := q.candidates[:0]
1265 for _, cs := range q.candidates {
1267 reportError(q, cs.err)
1272 filtered, isPackage, m, unique := r.disambiguate(cs)
1274 unresolved = append(unresolved, filtered)
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)
1284 q.matchesPackages = true
1290 q.candidates = unresolved
1294 if resolved == prevResolved {
1295 break // No unambiguous candidate remains.
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.
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.
1312 // If that results in conflicting versions, the user can re-run 'go get'
1313 // with additional explicit versions for the conflicting packages or
1315 resolvedArbitrarily := 0
1316 for _, q := range queries {
1317 for _, cs := range q.candidates {
1318 isPackage, m := r.chooseArbitrarily(cs)
1320 q.matchesPackages = true
1323 resolvedArbitrarily++
1326 if resolvedArbitrarily > 0 {
1327 changed = r.updateBuildList(ctx, nil)
1332 // applyUpgrades disambiguates candidate sets that are needed to upgrade (or
1333 // provide) transitive dependencies imported by previously-resolved packages.
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).
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()
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 {
1356 filtered, _, m, unique := r.disambiguate(cs)
1358 _, m = r.chooseArbitrarily(filtered)
1361 // There is no viable candidate for the missing package.
1362 // Leave it unresolved.
1365 tentative = append(tentative, m)
1369 changed = r.updateBuildList(ctx, tentative)
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
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")
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.
1395 if modload.MainModules.Contains(m.Path) {
1396 if m.Version == "" {
1397 return pathSet{}, true, m, true
1399 // A main module can only be set to its own version.
1403 vr, ok := r.resolvedVersion[m.Path]
1405 // m is a viable answer to the query, but other answers may also
1407 filtered.pkgMods = append(filtered.pkgMods, m)
1411 if vr.version != m.Version {
1412 // Some query forces the candidate module to a version other than this
1415 // The command could be something like
1417 // go get example.com/foo/bar@none example.com/foo/bar/baz@latest
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.
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
1430 // For example, consider the command
1432 // go get example.com/foo@latest example.com/foo/bar/baz@latest
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
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
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
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
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
1468 // chooseArbitrarily returns an arbitrary (but deterministic) module version
1469 // from among those in the given set.
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
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" {
1483 // Otherwise, arbitrarily choose the first module that provides the package.
1484 if len(cs.pkgMods) > 0 {
1485 return true, cs.pkgMods[0]
1488 return false, cs.mod
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.
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()
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.
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
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
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,
1527 ResolveMissingImports: false,
1529 SilenceNoGoErrors: true,
1531 matches, pkgs := modload.LoadPackages(ctx, pkgOpts, pkgPatterns...)
1532 for _, m := range matches {
1533 if len(m.Errs) > 0 {
1534 base.SetExitStatus(1)
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.
1551 base.SetExitStatus(1)
1552 if ambiguousErr := (*modload.AmbiguousImportError)(nil); errors.As(err, &ambiguousErr) {
1553 for _, m := range ambiguousErr.Modules {
1554 relevantMods[m] |= hasPkg
1558 if m := modload.PackageModule(pkg); m.Path != "" {
1559 relevantMods[m] |= hasPkg
1562 for _, match := range matches {
1563 for _, pkg := range match.Pkgs {
1564 m := modload.PackageModule(pkg)
1565 relevantMods[m] |= named
1570 reqs := modload.LoadModFile(ctx)
1571 for m := range relevantMods {
1572 if reqs.IsDirect(m.Path) {
1573 relevantMods[m] |= direct
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 {
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})
1590 sort.Slice(retractions, func(i, j int) bool { return retractions[i].m.Path < retractions[j].m.Path })
1591 for i := range retractions {
1594 err := modload.CheckRetractions(ctx, retractions[i].m)
1595 if retractErr := (*modload.ModuleRetractedError)(nil); errors.As(err, &retractErr) {
1596 retractions[i].message = err.Error()
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
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})
1611 sort.Slice(deprecations, func(i, j int) bool { return deprecations[i].m.Path < deprecations[j].m.Path })
1612 for i := range deprecations {
1615 deprecation, err := modload.CheckDeprecation(ctx, deprecations[i].m)
1616 if err != nil || deprecation == "" {
1619 deprecations[i].message = modload.ShortMessage(deprecation, "")
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 {
1635 if mRepl := modload.Replacement(m); mRepl.Path != "" {
1638 old := module.Version{Path: m.Path, Version: r.initialVersion[m.Path]}
1639 if old.Version == "" {
1643 if oldRepl := modload.Replacement(old); oldRepl.Path != "" {
1646 if mActual == oldActual || mActual.Version == "" || !modfetch.HaveSum(oldActual) {
1650 if _, err := modfetch.DownloadZip(ctx, mActual); err != nil {
1652 if gover.ModCompare(m.Path, m.Version, old.Version) < 0 {
1657 replaced = fmt.Sprintf(" (replaced by %s)", mActual)
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)
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)
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
1681 retractPath = "<module>"
1685 if retractPath != "" {
1686 fmt.Fprintf(os.Stderr, "go: to switch to the latest unretracted version, run:\n\tgo get %s@latest\n", retractPath)
1688 for _, err := range sumErrs {
1696 // reportChanges logs version changes to os.Stderr.
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.
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
1707 changes := make(map[string]change)
1709 // Collect changes in modules matched by command line arguments.
1710 for path, reason := range r.resolvedVersion {
1711 if gover.IsToolchain(path) {
1714 old := r.initialVersion[path]
1715 new := reason.version
1716 if old != new && (old != "" || new != "none") {
1717 changes[path] = change{path, old, new}
1721 // Collect changes to explicit requirements in go.mod.
1722 for _, req := range oldReqs {
1723 if gover.IsToolchain(req.Path) {
1728 new := r.buildListVersion[path]
1730 changes[path] = change{path, old, new}
1733 for _, req := range newReqs {
1734 if gover.IsToolchain(req.Path) {
1738 old := r.initialVersion[path]
1741 changes[path] = change{path, old, new}
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" {
1751 if req.Path == "toolchain" {
1752 toolchain = req.Version
1757 oldGo, oldToolchain := toolchainVersions(oldReqs)
1758 newGo, newToolchain := toolchainVersions(newReqs)
1760 changes["go"] = change{"go", oldGo, newGo}
1762 if oldToolchain != newToolchain {
1763 changes["toolchain"] = change{"toolchain", oldToolchain, newToolchain}
1766 sortedChanges := make([]change, 0, len(changes))
1767 for _, c := range changes {
1768 sortedChanges = append(sortedChanges, c)
1770 sort.Slice(sortedChanges, func(i, j int) bool {
1771 pi := sortedChanges[i].path
1772 pj := sortedChanges[j].path
1776 // go first; toolchain second
1782 case pi == "toolchain":
1784 case pj == "toolchain":
1790 for _, c := range sortedChanges {
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)
1802 fmt.Fprintf(os.Stderr, "go: downgraded %s %s => %s\n", c.path, c.old, c.new)
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
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) {
1817 panic("internal error: resolving a module.Version with an empty path")
1820 if modload.MainModules.Contains(m.Path) && m.Version != "" {
1821 reportError(q, &modload.QueryMatchesMainModulesError{
1822 MainModules: []module.Version{{Path: m.Path}},
1829 vr, ok := r.resolvedVersion[m.Path]
1830 if ok && vr.version != m.Version {
1831 reportConflict(q, m, vr)
1834 r.resolvedVersion[m.Path] = versionReason{m.Version, q}
1835 q.resolved = append(q.resolved, m)
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.
1842 // If the additional modules conflict with the resolved versions, they will be
1843 // downgraded to a non-conflicting version (possibly "none").
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()
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})
1857 changed, err := modload.EditBuildList(ctx, additions, resolved)
1859 if errors.Is(err, gover.ErrTooNew) {
1860 toolchain.SwitchOrFatal(ctx, err)
1863 var constraint *modload.ConstraintError
1864 if !errors.As(err, &constraint) {
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())
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]
1881 return fmt.Sprintf("(INTERNAL ERROR: no reason found for %v)", m)
1883 return rv.reason.ResolvedString(module.Version{Path: m.Path, Version: rv.version})
1885 for _, c := range constraint.Conflicts {
1887 if len(c.Path) > 2 {
1888 adverb = "indirectly "
1890 firstReason := reason(c.Path[0])
1891 last := c.Path[len(c.Path)-1]
1893 base.Errorf("go: %v %srequires %v: %v", firstReason, adverb, last, c.UnwrapModuleError())
1895 base.Errorf("go: %v %srequires %v, not %v", firstReason, adverb, last, reason(c.Constraint))
1904 mg, err := modload.LoadModGraph(ctx, "")
1906 toolchain.SwitchOrFatal(ctx, err)
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
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 {
1923 reqs = append(reqs, module.Version{Path: "go", Version: f.Go.Version})
1925 if f.Toolchain != nil {
1926 reqs = append(reqs, module.Version{Path: "toolchain", Version: f.Toolchain.Name})
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)
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)