var CmdGet … var HelpVCS … var getD … var getF … var getFix … var getM … var getT … var getU … var getTool … var getInsecure … type upgradeFlag … func (*upgradeFlag) IsBoolFlag() bool { … } func (v *upgradeFlag) Set(s string) error { … } func (v *upgradeFlag) String() string { … } type dFlag … func (v *dFlag) IsBoolFlag() bool { … } func (v *dFlag) Set(s string) error { … } func (b *dFlag) String() string { … } func init() { … } func runGet(ctx context.Context, cmd *base.Command, args []string) { … } func updateTools(ctx context.Context, queries []*query, opts *modload.WriteOpts) { … } // parseArgs parses command-line arguments and reports errors. // // The command-line arguments are of the form path@version or simply path, with // implicit @upgrade. path@none is "downgrade away". func parseArgs(ctx context.Context, rawArgs []string) (dropToolchain bool, queries []*query) { … } type resolver … type versionReason … type matchInModuleKey … func newResolver(ctx context.Context, queries []*query) *resolver { … } // initialSelected returns the version of the module with the given path that // was selected at the start of this 'go get' invocation. func (r *resolver) initialSelected(mPath string) (version string) { … } // selected returns the version of the module with the given path that is // selected in the resolver's current build list. func (r *resolver) selected(mPath string) (version string) { … } // noneForPath returns a "none" query matching the given module path, // or found == false if no such query exists. func (r *resolver) noneForPath(mPath string) (nq *query, found bool) { … } // queryModule wraps modload.Query, substituting r.checkAllowedOr to decide // allowed versions. func (r *resolver) queryModule(ctx context.Context, mPath, query string, selected func(string) string) (module.Version, error) { … } // queryPackages wraps modload.QueryPackage, substituting r.checkAllowedOr to // decide allowed versions. func (r *resolver) queryPackages(ctx context.Context, pattern, query string, selected func(string) string) (pkgMods []module.Version, err error) { … } // queryPattern wraps modload.QueryPattern, substituting r.checkAllowedOr to // decide allowed versions. func (r *resolver) queryPattern(ctx context.Context, pattern, query string, selected func(string) string) (pkgMods []module.Version, mod module.Version, err error) { … } // checkAllowedOr is like modload.CheckAllowed, but it always allows the requested // and current versions (even if they are retracted or otherwise excluded). func (r *resolver) checkAllowedOr(requested string, selected func(string) string) modload.AllowedFunc { … } // matchInModule is a caching wrapper around modload.MatchInModule. func (r *resolver) matchInModule(ctx context.Context, pattern string, m module.Version) (packages []string, err error) { … } // queryNone adds a candidate set to q for each module matching q.pattern. // Each candidate set has only one possible module version: the matched // module at version "none". // // We interpret arguments to 'go get' as packages first, and fall back to // modules second. However, no module exists at version "none", and therefore no // package exists at that version either: we know that the argument cannot match // any packages, and thus it must match modules instead. func (r *resolver) queryNone(ctx context.Context, q *query) { … } func (r *resolver) performLocalQueries(ctx context.Context) { … } // performWildcardQueries populates the candidates for each query whose pattern // is a wildcard. // // The candidates for a given module path matching (or containing a package // matching) a wildcard query depend only on the initial build list, but the set // of modules may be expanded by other queries, so wildcard queries need to be // re-evaluated whenever a potentially-matching module path is added to the // build list. func (r *resolver) performWildcardQueries(ctx context.Context) { … } // queryWildcard adds a candidate set to q for each module for which: // - some version of the module is already in the build list, and // - that module exists at some version matching q.version, and // - either the module path itself matches q.pattern, or some package within // the module at q.version matches q.pattern. func (r *resolver) queryWildcard(ctx context.Context, q *query) { … } // tryWildcard returns a pathSet for module m matching query q. // If m does not actually match q, tryWildcard returns an empty pathSet. func (r *resolver) tryWildcard(ctx context.Context, q *query, m module.Version) pathSet { … } // findMissingWildcards adds a candidate set for each query in r.wildcardQueries // that has not yet resolved to any version containing packages. func (r *resolver) findMissingWildcards(ctx context.Context) { … } // checkWildcardVersions reports an error if any module in the build list has a // path (or contains a package) matching a query with a wildcard pattern, but // has a selected version that does *not* match the query. func (r *resolver) checkWildcardVersions(ctx context.Context) { … } // performPathQueries populates the candidates for each query whose pattern is // a path literal. // // The candidate packages and modules for path literals depend only on the // initial build list, not the current build list, so we only need to query path // literals once. func (r *resolver) performPathQueries(ctx context.Context) { … } // queryPath adds a candidate set to q for the package with path q.pattern. // The candidate set consists of all modules that could provide q.pattern // and have a version matching q, plus (if it exists) the module whose path // is itself q.pattern (at a matching version). func (r *resolver) queryPath(ctx context.Context, q *query) { … } // performToolQueries populates the candidates for each query whose // pattern is "tool". func (r *resolver) performToolQueries(ctx context.Context) { … } // performPatternAllQueries populates the candidates for each query whose // pattern is "all". // // The candidate modules for a given package in "all" depend only on the initial // build list, but we cannot follow the dependencies of a given package until we // know which candidate is selected — and that selection may depend on the // results of other queries. We need to re-evaluate the "all" queries whenever // the module for one or more packages in "all" are resolved. func (r *resolver) performPatternAllQueries(ctx context.Context) { … } // findAndUpgradeImports returns a pathSet for each package that is not yet // in the build list but is transitively imported by the packages matching the // given queries (which must already have been resolved). // // If the getU flag ("-u") is set, findAndUpgradeImports also returns a // pathSet for each module that is not constrained by any other // command-line argument and has an available matching upgrade. func (r *resolver) findAndUpgradeImports(ctx context.Context, queries []*query) (upgrades []pathSet) { … } // loadPackages loads the packages matching the given patterns, invoking the // findPackage function for each package that may require a change to the // build list. // // loadPackages invokes the findPackage function for each package loaded from a // module outside the main module. If the module or version that supplies that // package needs to be changed due to a query, findPackage may return false // and the imports of that package will not be loaded. // // loadPackages also invokes the findPackage function for each imported package // that is neither present in the standard library nor in any module in the // build list. func (r *resolver) loadPackages(ctx context.Context, patterns []string, findPackage func(ctx context.Context, path string, m module.Version) (versionOk bool)) { … } var errVersionChange … // resolveQueries resolves candidate sets that are attached to the given // queries and/or needed to provide the given missing-package dependencies. // // resolveQueries starts by resolving one module version from each // unambiguous pathSet attached to the given queries. // // If no unambiguous query results in a change to the build list, // resolveQueries revisits the ambiguous query candidates and resolves them // arbitrarily in order to guarantee forward progress. // // If all pathSets are resolved without any changes to the build list, // resolveQueries returns with changed=false. func (r *resolver) resolveQueries(ctx context.Context, queries []*query) (changed bool) { … } // applyUpgrades disambiguates candidate sets that are needed to upgrade (or // provide) transitive dependencies imported by previously-resolved packages. // // applyUpgrades modifies the build list by adding one module version from each // pathSet in upgrades, then downgrading (or further upgrading) those modules as // needed to maintain any already-resolved versions of other modules. // applyUpgrades does not mark the new versions as resolved, so they can still // be further modified by other queries (such as wildcards). // // If all pathSets are resolved without any changes to the build list, // applyUpgrades returns with changed=false. func (r *resolver) applyUpgrades(ctx context.Context, upgrades []pathSet) (changed bool) { … } // disambiguate eliminates candidates from cs that conflict with other module // versions that have already been resolved. If there is only one (unique) // remaining candidate, disambiguate returns that candidate, along with // an indication of whether that result interprets cs.path as a package // // Note: we're only doing very simple disambiguation here. The goal is to // reproduce the user's intent, not to find a solution that a human couldn't. // In the vast majority of cases, we expect only one module per pathSet, // but we want to give some minimal additional tools so that users can add an // extra argument or two on the command line to resolve simple ambiguities. func (r *resolver) disambiguate(cs pathSet) (filtered pathSet, isPackage bool, m module.Version, unique bool) { … } // chooseArbitrarily returns an arbitrary (but deterministic) module version // from among those in the given set. // // chooseArbitrarily prefers module paths that were already in the build list at // the start of 'go get', prefers modules that provide packages over those that // do not, and chooses the first module meeting those criteria (so biases toward // longer paths). func (r *resolver) chooseArbitrarily(cs pathSet) (isPackage bool, m module.Version) { … } // checkPackageProblems reloads packages for the given patterns and reports // missing and ambiguous package errors. It also reports retractions and // deprecations for resolved modules and modules needed to build named packages. // It also adds a sum for each updated module in the build list if we had one // before and didn't get one while loading packages. // // We skip missing-package errors earlier in the process, since we want to // resolve pathSets ourselves, but at that point, we don't have enough context // to log the package-import chains leading to each error. func (r *resolver) checkPackageProblems(ctx context.Context, pkgPatterns []string) { … } // reportChanges logs version changes to os.Stderr. // // reportChanges only logs changes to modules named on the command line and to // explicitly required modules in go.mod. Most changes to indirect requirements // are not relevant to the user and are not logged. // // reportChanges should be called after WriteGoMod. func (r *resolver) reportChanges(oldReqs, newReqs []module.Version) { … } // resolve records that module m must be at its indicated version (which may be // "none") due to query q. If some other query forces module m to be at a // different version, resolve reports a conflict error. func (r *resolver) resolve(q *query, m module.Version) { … } // updateBuildList updates the module loader's global build list to be // consistent with r.resolvedVersion, and to include additional modules // provided that they do not conflict with the resolved versions. // // If the additional modules conflict with the resolved versions, they will be // downgraded to a non-conflicting version (possibly "none"). // // If the resulting build list is the same as the one resulting from the last // call to updateBuildList, updateBuildList returns with changed=false. func (r *resolver) updateBuildList(ctx context.Context, additions []module.Version) (changed bool) { … } func reqsFromGoMod(f *modfile.File) []module.Version { … } // isNoSuchModuleVersion reports whether err indicates that the requested module // does not exist at the requested version, either because the module does not // exist at all or because it does not include that specific version. func isNoSuchModuleVersion(err error) bool { … } // isNoSuchPackageVersion reports whether err indicates that the requested // package does not exist at the requested version, either because no module // that could contain it exists at that version, or because every such module // that does exist does not actually contain the package. func isNoSuchPackageVersion(err error) bool { … }