Functions
Error
method
#
func (e *conflictError) Error() string
IsBoolFlag
method
#
func (*upgradeFlag) IsBoolFlag() bool
IsBoolFlag
method
#
func (v *dFlag) IsBoolFlag() bool
ResolvedString
method
#
ResolvedString returns a string describing m as a resolved match for q.
func (q *query) ResolvedString(m module.Version) string
Set
method
#
func (v *dFlag) Set(s string) error
Set
method
#
func (v *upgradeFlag) Set(s string) error
String
method
#
func (b *dFlag) String() string
String
method
#
String returns the original argument from which q was parsed.
func (q *query) String() string
String
method
#
func (v *upgradeFlag) String() string
applyUpgrades
method
#
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)
canMatchInModule
method
#
canMatchInModule reports whether the given module path can potentially
contain q.pattern.
func (q *query) canMatchInModule(mPath string) bool
checkAllowedOr
method
#
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
checkPackageProblems
method
#
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)
checkWildcardVersions
method
#
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)
chooseArbitrarily
method
#
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)
disambiguate
method
#
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)
errSet
function
#
errSet returns a pathSet containing the given error.
func errSet(err error) pathSet
findAndUpgradeImports
method
#
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)
findMissingWildcards
method
#
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)
init
function
#
func init()
initialSelected
method
#
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)
isNoSuchModuleVersion
function
#
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
function
#
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
isWildcard
method
#
isWildcard reports whether q is a pattern that can match multiple paths.
func (q *query) isWildcard() bool
loadPackages
method
#
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)
matchInModule
method
#
matchInModule is a caching wrapper around modload.MatchInModule.
func (r *resolver) matchInModule(ctx context.Context, pattern string, m module.Version) (packages []string, err error)
matchesPath
method
#
matchesPath reports whether the given path matches q.pattern.
func (q *query) matchesPath(path string) bool
newQuery
function
#
newQuery returns a new query parsed from the raw argument,
which must be either path or path@version.
func newQuery(raw string) (*query, error)
newResolver
function
#
func newResolver(ctx context.Context, queries []*query) *resolver
noneForPath
method
#
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)
parseArgs
function
#
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)
pathOnce
method
#
pathOnce invokes f to generate the pathSet for the given path,
if one is still needed.
Note that, unlike sync.Once, pathOnce does not guarantee that a concurrent
call to f for the given path has completed on return.
pathOnce is safe for concurrent use by multiple goroutines, but note that
multiple concurrent calls will result in the sets being added in
nondeterministic order.
func (q *query) pathOnce(path string, f func() pathSet)
performLocalQueries
method
#
func (r *resolver) performLocalQueries(ctx context.Context)
performPathQueries
method
#
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)
performPatternAllQueries
method
#
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)
performToolQueries
method
#
performToolQueries populates the candidates for each query whose
pattern is "tool".
func (r *resolver) performToolQueries(ctx context.Context)
performWildcardQueries
method
#
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)
queryModule
method
#
queryModule wraps modload.Query, substituting r.checkAllowedOr to decide
allowed versions.
func (r *resolver) queryModule(ctx context.Context, mPath string, query string, selected func(string) string) (module.Version, error)
queryNone
method
#
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)
queryPackages
method
#
queryPackages wraps modload.QueryPackage, substituting r.checkAllowedOr to
decide allowed versions.
func (r *resolver) queryPackages(ctx context.Context, pattern string, query string, selected func(string) string) (pkgMods []module.Version, err error)
queryPath
method
#
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)
queryPattern
method
#
queryPattern wraps modload.QueryPattern, substituting r.checkAllowedOr to
decide allowed versions.
func (r *resolver) queryPattern(ctx context.Context, pattern string, query string, selected func(string) string) (pkgMods []module.Version, mod module.Version, err error)
queryWildcard
method
#
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)
reportChanges
method
#
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 []module.Version, newReqs []module.Version)
reportConflict
function
#
func reportConflict(pq *query, m module.Version, conflict versionReason)
reportError
function
#
reportError logs err concisely using base.Errorf.
func reportError(q *query, err error)
reqsFromGoMod
function
#
func reqsFromGoMod(f *modfile.File) []module.Version
resolve
method
#
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)
resolveQueries
method
#
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)
runGet
function
#
func runGet(ctx context.Context, cmd *base.Command, args []string)
selected
method
#
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)
tryWildcard
method
#
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
updateBuildList
method
#
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)
updateTools
function
#
func updateTools(ctx context.Context, queries []*query, opts *modload.WriteOpts)
validate
method
#
validate reports a non-nil error if q is not sensible and well-formed.
func (q *query) validate() error
versionOkForMainModule
function
#
func versionOkForMainModule(version string) bool