...

Source file src/pkg/cmd/go/internal/modget/get.go

     1	// Copyright 2018 The Go Authors. All rights reserved.
     2	// Use of this source code is governed by a BSD-style
     3	// license that can be found in the LICENSE file.
     4	
     5	// Package modget implements the module-aware ``go get'' command.
     6	package modget
     7	
     8	import (
     9		"cmd/go/internal/base"
    10		"cmd/go/internal/cfg"
    11		"cmd/go/internal/get"
    12		"cmd/go/internal/imports"
    13		"cmd/go/internal/load"
    14		"cmd/go/internal/modload"
    15		"cmd/go/internal/module"
    16		"cmd/go/internal/mvs"
    17		"cmd/go/internal/par"
    18		"cmd/go/internal/search"
    19		"cmd/go/internal/semver"
    20		"cmd/go/internal/work"
    21		"errors"
    22		"fmt"
    23		"os"
    24		"path/filepath"
    25		"sort"
    26		"strings"
    27		"sync"
    28	)
    29	
    30	var CmdGet = &base.Command{
    31		// Note: -d -u are listed explicitly because they are the most common get flags.
    32		// Do not send CLs removing them because they're covered by [get flags].
    33		UsageLine: "go get [-d] [-t] [-u] [-v] [-insecure] [build flags] [packages]",
    34		Short:     "add dependencies to current module and install them",
    35		Long: `
    36	Get resolves and adds dependencies to the current development module
    37	and then builds and installs them.
    38	
    39	The first step is to resolve which dependencies to add.
    40	
    41	For each named package or package pattern, get must decide which version of
    42	the corresponding module to use. By default, get looks up the latest tagged
    43	release version, such as v0.4.5 or v1.2.3. If there are no tagged release
    44	versions, get looks up the latest tagged pre-release version, such as
    45	v0.0.1-pre1. If there are no tagged versions at all, get looks up the latest
    46	known commit. If the module is not already required at a later version
    47	(for example, a pre-release newer than the latest release), get will use
    48	the version it looked up. Otherwise, get will use the currently
    49	required version.
    50	
    51	This default version selection can be overridden by adding an @version
    52	suffix to the package argument, as in 'go get golang.org/x/text@v0.3.0'.
    53	The version may be a prefix: @v1 denotes the latest available version starting
    54	with v1. See 'go help modules' under the heading 'Module queries' for the
    55	full query syntax.
    56	
    57	For modules stored in source control repositories, the version suffix can
    58	also be a commit hash, branch identifier, or other syntax known to the
    59	source control system, as in 'go get golang.org/x/text@master'. Note that
    60	branches with names that overlap with other module query syntax cannot be
    61	selected explicitly. For example, the suffix @v2 means the latest version
    62	starting with v2, not the branch named v2.
    63	
    64	If a module under consideration is already a dependency of the current
    65	development module, then get will update the required version.
    66	Specifying a version earlier than the current required version is valid and
    67	downgrades the dependency. The version suffix @none indicates that the
    68	dependency should be removed entirely, downgrading or removing modules
    69	depending on it as needed.
    70	
    71	The version suffix @latest explicitly requests the latest minor release of the
    72	module named by the given path. The suffix @upgrade is like @latest but
    73	will not downgrade a module if it is already required at a revision or
    74	pre-release version newer than the latest released version. The suffix
    75	@patch requests the latest patch release: the latest released version
    76	with the same major and minor version numbers as the currently required
    77	version. Like @upgrade, @patch will not downgrade a module already required
    78	at a newer version. If the path is not already required, @upgrade and @patch
    79	are equivalent to @latest.
    80	
    81	Although get defaults to using the latest version of the module containing
    82	a named package, it does not use the latest version of that module's
    83	dependencies. Instead it prefers to use the specific dependency versions
    84	requested by that module. For example, if the latest A requires module
    85	B v1.2.3, while B v1.2.4 and v1.3.1 are also available, then 'go get A'
    86	will use the latest A but then use B v1.2.3, as requested by A. (If there
    87	are competing requirements for a particular module, then 'go get' resolves
    88	those requirements by taking the maximum requested version.)
    89	
    90	The -t flag instructs get to consider modules needed to build tests of
    91	packages specified on the command line.
    92	
    93	The -u flag instructs get to update modules providing dependencies
    94	of packages named on the command line to use newer minor or patch
    95	releases when available. Continuing the previous example, 'go get -u A'
    96	will use the latest A with B v1.3.1 (not B v1.2.3). If B requires module C,
    97	but C does not provide any packages needed to build packages in A
    98	(not including tests), then C will not be updated.
    99	
   100	The -u=patch flag (not -u patch) also instructs get to update dependencies,
   101	but changes the default to select patch releases.
   102	Continuing the previous example,
   103	'go get -u=patch A@latest' will use the latest A with B v1.2.4 (not B v1.2.3),
   104	while 'go get -u=patch A' will use a patch release of A instead.
   105	
   106	When the -t and -u flags are used together, get will update
   107	test dependencies as well.
   108	
   109	In general, adding a new dependency may require upgrading
   110	existing dependencies to keep a working build, and 'go get' does
   111	this automatically. Similarly, downgrading one dependency may
   112	require downgrading other dependencies, and 'go get' does
   113	this automatically as well.
   114	
   115	The -insecure flag permits fetching from repositories and resolving
   116	custom domains using insecure schemes such as HTTP. Use with caution.
   117	
   118	The second step is to download (if needed), build, and install
   119	the named packages.
   120	
   121	If an argument names a module but not a package (because there is no
   122	Go source code in the module's root directory), then the install step
   123	is skipped for that argument, instead of causing a build failure.
   124	For example 'go get golang.org/x/perf' succeeds even though there
   125	is no code corresponding to that import path.
   126	
   127	Note that package patterns are allowed and are expanded after resolving
   128	the module versions. For example, 'go get golang.org/x/perf/cmd/...'
   129	adds the latest golang.org/x/perf and then installs the commands in that
   130	latest version.
   131	
   132	The -d flag instructs get to download the source code needed to build
   133	the named packages, including downloading necessary dependencies,
   134	but not to build and install them.
   135	
   136	With no package arguments, 'go get' applies to Go package in the
   137	current directory, if any. In particular, 'go get -u' and
   138	'go get -u=patch' update all the dependencies of that package.
   139	With no package arguments and also without -u, 'go get' is not much more
   140	than 'go install', and 'go get -d' not much more than 'go list'.
   141	
   142	For more about modules, see 'go help modules'.
   143	
   144	For more about specifying packages, see 'go help packages'.
   145	
   146	This text describes the behavior of get using modules to manage source
   147	code and dependencies. If instead the go command is running in GOPATH
   148	mode, the details of get's flags and effects change, as does 'go help get'.
   149	See 'go help modules' and 'go help gopath-get'.
   150	
   151	See also: go build, go install, go clean, go mod.
   152		`,
   153	}
   154	
   155	// Note that this help text is a stopgap to make the module-aware get help text
   156	// available even in non-module settings. It should be deleted when the old get
   157	// is deleted. It should NOT be considered to set a precedent of having hierarchical
   158	// help names with dashes.
   159	var HelpModuleGet = &base.Command{
   160		UsageLine: "module-get",
   161		Short:     "module-aware go get",
   162		Long: `
   163	The 'go get' command changes behavior depending on whether the
   164	go command is running in module-aware mode or legacy GOPATH mode.
   165	This help text, accessible as 'go help module-get' even in legacy GOPATH mode,
   166	describes 'go get' as it operates in module-aware mode.
   167	
   168	Usage: ` + CmdGet.UsageLine + `
   169	` + CmdGet.Long,
   170	}
   171	
   172	var (
   173		getD   = CmdGet.Flag.Bool("d", false, "")
   174		getF   = CmdGet.Flag.Bool("f", false, "")
   175		getFix = CmdGet.Flag.Bool("fix", false, "")
   176		getM   = CmdGet.Flag.Bool("m", false, "")
   177		getT   = CmdGet.Flag.Bool("t", false, "")
   178		getU   upgradeFlag
   179		// -insecure is get.Insecure
   180		// -v is cfg.BuildV
   181	)
   182	
   183	// upgradeFlag is a custom flag.Value for -u.
   184	type upgradeFlag string
   185	
   186	func (*upgradeFlag) IsBoolFlag() bool { return true } // allow -u
   187	
   188	func (v *upgradeFlag) Set(s string) error {
   189		if s == "false" {
   190			s = ""
   191		}
   192		if s == "true" {
   193			s = "upgrade"
   194		}
   195		*v = upgradeFlag(s)
   196		return nil
   197	}
   198	
   199	func (v *upgradeFlag) String() string { return "" }
   200	
   201	func init() {
   202		work.AddBuildFlags(CmdGet)
   203		CmdGet.Run = runGet // break init loop
   204		CmdGet.Flag.BoolVar(&get.Insecure, "insecure", get.Insecure, "")
   205		CmdGet.Flag.Var(&getU, "u", "")
   206	}
   207	
   208	// A getArg holds a parsed positional argument for go get (path@vers).
   209	type getArg struct {
   210		// raw is the original argument, to be printed in error messages.
   211		raw string
   212	
   213		// path is the part of the argument before "@" (or the whole argument
   214		// if there is no "@"). path specifies the modules or packages to get.
   215		path string
   216	
   217		// vers is the part of the argument after "@" or an implied
   218		// "upgrade" or "patch" if there is no "@". vers specifies the
   219		// module version to get.
   220		vers string
   221	}
   222	
   223	// querySpec describes a query for a specific module. path may be a
   224	// module path, package path, or package pattern. vers is a version
   225	// query string from a command line argument.
   226	type querySpec struct {
   227		// path is a module path, package path, or package pattern that
   228		// specifies which module to query.
   229		path string
   230	
   231		// vers specifies what version of the module to get.
   232		vers string
   233	
   234		// forceModulePath is true if path should be interpreted as a module path.
   235		// If forceModulePath is true, prevM must be set.
   236		forceModulePath bool
   237	
   238		// prevM is the previous version of the module. prevM is needed
   239		// to determine the minor version number if vers is "patch". It's also
   240		// used to avoid downgrades from prerelease versions newer than
   241		// "latest" and "patch". If prevM is set, forceModulePath must be true.
   242		prevM module.Version
   243	}
   244	
   245	// query holds the state for a query made for a specific module.
   246	// After a query is performed, we know the actual module path and
   247	// version and whether any packages were matched by the query path.
   248	type query struct {
   249		querySpec
   250	
   251		// arg is the command line argument that matched the specified module.
   252		arg string
   253	
   254		// m is the module path and version found by the query.
   255		m module.Version
   256	}
   257	
   258	func runGet(cmd *base.Command, args []string) {
   259		// -mod=readonly has no effect on "go get".
   260		if cfg.BuildMod == "readonly" {
   261			cfg.BuildMod = ""
   262		}
   263	
   264		switch getU {
   265		case "", "upgrade", "patch":
   266			// ok
   267		default:
   268			base.Fatalf("go get: unknown upgrade flag -u=%s", getU)
   269		}
   270		if *getF {
   271			fmt.Fprintf(os.Stderr, "go get: -f flag is a no-op when using modules\n")
   272		}
   273		if *getFix {
   274			fmt.Fprintf(os.Stderr, "go get: -fix flag is a no-op when using modules\n")
   275		}
   276		if *getM {
   277			base.Fatalf("go get: -m flag is no longer supported; consider -d to skip building packages")
   278		}
   279		modload.LoadTests = *getT
   280	
   281		if cfg.BuildMod == "vendor" {
   282			base.Fatalf("go get: disabled by -mod=%s", cfg.BuildMod)
   283		}
   284	
   285		buildList := modload.LoadBuildList()
   286		buildList = buildList[:len(buildList):len(buildList)] // copy on append
   287		versionByPath := make(map[string]string)
   288		for _, m := range buildList {
   289			versionByPath[m.Path] = m.Version
   290		}
   291	
   292		// Do not allow any updating of go.mod until we've applied
   293		// all the requested changes and checked that the result matches
   294		// what was requested.
   295		modload.DisallowWriteGoMod()
   296	
   297		// Parse command-line arguments and report errors. The command-line
   298		// arguments are of the form path@version or simply path, with implicit
   299		// @upgrade. path@none is "downgrade away".
   300		var gets []getArg
   301		var queries []*query
   302		for _, arg := range search.CleanPatterns(args) {
   303			// Argument is path or path@vers.
   304			path := arg
   305			vers := ""
   306			if i := strings.Index(arg, "@"); i >= 0 {
   307				path, vers = arg[:i], arg[i+1:]
   308			}
   309			if strings.Contains(vers, "@") || arg != path && vers == "" {
   310				base.Errorf("go get %s: invalid module version syntax", arg)
   311				continue
   312			}
   313	
   314			// If no version suffix is specified, assume @upgrade.
   315			// If -u=patch was specified, assume @patch instead.
   316			if vers == "" {
   317				if getU != "" {
   318					vers = string(getU)
   319				} else {
   320					vers = "upgrade"
   321				}
   322			}
   323	
   324			gets = append(gets, getArg{raw: arg, path: path, vers: vers})
   325	
   326			// Determine the modules that path refers to, and create queries
   327			// to lookup modules at target versions before loading packages.
   328			// This is an imprecise process, but it helps reduce unnecessary
   329			// queries and package loading. It's also necessary for handling
   330			// patterns like golang.org/x/tools/..., which can't be expanded
   331			// during package loading until they're in the build list.
   332			switch {
   333			case search.IsRelativePath(path):
   334				// Relative paths like ../../foo or ../../foo... are restricted to
   335				// matching packages in the main module. If the path is explicit and
   336				// contains no wildcards (...), check that it is a package in
   337				// the main module. If the path contains wildcards but matches no
   338				// packages, we'll warn after package loading.
   339				if !strings.Contains(path, "...") {
   340					pkgPath := modload.DirImportPath(filepath.FromSlash(path))
   341					if pkgs := modload.TargetPackages(pkgPath); len(pkgs) == 0 {
   342						abs, err := filepath.Abs(path)
   343						if err != nil {
   344							abs = path
   345						}
   346						base.Errorf("go get %s: path %s is not a package in module rooted at %s", arg, abs, modload.ModRoot())
   347						continue
   348					}
   349				}
   350	
   351				if path != arg {
   352					base.Errorf("go get %s: can't request explicit version of path in main module", arg)
   353					continue
   354				}
   355	
   356			case strings.Contains(path, "..."):
   357				// Wait until we load packages to look up modules.
   358				// We don't know yet whether any modules in the build list provide
   359				// packages matching the pattern. For example, suppose
   360				// golang.org/x/tools and golang.org/x/tools/playground are separate
   361				// modules, and only golang.org/x/tools is in the build list. If the
   362				// user runs 'go get golang.org/x/tools/playground/...', we should
   363				// add a requirement for golang.org/x/tools/playground. We should not
   364				// upgrade golang.org/x/tools.
   365	
   366			case path == "all":
   367				// Don't query modules until we load packages. We'll automatically
   368				// look up any missing modules.
   369	
   370			case search.IsMetaPackage(path):
   371				base.Errorf("go get %s: explicit requirement on standard-library module %s not allowed", path, path)
   372				continue
   373	
   374			default:
   375				// The argument is a package path.
   376				if pkgs := modload.TargetPackages(path); len(pkgs) != 0 {
   377					// The path is in the main module. Nothing to query.
   378					if vers != "upgrade" && vers != "patch" {
   379						base.Errorf("go get %s: can't request explicit version of path in main module", arg)
   380					}
   381					continue
   382				}
   383	
   384				first := path
   385				if i := strings.IndexByte(first, '/'); i >= 0 {
   386					first = path
   387				}
   388				if !strings.Contains(first, ".") {
   389					// The path doesn't have a dot in the first component and cannot be
   390					// queried as a module. It may be a package in the standard library,
   391					// which is fine, so don't report an error unless we encounter
   392					// a problem loading packages below.
   393					continue
   394				}
   395	
   396				// If we're querying "upgrade" or "patch", we need to know the current
   397				// version of the module. For "upgrade", we want to avoid accidentally
   398				// downgrading from a newer prerelease. For "patch", we need to query
   399				// the correct minor version.
   400				// Here, we check if "path" is the name of a module in the build list
   401				// (other than the main module) and set prevM if so. If "path" isn't
   402				// a module in the build list, the current version doesn't matter
   403				// since it's either an unknown module or a package within a module
   404				// that we'll discover later.
   405				q := &query{querySpec: querySpec{path: path, vers: vers}, arg: arg}
   406				if v, ok := versionByPath[path]; ok && path != modload.Target.Path {
   407					q.prevM = module.Version{Path: path, Version: v}
   408					q.forceModulePath = true
   409				}
   410				queries = append(queries, q)
   411			}
   412		}
   413		base.ExitIfErrors()
   414	
   415		// Query modules referenced by command line arguments at requested versions.
   416		// We need to do this before loading packages since patterns that refer to
   417		// packages in unknown modules can't be expanded. This also avoids looking
   418		// up new modules while loading packages, only to downgrade later.
   419		queryCache := make(map[querySpec]*query)
   420		byPath := runQueries(queryCache, queries, nil)
   421	
   422		// Add missing modules to the build list.
   423		// We call SetBuildList here and elsewhere, since newUpgrader,
   424		// ImportPathsQuiet, and other functions read the global build list.
   425		for _, q := range queries {
   426			if _, ok := versionByPath[q.m.Path]; !ok && q.m.Version != "none" {
   427				buildList = append(buildList, q.m)
   428			}
   429		}
   430		versionByPath = nil // out of date now; rebuilt later when needed
   431		modload.SetBuildList(buildList)
   432	
   433		// Upgrade modules specifically named on the command line. This is our only
   434		// chance to upgrade modules without root packages (modOnly below).
   435		// This also skips loading packages at an old version, only to upgrade
   436		// and reload at a new version.
   437		upgrade := make(map[string]*query)
   438		for path, q := range byPath {
   439			if q.path == q.m.Path && q.m.Version != "none" {
   440				upgrade[path] = q
   441			}
   442		}
   443		buildList, err := mvs.UpgradeAll(modload.Target, newUpgrader(upgrade, nil))
   444		if err != nil {
   445			base.Fatalf("go get: %v", err)
   446		}
   447		modload.SetBuildList(buildList)
   448		base.ExitIfErrors()
   449		prevBuildList := buildList
   450	
   451		// Build a set of module paths that we don't plan to load packages from.
   452		// This includes explicitly requested modules that don't have a root package
   453		// and modules with a target version of "none".
   454		var wg sync.WaitGroup
   455		var modOnlyMu sync.Mutex
   456		modOnly := make(map[string]*query)
   457		for _, q := range queries {
   458			if q.m.Version == "none" {
   459				modOnlyMu.Lock()
   460				modOnly[q.m.Path] = q
   461				modOnlyMu.Unlock()
   462				continue
   463			}
   464			if q.path == q.m.Path {
   465				wg.Add(1)
   466				go func(q *query) {
   467					if hasPkg, err := modload.ModuleHasRootPackage(q.m); err != nil {
   468						base.Errorf("go get: %v", err)
   469					} else if !hasPkg {
   470						modOnlyMu.Lock()
   471						modOnly[q.m.Path] = q
   472						modOnlyMu.Unlock()
   473					}
   474					wg.Done()
   475				}(q)
   476			}
   477		}
   478		wg.Wait()
   479		base.ExitIfErrors()
   480	
   481		// Build a list of arguments that may refer to packages.
   482		var pkgPatterns []string
   483		var pkgGets []getArg
   484		for _, arg := range gets {
   485			if modOnly[arg.path] == nil && arg.vers != "none" {
   486				pkgPatterns = append(pkgPatterns, arg.path)
   487				pkgGets = append(pkgGets, arg)
   488			}
   489		}
   490	
   491		// Load packages and upgrade the modules that provide them. We do this until
   492		// we reach a fixed point, since modules providing packages may change as we
   493		// change versions. This must terminate because the module graph is finite,
   494		// and the load and upgrade operations may only add and upgrade modules
   495		// in the build list.
   496		var matches []*search.Match
   497		for {
   498			var seenPkgs map[string]bool
   499			seenQuery := make(map[querySpec]bool)
   500			var queries []*query
   501			addQuery := func(q *query) {
   502				if !seenQuery[q.querySpec] {
   503					seenQuery[q.querySpec] = true
   504					queries = append(queries, q)
   505				}
   506			}
   507	
   508			if len(pkgPatterns) > 0 {
   509				// Don't load packages if pkgPatterns is empty. Both
   510				// modload.ImportPathsQuiet and ModulePackages convert an empty list
   511				// of patterns to []string{"."}, which is not what we want.
   512				matches = modload.ImportPathsQuiet(pkgPatterns, imports.AnyTags())
   513				seenPkgs = make(map[string]bool)
   514				for i, match := range matches {
   515					arg := pkgGets[i]
   516	
   517					if len(match.Pkgs) == 0 {
   518						// If the pattern did not match any packages, look up a new module.
   519						// If the pattern doesn't match anything on the last iteration,
   520						// we'll print a warning after the outer loop.
   521						if !search.IsRelativePath(arg.path) && !match.Literal && arg.path != "all" {
   522							addQuery(&query{querySpec: querySpec{path: arg.path, vers: arg.vers}, arg: arg.raw})
   523						}
   524						continue
   525					}
   526	
   527					allStd := true
   528					for _, pkg := range match.Pkgs {
   529						if !seenPkgs[pkg] {
   530							seenPkgs[pkg] = true
   531							if _, _, err := modload.Lookup("", false, pkg); err != nil {
   532								allStd = false
   533								base.Errorf("go get %s: %v", arg.raw, err)
   534								continue
   535							}
   536						}
   537						m := modload.PackageModule(pkg)
   538						if m.Path == "" {
   539							// pkg is in the standard library.
   540							continue
   541						}
   542						allStd = false
   543						if m.Path == modload.Target.Path {
   544							// pkg is in the main module.
   545							continue
   546						}
   547						addQuery(&query{querySpec: querySpec{path: m.Path, vers: arg.vers, forceModulePath: true, prevM: m}, arg: arg.raw})
   548					}
   549					if allStd && arg.path != arg.raw {
   550						base.Errorf("go get %s: cannot use pattern %q with explicit version", arg.raw, arg.raw)
   551					}
   552				}
   553			}
   554			base.ExitIfErrors()
   555	
   556			// Query target versions for modules providing packages matched by
   557			// command line arguments.
   558			byPath = runQueries(queryCache, queries, modOnly)
   559	
   560			// Handle upgrades. This is needed for arguments that didn't match
   561			// modules or matched different modules from a previous iteration. It
   562			// also upgrades modules providing package dependencies if -u is set.
   563			buildList, err := mvs.UpgradeAll(modload.Target, newUpgrader(byPath, seenPkgs))
   564			if err != nil {
   565				base.Fatalf("go get: %v", err)
   566			}
   567			modload.SetBuildList(buildList)
   568			base.ExitIfErrors()
   569	
   570			// Stop if no changes have been made to the build list.
   571			buildList = modload.BuildList()
   572			eq := len(buildList) == len(prevBuildList)
   573			for i := 0; eq && i < len(buildList); i++ {
   574				eq = buildList[i] == prevBuildList[i]
   575			}
   576			if eq {
   577				break
   578			}
   579			prevBuildList = buildList
   580		}
   581		if !*getD {
   582			// Only print warnings after the last iteration,
   583			// and only if we aren't going to build.
   584			search.WarnUnmatched(matches)
   585		}
   586	
   587		// Handle downgrades.
   588		var down []module.Version
   589		for _, m := range modload.BuildList() {
   590			q := byPath[m.Path]
   591			if q != nil && semver.Compare(m.Version, q.m.Version) > 0 {
   592				down = append(down, module.Version{Path: m.Path, Version: q.m.Version})
   593			}
   594		}
   595		if len(down) > 0 {
   596			buildList, err := mvs.Downgrade(modload.Target, modload.Reqs(), down...)
   597			if err != nil {
   598				base.Fatalf("go: %v", err)
   599			}
   600			modload.SetBuildList(buildList)
   601			modload.ReloadBuildList() // note: does not update go.mod
   602			base.ExitIfErrors()
   603		}
   604	
   605		// Scan for any upgrades lost by the downgrades.
   606		var lostUpgrades []*query
   607		if len(down) > 0 {
   608			versionByPath = make(map[string]string)
   609			for _, m := range modload.BuildList() {
   610				versionByPath[m.Path] = m.Version
   611			}
   612			for _, q := range byPath {
   613				if v, ok := versionByPath[q.m.Path]; q.m.Version != "none" && (!ok || semver.Compare(v, q.m.Version) != 0) {
   614					lostUpgrades = append(lostUpgrades, q)
   615				}
   616			}
   617			sort.Slice(lostUpgrades, func(i, j int) bool {
   618				return lostUpgrades[i].m.Path < lostUpgrades[j].m.Path
   619			})
   620		}
   621		if len(lostUpgrades) > 0 {
   622			desc := func(m module.Version) string {
   623				s := m.Path + "@" + m.Version
   624				t := byPath[m.Path]
   625				if t != nil && t.arg != s {
   626					s += " from " + t.arg
   627				}
   628				return s
   629			}
   630			downByPath := make(map[string]module.Version)
   631			for _, d := range down {
   632				downByPath[d.Path] = d
   633			}
   634	
   635			var buf strings.Builder
   636			fmt.Fprintf(&buf, "go get: inconsistent versions:")
   637			reqs := modload.Reqs()
   638			for _, q := range lostUpgrades {
   639				// We lost q because its build list requires a newer version of something in down.
   640				// Figure out exactly what.
   641				// Repeatedly constructing the build list is inefficient
   642				// if there are MANY command-line arguments,
   643				// but at least all the necessary requirement lists are cached at this point.
   644				list, err := buildListForLostUpgrade(q.m, reqs)
   645				if err != nil {
   646					base.Fatalf("go: %v", err)
   647				}
   648	
   649				fmt.Fprintf(&buf, "\n\t%s", desc(q.m))
   650				sep := " requires"
   651				for _, m := range list {
   652					if down, ok := downByPath[m.Path]; ok && semver.Compare(down.Version, m.Version) < 0 {
   653						fmt.Fprintf(&buf, "%s %s@%s (not %s)", sep, m.Path, m.Version, desc(down))
   654						sep = ","
   655					}
   656				}
   657				if sep != "," {
   658					// We have no idea why this happened.
   659					// At least report the problem.
   660					if v := versionByPath[q.m.Path]; v == "" {
   661						fmt.Fprintf(&buf, " removed unexpectedly")
   662					} else {
   663						fmt.Fprintf(&buf, " ended up at %s unexpectedly", v)
   664					}
   665					fmt.Fprintf(&buf, " (please report at golang.org/issue/new)")
   666				}
   667			}
   668			base.Fatalf("%v", buf.String())
   669		}
   670	
   671		// Everything succeeded. Update go.mod.
   672		modload.AllowWriteGoMod()
   673		modload.WriteGoMod()
   674	
   675		// If -d was specified, we're done after the module work.
   676		// We've already downloaded modules by loading packages above.
   677		// Otherwise, we need to build and install the packages matched by
   678		// command line arguments. This may be a different set of packages,
   679		// since we only build packages for the target platform.
   680		// Note that 'go get -u' without arguments is equivalent to
   681		// 'go get -u .', so we'll typically build the package in the current
   682		// directory.
   683		if *getD || len(pkgPatterns) == 0 {
   684			return
   685		}
   686		work.BuildInit()
   687		pkgs := load.PackagesForBuild(pkgPatterns)
   688		work.InstallPackages(pkgPatterns, pkgs)
   689	}
   690	
   691	// runQueries looks up modules at target versions in parallel. Results will be
   692	// cached. If the same module is referenced by multiple queries at different
   693	// versions (including earlier queries in the modOnly map), an error will be
   694	// reported. A map from module paths to queries is returned, which includes
   695	// queries and modOnly.
   696	func runQueries(cache map[querySpec]*query, queries []*query, modOnly map[string]*query) map[string]*query {
   697		var lookup par.Work
   698		for _, q := range queries {
   699			if cached := cache[q.querySpec]; cached != nil {
   700				*q = *cached
   701			} else {
   702				cache[q.querySpec] = q
   703				lookup.Add(q)
   704			}
   705		}
   706	
   707		lookup.Do(10, func(item interface{}) {
   708			q := item.(*query)
   709			if q.vers == "none" {
   710				// Wait for downgrade step.
   711				q.m = module.Version{Path: q.path, Version: "none"}
   712				return
   713			}
   714			m, err := getQuery(q.path, q.vers, q.prevM, q.forceModulePath)
   715			if err != nil {
   716				base.Errorf("go get %s: %v", q.arg, err)
   717			}
   718			q.m = m
   719		})
   720		base.ExitIfErrors()
   721	
   722		byPath := make(map[string]*query)
   723		check := func(q *query) {
   724			if prev, ok := byPath[q.m.Path]; prev != nil && prev.m != q.m {
   725				base.Errorf("go get: conflicting versions for module %s: %s and %s", q.m.Path, prev.m.Version, q.m.Version)
   726				byPath[q.m.Path] = nil // sentinel to stop errors
   727				return
   728			} else if !ok {
   729				byPath[q.m.Path] = q
   730			}
   731		}
   732		for _, q := range queries {
   733			check(q)
   734		}
   735		for _, q := range modOnly {
   736			check(q)
   737		}
   738		base.ExitIfErrors()
   739	
   740		return byPath
   741	}
   742	
   743	// getQuery evaluates the given (package or module) path and version
   744	// to determine the underlying module version being requested.
   745	// If forceModulePath is set, getQuery must interpret path
   746	// as a module path.
   747	func getQuery(path, vers string, prevM module.Version, forceModulePath bool) (module.Version, error) {
   748		if (prevM.Version != "") != forceModulePath {
   749			// We resolve package patterns by calling QueryPattern, which does not
   750			// accept a previous version and therefore cannot take it into account for
   751			// the "latest" or "patch" queries.
   752			// If we are resolving a package path or pattern, the caller has already
   753			// resolved any existing packages to their containing module(s), and
   754			// will set both prevM.Version and forceModulePath for those modules.
   755			// The only remaining package patterns are those that are not already
   756			// provided by the build list, which are indicated by
   757			// an empty prevM.Version.
   758			base.Fatalf("go get: internal error: prevM may be set if and only if forceModulePath is set")
   759		}
   760	
   761		// If the query must be a module path, try only that module path.
   762		if forceModulePath {
   763			if path == modload.Target.Path {
   764				if vers != "latest" {
   765					return module.Version{}, fmt.Errorf("can't get a specific version of the main module")
   766				}
   767			}
   768	
   769			info, err := modload.Query(path, vers, prevM.Version, modload.Allowed)
   770			if err == nil {
   771				return module.Version{Path: path, Version: info.Version}, nil
   772			}
   773	
   774			// If the query was "upgrade" or "patch" and the current version has been
   775			// replaced, check to see whether the error was for that same version:
   776			// if so, the version was probably replaced because it is invalid,
   777			// and we should keep that replacement without complaining.
   778			if vers == "upgrade" || vers == "patch" {
   779				var vErr *module.InvalidVersionError
   780				if errors.As(err, &vErr) && vErr.Version == prevM.Version && modload.Replacement(prevM).Path != "" {
   781					return prevM, nil
   782				}
   783			}
   784	
   785			return module.Version{}, err
   786		}
   787	
   788		// If the query may be either a package or a module, try it as a package path.
   789		// If it turns out to only exist as a module, we can detect the resulting
   790		// PackageNotInModuleError and avoid a second round-trip through (potentially)
   791		// all of the configured proxies.
   792		results, err := modload.QueryPattern(path, vers, modload.Allowed)
   793		if err != nil {
   794			// If the path doesn't contain a wildcard, check whether it was actually a
   795			// module path instead. If so, return that.
   796			if !strings.Contains(path, "...") {
   797				var modErr *modload.PackageNotInModuleError
   798				if errors.As(err, &modErr) && modErr.Mod.Path == path {
   799					return modErr.Mod, nil
   800				}
   801			}
   802	
   803			return module.Version{}, err
   804		}
   805	
   806		return results[0].Mod, nil
   807	}
   808	
   809	// An upgrader adapts an underlying mvs.Reqs to apply an
   810	// upgrade policy to a list of targets and their dependencies.
   811	type upgrader struct {
   812		mvs.Reqs
   813	
   814		// cmdline maps a module path to a query made for that module at a
   815		// specific target version. Each query corresponds to a module
   816		// matched by a command line argument.
   817		cmdline map[string]*query
   818	
   819		// upgrade is a set of modules providing dependencies of packages
   820		// matched by command line arguments. If -u or -u=patch is set,
   821		// these modules are upgraded accordingly.
   822		upgrade map[string]bool
   823	}
   824	
   825	// newUpgrader creates an upgrader. cmdline contains queries made at
   826	// specific versions for modules matched by command line arguments. pkgs
   827	// is the set of packages matched by command line arguments. If -u or -u=patch
   828	// is set, modules providing dependencies of pkgs are upgraded accordingly.
   829	func newUpgrader(cmdline map[string]*query, pkgs map[string]bool) *upgrader {
   830		u := &upgrader{
   831			Reqs:    modload.Reqs(),
   832			cmdline: cmdline,
   833		}
   834		if getU != "" {
   835			u.upgrade = make(map[string]bool)
   836	
   837			// Traverse package import graph.
   838			// Initialize work queue with root packages.
   839			seen := make(map[string]bool)
   840			var work []string
   841			add := func(path string) {
   842				if !seen[path] {
   843					seen[path] = true
   844					work = append(work, path)
   845				}
   846			}
   847			for pkg := range pkgs {
   848				add(pkg)
   849			}
   850			for len(work) > 0 {
   851				pkg := work[0]
   852				work = work[1:]
   853				m := modload.PackageModule(pkg)
   854				u.upgrade[m.Path] = true
   855	
   856				// testImports is empty unless test imports were actually loaded,
   857				// i.e., -t was set or "all" was one of the arguments.
   858				imports, testImports := modload.PackageImports(pkg)
   859				for _, imp := range imports {
   860					add(imp)
   861				}
   862				for _, imp := range testImports {
   863					add(imp)
   864				}
   865			}
   866		}
   867		return u
   868	}
   869	
   870	// Required returns the requirement list for m.
   871	// For the main module, we override requirements with the modules named
   872	// one the command line, and we include new requirements. Otherwise,
   873	// we defer to u.Reqs.
   874	func (u *upgrader) Required(m module.Version) ([]module.Version, error) {
   875		rs, err := u.Reqs.Required(m)
   876		if err != nil {
   877			return nil, err
   878		}
   879		if m != modload.Target {
   880			return rs, nil
   881		}
   882	
   883		overridden := make(map[string]bool)
   884		for i, m := range rs {
   885			if q := u.cmdline[m.Path]; q != nil && q.m.Version != "none" {
   886				rs[i] = q.m
   887				overridden[q.m.Path] = true
   888			}
   889		}
   890		for _, q := range u.cmdline {
   891			if !overridden[q.m.Path] && q.m.Path != modload.Target.Path && q.m.Version != "none" {
   892				rs = append(rs, q.m)
   893			}
   894		}
   895		return rs, nil
   896	}
   897	
   898	// Upgrade returns the desired upgrade for m.
   899	//
   900	// If m was requested at a specific version on the command line, then
   901	// Upgrade returns that version.
   902	//
   903	// If -u is set and m provides a dependency of a package matched by
   904	// command line arguments, then Upgrade may provider a newer tagged version.
   905	// If m is a tagged version, then Upgrade will return the latest tagged
   906	// version (with the same minor version number if -u=patch).
   907	// If m is a pseudo-version, then Upgrade returns the latest tagged version
   908	// only if that version has a time-stamp newer than m. This special case
   909	// prevents accidental downgrades when already using a pseudo-version
   910	// newer than the latest tagged version.
   911	//
   912	// If none of the above cases apply, then Upgrade returns m.
   913	func (u *upgrader) Upgrade(m module.Version) (module.Version, error) {
   914		// Allow pkg@vers on the command line to override the upgrade choice v.
   915		// If q's version is < m.Version, then we're going to downgrade anyway,
   916		// and it's cleaner to avoid moving back and forth and picking up
   917		// extraneous other newer dependencies.
   918		// If q's version is > m.Version, then we're going to upgrade past
   919		// m.Version anyway, and again it's cleaner to avoid moving back and forth
   920		// picking up extraneous other newer dependencies.
   921		if q := u.cmdline[m.Path]; q != nil {
   922			return q.m, nil
   923		}
   924	
   925		if !u.upgrade[m.Path] {
   926			// Not involved in upgrade. Leave alone.
   927			return m, nil
   928		}
   929	
   930		// Run query required by upgrade semantics.
   931		// Note that Query "latest" is not the same as using repo.Latest,
   932		// which may return a pseudoversion for the latest commit.
   933		// Query "latest" returns the newest tagged version or the newest
   934		// prerelease version if there are no non-prereleases, or repo.Latest
   935		// if there aren't any tagged versions.
   936		// If we're querying "upgrade" or "patch", Query will compare the current
   937		// version against the chosen version and will return the current version
   938		// if it is newer.
   939		info, err := modload.Query(m.Path, string(getU), m.Version, modload.Allowed)
   940		if err != nil {
   941			// Report error but return m, to let version selection continue.
   942			// (Reporting the error will fail the command at the next base.ExitIfErrors.)
   943	
   944			// Special case: if the error is for m.Version itself and m.Version has a
   945			// replacement, then keep it and don't report the error: the fact that the
   946			// version is invalid is likely the reason it was replaced to begin with.
   947			var vErr *module.InvalidVersionError
   948			if errors.As(err, &vErr) && vErr.Version == m.Version && modload.Replacement(m).Path != "" {
   949				return m, nil
   950			}
   951	
   952			// Special case: if the error is "no matching versions" then don't
   953			// even report the error. Because Query does not consider pseudo-versions,
   954			// it may happen that we have a pseudo-version but during -u=patch
   955			// the query v0.0 matches no versions (not even the one we're using).
   956			var noMatch *modload.NoMatchingVersionError
   957			if !errors.As(err, &noMatch) {
   958				base.Errorf("go get: upgrading %s@%s: %v", m.Path, m.Version, err)
   959			}
   960			return m, nil
   961		}
   962	
   963		return module.Version{Path: m.Path, Version: info.Version}, nil
   964	}
   965	
   966	// buildListForLostUpgrade returns the build list for the module graph
   967	// rooted at lost. Unlike mvs.BuildList, the target module (lost) is not
   968	// treated specially. The returned build list may contain a newer version
   969	// of lost.
   970	//
   971	// buildListForLostUpgrade is used after a downgrade has removed a module
   972	// requested at a specific version. This helps us understand the requirements
   973	// implied by each downgrade.
   974	func buildListForLostUpgrade(lost module.Version, reqs mvs.Reqs) ([]module.Version, error) {
   975		return mvs.BuildList(lostUpgradeRoot, &lostUpgradeReqs{Reqs: reqs, lost: lost})
   976	}
   977	
   978	var lostUpgradeRoot = module.Version{Path: "lost-upgrade-root", Version: ""}
   979	
   980	type lostUpgradeReqs struct {
   981		mvs.Reqs
   982		lost module.Version
   983	}
   984	
   985	func (r *lostUpgradeReqs) Required(mod module.Version) ([]module.Version, error) {
   986		if mod == lostUpgradeRoot {
   987			return []module.Version{r.lost}, nil
   988		}
   989		return r.Reqs.Required(mod)
   990	}
   991	

View as plain text