Functions
AllowMissingModuleImports
function
#
AllowMissingModuleImports allows import paths to be resolved to modules
when there is no module root. Normally, this is forbidden because it's slow
and there's no way to make the result reproducible, but some commands
like 'go get' are expected to do this.
This function affects the default cfg.BuildMod when outside of a module,
so it can only be called prior to Init.
func AllowMissingModuleImports()
BinDir
function
#
func BinDir() string
BuildList
method
#
BuildList returns the selected versions of all modules present in the graph,
beginning with the main modules.
The order of the remaining elements in the list is deterministic
but arbitrary.
The caller must not modify the returned list, but may safely append to it
and may rely on it not to be modified.
func (mg *ModuleGraph) BuildList() []module.Version
CheckAllowed
function
#
CheckAllowed returns an error equivalent to ErrDisallowed if m is excluded by
the main module's go.mod or retracted by its author. Most version queries use
this to filter out versions that should not be used.
func CheckAllowed(ctx context.Context, m module.Version) error
CheckDeprecation
function
#
CheckDeprecation returns a deprecation message from the go.mod file of the
latest version of the given module. Deprecation messages are comments
before or on the same line as the module directives that start with
"Deprecated:" and run until the end of the paragraph.
CheckDeprecation returns an error if the message can't be loaded.
CheckDeprecation returns "", nil if there is no deprecation message.
func CheckDeprecation(ctx context.Context, m module.Version) (deprecation string, err error)
CheckExclusions
function
#
CheckExclusions returns an error equivalent to ErrDisallowed if module m is
excluded by the main module's go.mod file.
func CheckExclusions(ctx context.Context, m module.Version) error
CheckGodebug
function
#
func CheckGodebug(verb string, k string, v string) error
CheckRetractions
function
#
CheckRetractions returns an error if module m has been retracted by
its author.
func CheckRetractions(ctx context.Context, m module.Version) (err error)
CheckReuse
method
#
func (rr *replacementRepo) CheckReuse(ctx context.Context, old *codehost.Origin) error
CheckReuse
method
#
func (er emptyRepo) CheckReuse(ctx context.Context, old *codehost.Origin) error
Contains
method
#
func (mms *MainModuleSet) Contains(path string) bool
CreateModFile
function
#
CreateModFile initializes a new module by creating a go.mod file.
If modPath is empty, CreateModFile will attempt to infer the path from the
directory location within GOPATH.
If a vendoring configuration file is present, CreateModFile will attempt to
translate it to go.mod directives. The resulting build list may not be
exactly the same as in the legacy configuration (for example, we can't get
packages at multiple versions from the same module).
func CreateModFile(ctx context.Context, modPath string)
DirImportPath
method
#
DirImportPath returns the effective import path for dir,
provided it is within a main module, or else returns ".".
func (mms *MainModuleSet) DirImportPath(ctx context.Context, dir string) (path string, m module.Version)
EditBuildList
function
#
EditBuildList edits the global build list by first adding every module in add
to the existing build list, then adjusting versions (and adding or removing
requirements as needed) until every module in mustSelect is selected at the
given version.
(Note that the newly-added modules might not be selected in the resulting
build list: they could be lower than existing requirements or conflict with
versions in mustSelect.)
If the versions listed in mustSelect are mutually incompatible (due to one of
the listed modules requiring a higher version of another), EditBuildList
returns a *ConstraintError and leaves the build list in its previous state.
On success, EditBuildList reports whether the selected version of any module
in the build list may have been changed (possibly to or from "none") as a
result.
func EditBuildList(ctx context.Context, add []module.Version, mustSelect []module.Version) (changed bool, err error)
Enabled
function
#
Enabled reports whether modules are (or must be) enabled.
If modules are enabled but there is no main module, Enabled returns true
and then the first use of module information will call die
(usually through MustModRoot).
func Enabled() bool
EnterModule
function
#
EnterModule resets MainModules and requirements to refer to just this one module.
func EnterModule(ctx context.Context, enterModroot string)
Error
method
#
func (e *ModuleRetractedError) Error() string
Error
method
#
func (e *DirectImportFromImplicitDependencyError) Error() string
Error
method
#
func (e *sumMissingError) Error() string
Error
method
#
func (e *WildcardInFirstElementError) Error() string
Error
method
#
func (e *PackageNotInModuleError) Error() string
Error
method
#
func (e *QueryUpgradesAllError) Error() string
Error
method
#
func (queryDisabledError) Error() string
Error
method
#
func (e *invalidImportError) Error() string
Error
method
#
func (e *ConstraintError) Error() string
Error
method
#
func (e *excludedError) Error() string
Error
method
#
func (e *NoPatchBaseError) Error() string
Error
method
#
func (e *ImportMissingError) Error() string
Error
method
#
func (e *QueryMatchesMainModulesError) Error() string
Error
method
#
func (e *AmbiguousImportError) Error() string
Error
method
#
func (e *QueryMatchesPackagesInMainModuleError) Error() string
Error
method
#
func (e *NoMatchingVersionError) Error() string
Error
method
#
func (e *retractionLoadingError) Error() string
Error
method
#
func (e *ImportMissingSumError) Error() string
Error
method
#
func (goModDirtyError) Error() string
FindGoMod
function
#
FindGoMod returns the name of the go.mod file for this command,
or the empty string if there isn't one.
Most code should use Init and Enabled rather than use this directly.
It is exported mainly for Go toolchain switching, which must process
the go.mod very early at startup.
func FindGoMod(wd string) string
FindGoWork
function
#
FindGoWork returns the name of the go.work file for this command,
or the empty string if there isn't one.
Most code should use Init and Enabled rather than use this directly.
It is exported mainly for Go toolchain switching, which must process
the go.work very early at startup.
func FindGoWork(wd string) string
GetSingleIndexOrNil
method
#
func (mms *MainModuleSet) GetSingleIndexOrNil() *modFileIndex
GoVersion
method
#
GoVersion returns the Go language version for the Requirements.
func (rs *Requirements) GoVersion() string
GoVersion
method
#
GoVersion returns the go version set on the single module, in module mode,
or the go.work file in workspace mode.
func (mms *MainModuleSet) GoVersion() string
Godebugs
method
#
Godebugs returns the godebug lines set on the single module, in module mode,
or on the go.work file in workspace mode.
The caller must not modify the result.
func (mms *MainModuleSet) Godebugs() []*modfile.Godebug
Graph
method
#
Graph returns the graph of module requirements loaded from the current
root modules (as reported by RootModules).
Graph always makes a best effort to load the requirement graph despite any
errors, and always returns a non-nil *ModuleGraph.
If the requirements of any relevant module fail to load, Graph also
returns a non-nil error of type *mvs.BuildListError.
func (rs *Requirements) Graph(ctx context.Context) (*ModuleGraph, error)
HasModRoot
function
#
HasModRoot reports whether a main module is present.
HasModRoot may return false even if Enabled returns true: for example, 'get'
does not require a main module.
func HasModRoot() bool
HighestReplaced
method
#
func (mms *MainModuleSet) HighestReplaced() map[string]string
ImportFromFiles
function
#
ImportFromFiles adds modules to the build list as needed
to satisfy the imports in the named Go source files.
Errors in missing dependencies are silenced.
TODO(bcmills): Silencing errors seems off. Take a closer look at this and
figure out what the error-reporting actually ought to be.
func ImportFromFiles(ctx context.Context, gofiles []string)
ImportPath
method
#
func (e *PackageNotInModuleError) ImportPath() string
ImportPath
method
#
func (e *ImportMissingError) ImportPath() string
ImportPath
method
#
func (e *AmbiguousImportError) ImportPath() string
ImportPath
method
#
func (e *DirectImportFromImplicitDependencyError) ImportPath() string
ImportPath
method
#
func (e *ImportMissingSumError) ImportPath() string
ImportPath
method
#
func (e *invalidImportError) ImportPath() string
InGorootSrc
method
#
func (mms *MainModuleSet) InGorootSrc(m module.Version) bool
Index
method
#
func (mms *MainModuleSet) Index(m module.Version) *modFileIndex
Init
function
#
Init determines whether module mode is enabled, locates the root of the
current module (if any), sets environment variables for Git subprocesses, and
configures the cfg, codehost, load, modfetch, and search packages for use
with modules.
func Init()
InitWorkfile
function
#
InitWorkfile initializes the workFilePath variable for commands that
operate in workspace mode. It should not be called by other commands,
for example 'go mod tidy', that don't operate in workspace mode.
func InitWorkfile()
Is
method
#
func (e *ModuleRetractedError) Is(err error) bool
Is
method
#
func (e *excludedError) Is(err error) bool
IsDirect
method
#
IsDirect returns whether the given module provides a package directly
imported by a package or test in the main module.
func (rs *Requirements) IsDirect(path string) bool
IsRevisionQuery
function
#
IsRevisionQuery returns true if vers is a version query that may refer to
a particular version or revision in a repository like "v1.0.0", "master",
or "0123abcd". IsRevisionQuery returns false if vers is a query that
chooses from among available versions like "latest" or ">v1.0.0".
func IsRevisionQuery(path string, vers string) bool
Latest
method
#
func (er emptyRepo) Latest(ctx context.Context) (*modfetch.RevInfo, error)
Latest
method
#
func (rr *replacementRepo) Latest(ctx context.Context) (*modfetch.RevInfo, error)
Len
method
#
func (mms *MainModuleSet) Len() int
ListModules
function
#
ListModules returns a description of the modules matching args, if known,
along with any error preventing additional matches from being identified.
The returned slice can be nonempty even if the error is non-nil.
func ListModules(ctx context.Context, args []string, mode ListMode, reuseFile string) ([]*modinfo.ModulePublic, error)
LoadModFile
function
#
LoadModFile sets Target and, if there is a main module, parses the initial
build list from its go.mod file.
LoadModFile may make changes in memory, like adding a go directive and
ensuring requirements are consistent. The caller is responsible for ensuring
those changes are written to disk by calling LoadPackages or ListModules
(unless ExplicitWriteGoMod is set) or by calling WriteGoMod directly.
As a side-effect, LoadModFile may change cfg.BuildMod to "vendor" if
-mod wasn't set explicitly and automatic vendoring should be enabled.
If LoadModFile or CreateModFile has already been called, LoadModFile returns
the existing in-memory requirements (rather than re-reading them from disk).
LoadModFile checks the roots of the module graph for consistency with each
other, but unlike LoadModGraph does not load the full module graph or check
it for global consistency. Most callers outside of the modload package should
use LoadModGraph instead.
func LoadModFile(ctx context.Context) *Requirements
LoadModGraph
function
#
LoadModGraph loads and returns the graph of module dependencies of the main module,
without loading any packages.
If the goVersion string is non-empty, the returned graph is the graph
as interpreted by the given Go version (instead of the version indicated
in the go.mod file).
Modules are loaded automatically (and lazily) in LoadPackages:
LoadModGraph need only be called if LoadPackages is not,
typically in commands that care about modules but no particular package.
func LoadModGraph(ctx context.Context, goVersion string) (*ModuleGraph, error)
LoadPackages
function
#
LoadPackages identifies the set of packages matching the given patterns and
loads the packages in the import graph rooted at that set.
func LoadPackages(ctx context.Context, opts PackageOpts, patterns ...string) (matches []*search.Match, loadedPackages []string)
Lookup
function
#
Lookup returns the source directory, import path, and any loading error for
the package at path as imported from the package in parentDir.
Lookup requires that one of the Load functions in this package has already
been called.
func Lookup(parentPath string, parentIsStd bool, path string) (dir string, realPath string, err error)
MatchInModule
function
#
MatchInModule identifies the packages matching the given pattern within the
given module version, which does not need to be in the build list or module
requirement graph.
If m is the zero module.Version, MatchInModule matches the pattern
against the standard library (std and cmd) in GOROOT/src.
func MatchInModule(ctx context.Context, pattern string, m module.Version, tags map[string]bool) *search.Match
Max
method
#
Max returns the maximum of v1 and v2 according to gover.ModCompare.
As a special case, the version "" is considered higher than all other
versions. The main module (also known as the target) has no version and must
be chosen over other versions of the same module in the module dependency
graph.
func (*mvsReqs) Max(p string, v1 string, v2 string) string
ModContainingCWD
method
#
ModContainingCWD returns the main module containing the working directory,
or module.Version{} if none of the main modules contain the working
directory.
func (mms *MainModuleSet) ModContainingCWD() module.Version
ModFile
function
#
ModFile returns the parsed go.mod file.
Note that after calling LoadPackages or LoadModGraph,
the require statements in the modfile.File are no longer
the source of truth and will be ignored: edits made directly
will be lost at the next call to WriteGoMod.
To make permanent changes to the require statements
in go.mod, edit it before loading.
func ModFile() *modfile.File
ModFile
method
#
func (mms *MainModuleSet) ModFile(m module.Version) *modfile.File
ModFilePath
function
#
ModFilePath returns the path that would be used for the go.mod
file, if in module mode. ModFilePath calls base.Fatalf if there is no main
module, even if -modfile is set.
func ModFilePath() string
ModInfoData
function
#
func ModInfoData(info string) []byte
ModInfoProg
function
#
func ModInfoProg(info string, isgccgo bool) []byte
ModRoot
method
#
func (mms *MainModuleSet) ModRoot(m module.Version) string
ModuleInfo
function
#
func ModuleInfo(ctx context.Context, path string) *modinfo.ModulePublic
ModulePath
method
#
func (rr *replacementRepo) ModulePath() string
ModulePath
method
#
func (er emptyRepo) ModulePath() string
MustHaveModRoot
function
#
MustHaveModRoot checks that a main module or main modules are present,
and calls base.Fatalf if there are no main modules.
func MustHaveModRoot()
OverrideRoots
function
#
OverrideRoots edits the global requirement roots by replacing the specific module versions.
func OverrideRoots(ctx context.Context, replace []module.Version)
PackageModRoot
function
#
PackageModRoot returns the module root directory for the module that provides
a given package. If modules are not enabled or if the package is in the
standard library or if the package was not successfully loaded with
LoadPackages or ImportFromFiles, the empty string is returned.
func PackageModRoot(ctx context.Context, pkgpath string) string
PackageModule
function
#
PackageModule returns the module providing the package named by the import path.
func PackageModule(path string) module.Version
PackageModuleInfo
function
#
PackageModuleInfo returns information about the module that provides
a given package. If modules are not enabled or if the package is in the
standard library or if the package was not successfully loaded with
LoadPackages or ImportFromFiles, nil is returned.
func PackageModuleInfo(ctx context.Context, pkgpath string) *modinfo.ModulePublic
PathPrefix
method
#
func (mms *MainModuleSet) PathPrefix(m module.Version) string
Previous
method
#
func (*mvsReqs) Previous(m module.Version) (module.Version, error)
Query
function
#
Query looks up a revision of a given module given a version query string.
The module must be a complete module path.
The version must take one of the following forms:
- the literal string "latest", denoting the latest available, allowed
tagged version, with non-prereleases preferred over prereleases.
If there are no tagged versions in the repo, latest returns the most
recent commit.
- the literal string "upgrade", equivalent to "latest" except that if
current is a newer version, current will be returned (see below).
- the literal string "patch", denoting the latest available tagged version
with the same major and minor number as current (see below).
- v1, denoting the latest available tagged version v1.x.x.
- v1.2, denoting the latest available tagged version v1.2.x.
- v1.2.3, a semantic version string denoting that tagged version.
- v1.2.3, >=v1.2.3,
denoting the version closest to the target and satisfying the given operator,
with non-prereleases preferred over prereleases.
- a repository commit identifier or tag, denoting that commit.
current denotes the currently-selected version of the module; it may be
"none" if no version is currently selected, or "" if the currently-selected
version is unknown or should not be considered. If query is
"upgrade" or "patch", current will be returned if it is a newer
semantic version or a chronologically later pseudo-version than the
version that would otherwise be chosen. This prevents accidental downgrades
from newer pre-release or development versions.
The allowed function (which may be nil) is used to filter out unsuitable
versions (see AllowedFunc documentation for details). If the query refers to
a specific revision (for example, "master"; see IsRevisionQuery), and the
revision is disallowed by allowed, Query returns the error. If the query
does not refer to a specific revision (for example, "latest"), Query
acts as if versions disallowed by allowed do not exist.
If path is the path of the main module and the query is "latest",
Query returns Target.Version as the version.
Query often returns a non-nil *RevInfo with a non-nil error,
to provide an info.Origin that can allow the error to be cached.
func Query(ctx context.Context, path string, query string, current string, allowed AllowedFunc) (*modfetch.RevInfo, error)
QueryPackages
function
#
QueryPackages is like QueryPattern, but requires that the pattern match at
least one package and omits the non-package result (if any).
func QueryPackages(ctx context.Context, pattern string, query string, current func(string) string, allowed AllowedFunc) ([]QueryResult, error)
QueryPattern
function
#
QueryPattern looks up the module(s) containing at least one package matching
the given pattern at the given version. The results are sorted by module path
length in descending order. If any proxy provides a non-empty set of candidate
modules, no further proxies are tried.
For wildcard patterns, QueryPattern looks in modules with package paths up to
the first "..." in the pattern. For the pattern "example.com/a/b.../c",
QueryPattern would consider prefixes of "example.com/a".
If any matching package is in the main module, QueryPattern considers only
the main module and only the version "latest", without checking for other
possible modules.
QueryPattern always returns at least one QueryResult (which may be only
modOnly) or a non-nil error.
func QueryPattern(ctx context.Context, pattern string, query string, current func(string) string, allowed AllowedFunc) (pkgMods []QueryResult, modOnly *QueryResult, err error)
ReadModFile
function
#
ReadModFile reads and parses the mod file at gomod. ReadModFile properly applies the
overlay, locks the file while reading, and applies fix, if applicable.
func ReadModFile(gomod string, fix modfile.VersionFixer) (data []byte, f *modfile.File, err error)
ReadWorkFile
function
#
ReadWorkFile reads and parses the go.work file at the given path.
func ReadWorkFile(path string) (*modfile.WorkFile, error)
Replacement
function
#
Replacement returns the replacement for mod, if any. If the path in the
module.Version is relative it's relative to the single main module outside
workspace mode, or the workspace's directory in workspace mode.
func Replacement(mod module.Version) module.Version
Required
method
#
func (r *mvsReqs) Required(mod module.Version) ([]module.Version, error)
RequiredBy
method
#
RequiredBy returns the dependencies required by module m in the graph,
or ok=false if module m's dependencies are pruned out.
The caller must not modify the returned slice, but may safely append to it
and may rely on it not to be modified.
func (mg *ModuleGraph) RequiredBy(m module.Version) (reqs []module.Version, ok bool)
Reset
function
#
Reset clears all the initialized, cached state about the use of modules,
so that we can start over.
func Reset()
Selected
method
#
Selected returns the selected version of the module with the given path.
If no version is selected, Selected returns version "none".
func (mg *ModuleGraph) Selected(path string) (version string)
SetIndex
method
#
func (mms *MainModuleSet) SetIndex(m module.Version, index *modFileIndex)
ShortMessage
function
#
ShortMessage returns a string from go.mod (for example, a retraction
rationale or deprecation message) that is safe to print in a terminal.
If the given string is empty, ShortMessage returns the given default. If the
given string is too long or contains non-printable characters, ShortMessage
returns a hard-coded string.
func ShortMessage(message string, emptyDefault string) string
Stat
method
#
func (er emptyRepo) Stat(ctx context.Context, rev string) (*modfetch.RevInfo, error)
Stat
method
#
func (rr *replacementRepo) Stat(ctx context.Context, rev string) (*modfetch.RevInfo, error)
String
method
#
String returns a string that describes the full conflict path.
func (c Conflict) String() string
String
method
#
String returns a string describing the Requirements for debugging.
func (rs *Requirements) String() string
String
method
#
func (p modPruning) String() string
String
method
#
func (dq dqState) String() string
Summary
method
#
Summary returns a string that describes only the first and last modules in
the conflict path.
func (c Conflict) Summary() string
ToDirectoryPath
function
#
ToDirectoryPath adds a prefix if necessary so that path in unambiguously
an absolute path or a relative path starting with a '.' or '..'
path component.
func ToDirectoryPath(path string) string
Toolchain
method
#
Toolchain returns the toolchain set on the single module, in module mode,
or the go.work file in workspace mode.
func (mms *MainModuleSet) Toolchain() string
Tools
method
#
Tools returns the tools defined by all the main modules.
The key is the absolute package path of the tool.
func (mms *MainModuleSet) Tools() map[string]bool
Unwrap
method
#
func (e *retractionLoadingError) Unwrap() error
Unwrap
method
#
func (e *invalidImportError) Unwrap() error
Unwrap
method
#
func (e *ImportMissingError) Unwrap() error
UnwrapModuleError
method
#
UnwrapModuleError returns c.Err, but unwraps it if it is a module.ModuleError
with a version and path matching the last entry in the Path slice.
func (c Conflict) UnwrapModuleError() error
UpdateGoModFromReqs
function
#
UpdateGoModFromReqs returns a modified go.mod file using the current
requirements. It does not commit these changes to disk.
func UpdateGoModFromReqs(ctx context.Context, opts WriteOpts) (before []byte, after []byte, modFile *modfile.File, err error)
UpdateWorkFile
function
#
UpdateWorkFile updates comments on directory directives in the go.work
file to include the associated module path.
func UpdateWorkFile(wf *modfile.WorkFile)
UpdateWorkGoVersion
function
#
UpdateWorkGoVersion updates the go line in wf to be at least goVers,
reporting whether it changed the file.
func UpdateWorkGoVersion(wf *modfile.WorkFile, goVers string) (changed bool)
Upgrade
method
#
Upgrade is a no-op, here to implement mvs.Reqs.
The upgrade logic for go get -u is in ../modget/get.go.
func (*mvsReqs) Upgrade(m module.Version) (module.Version, error)
VendorDir
function
#
func VendorDir() string
Versions
method
#
Versions returns the versions from rr.repo augmented with any matching
replacement versions.
func (rr *replacementRepo) Versions(ctx context.Context, prefix string) (*modfetch.Versions, error)
Versions
method
#
func (er emptyRepo) Versions(ctx context.Context, prefix string) (*modfetch.Versions, error)
Versions
method
#
Versions returns the module.Version values of each of the main modules.
For each of them, the Path fields are ordinary module paths and the Version
fields are empty strings.
Callers should not modify the returned slice.
func (mms *MainModuleSet) Versions() []module.Version
WalkBreadthFirst
method
#
WalkBreadthFirst invokes f once, in breadth-first order, for each module
version other than "none" that appears in the graph, regardless of whether
that version is selected.
func (mg *ModuleGraph) WalkBreadthFirst(f func(m module.Version))
Why
function
#
Why returns the "go mod why" output stanza for the given package,
without the leading # comment.
The package graph must have been loaded already, usually by LoadPackages.
If there is no reason for the package to be in the current build,
Why returns an empty string.
func Why(path string) string
WhyDepth
function
#
WhyDepth returns the number of steps in the Why listing.
If there is no reason for the package to be in the current build,
WhyDepth returns 0.
func WhyDepth(path string) int
WillBeEnabled
function
#
WillBeEnabled checks whether modules should be enabled but does not
initialize modules by installing hooks. If Init has already been called,
WillBeEnabled returns the same result as Enabled.
This function is needed to break a cycle. The main package needs to know
whether modules are enabled in order to install the module or GOPATH version
of 'go get', but Init reads the -modfile flag in 'go get', so it shouldn't
be called until the command is installed and flags are parsed. Instead of
calling Init and Enabled, the main package can call this function.
func WillBeEnabled() bool
WorkFile
method
#
func (mms *MainModuleSet) WorkFile() *modfile.WorkFile
WorkFilePath
function
#
WorkFilePath returns the absolute path of the go.work file, or "" if not in
workspace mode. WorkFilePath must be called after InitWorkfile.
func WorkFilePath() string
WorkFileReplaceMap
method
#
func (mms *MainModuleSet) WorkFileReplaceMap() map[module.Version]module.Version
WriteGoMod
function
#
WriteGoMod writes the current build list back to go.mod.
func WriteGoMod(ctx context.Context, opts WriteOpts) error
WriteWorkFile
function
#
WriteWorkFile cleans and writes out the go.work file to the given path.
func WriteWorkFile(path string, wf *modfile.WorkFile) error
addDeprecation
function
#
addDeprecation fills in m.Deprecated if the module was deprecated by its
author. m.Error is set if there's an error loading deprecation information.
func addDeprecation(ctx context.Context, m *modinfo.ModulePublic)
addGoStmt
function
#
addGoStmt adds a go directive to the go.mod file if it does not already
include one. The 'go' version added, if any, is the latest version supported
by this toolchain.
func addGoStmt(modFile *modfile.File, mod module.Version, v string)
addRetraction
function
#
addRetraction fills in m.Retracted if the module was retracted by its author.
m.Error is set if there's an error loading retraction information.
func addRetraction(ctx context.Context, m *modinfo.ModulePublic)
addUpdate
function
#
addUpdate fills in m.Update if an updated version is available.
func addUpdate(ctx context.Context, m *modinfo.ModulePublic)
addVersions
function
#
addVersions fills in m.Versions with the list of known versions.
Excluded versions will be omitted. If listRetracted is false, retracted
versions will also be omitted.
func addVersions(ctx context.Context, m *modinfo.ModulePublic, listRetracted bool)
allRootsSelected
method
#
func (mg *ModuleGraph) allRootsSelected() bool
allowsVersion
method
#
allowsVersion reports whether version v is allowed by the prefix, filter, and
AllowedFunc of qm.
func (qm *queryMatcher) allowsVersion(ctx context.Context, v string) bool
appendGoAndToolchainRoots
function
#
func appendGoAndToolchainRoots(roots []module.Version, goVersion string, toolchain string, direct map[string]bool) []module.Version
applyPkgFlags
method
#
applyPkgFlags updates pkg.flags to set the given flags and propagate the
(transitive) effects of those flags, possibly loading or enqueueing further
packages as a result.
func (ld *loader) applyPkgFlags(ctx context.Context, pkg *loadPkg, flags loadPkgFlags)
buildStacks
method
#
buildStacks computes minimal import stacks for each package,
for use in error messages. When it completes, packages that
are part of the original root set have pkg.stack == nil,
and other packages have pkg.stack pointing at the next
package up the import stack in their minimal chain.
As a side effect, buildStacks also constructs ld.pkgs,
the list of all packages loaded.
func (ld *loader) buildStacks()
canonicalizeReplacePath
function
#
canonicalizeReplacePath ensures that relative, on-disk, replaced module paths
are relative to the workspace directory (in workspace mode) or to the module's
directory (in module mode, as they already are).
func canonicalizeReplacePath(r module.Version, modRoot string) module.Version
check
method
#
check reports whether m is disqualified in the given pruning context.
func (t *dqTracker) check(m module.Version, pruning modPruning) dqState
checkMultiplePaths
method
#
checkMultiplePaths verifies that a given module path is used as itself
or as a replacement for another module, but not both at the same time.
(See https://golang.org/issue/26607 and https://golang.org/issue/34650.)
func (ld *loader) checkMultiplePaths()
checkReuse
function
#
checkReuse checks whether a revision of a given module
for a given module may be reused, according to the information in origin.
func checkReuse(ctx context.Context, m module.Version, old *codehost.Origin) error
checkReuseRepo
function
#
func checkReuseRepo(ctx context.Context, repo versionRepo, path string, query string, origin *codehost.Origin) error
checkTidyCompatibility
method
#
checkTidyCompatibility emits an error if any package would be loaded from a
different module under rs than under ld.requirements.
func (ld *loader) checkTidyCompatibility(ctx context.Context, rs *Requirements, compatVersion string)
checkVendorConsistency
function
#
checkVendorConsistency verifies that the vendor/modules.txt file matches (if
go 1.14) or at least does not contradict (go 1.13 or earlier) the
requirements and replacements listed in the main module's go.mod file.
func checkVendorConsistency(indexes []*modFileIndex, modFiles []*modfile.File, modRoots []string)
cmpVersion
function
#
cmpVersion implements the comparison for versions in the module loader.
It is consistent with gover.ModCompare except that as a special case,
the version "" is considered higher than all other versions.
The main module (also known as the target) has no version and must be chosen
over other versions of the same module in the module dependency graph.
func cmpVersion(p string, v1 string, v2 string) int
commitRequirements
function
#
commitRequirements ensures go.mod and go.sum are up to date with the current
requirements.
In "mod" mode, commitRequirements writes changes to go.mod and go.sum.
In "readonly" and "vendor" modes, commitRequirements returns an error if
go.mod or go.sum are out of date in a semantically significant way.
In workspace mode, commitRequirements only writes changes to go.work.sum.
func commitRequirements(ctx context.Context, opts WriteOpts) (err error)
computePatternAll
method
#
computePatternAll returns the list of packages matching pattern "all",
starting with a list of the import paths for the packages in the main module.
func (ld *loader) computePatternAll() (all []string)
convertPruning
function
#
convertPruning returns a version of rs with the given pruning behavior.
If rs already has the given pruning, convertPruning returns rs unmodified.
func convertPruning(ctx context.Context, rs *Requirements, pruning modPruning) (*Requirements, error)
die
function
#
func die()
dirInModule
function
#
dirInModule locates the directory that would hold the package named by the given path,
if it were in the module with module path mpath and root mdir.
If path is syntactically not within mpath,
or if mdir is a local file tree (isLocal == true) and the directory
that would hold path is in a sub-module (covered by a go.mod below mdir),
dirInModule returns "", false, nil.
Otherwise, dirInModule returns the name of the directory where
Go source files would be expected, along with a boolean indicating
whether there are in fact Go source files in that directory.
A non-nil error indicates that the existence of the directory and/or
source files could not be determined, for example due to a permission error.
func dirInModule(path string, mpath string, mdir string, isLocal bool) (dir string, haveGoFiles bool, err error)
directRequirements
function
#
func directRequirements(modFiles []*modfile.File) map[string]bool
disqualify
method
#
disqualify records why the dependencies of m cannot be included in the module
graph if reached from a part of the graph with the given pruning.
Since the pruned graph is a subgraph of the unpruned graph, disqualifying a
module from a pruned part of the graph also disqualifies it in the unpruned
parts.
func (t *dqTracker) disqualify(m module.Version, fromPruning modPruning, reason dqState)
editRequirements
function
#
editRequirements returns an edited version of rs such that:
1. Each module version in mustSelect is selected.
2. Each module version in tryUpgrade is upgraded toward the indicated
version as far as can be done without violating (1).
(Other upgrades are also allowed if they are caused by
transitive requirements of versions in mustSelect or
tryUpgrade.)
3. Each module version in rs.rootModules (or rs.graph, if rs is unpruned)
is downgraded or upgraded from its original version only to the extent
needed to satisfy (1) and (2).
Generally, the module versions in mustSelect are due to the module or a
package within the module matching an explicit command line argument to 'go
get', and the versions in tryUpgrade are transitive dependencies that are
either being upgraded by 'go get -u' or being added to satisfy some
otherwise-missing package import.
If pruning is enabled, the roots of the edited requirements include an
explicit entry for each module path in tryUpgrade, mustSelect, and the roots
of rs, unless the selected version for the module path is "none".
func editRequirements(ctx context.Context, rs *Requirements, tryUpgrade []module.Version, mustSelect []module.Version) (edited *Requirements, changed bool, err error)
errWorkTooOld
function
#
func errWorkTooOld(gomod string, wf *modfile.WorkFile, goVers string) error
error
method
#
error reports an error via either os.Stderr or base.Error,
according to whether ld.AllowErrors is set.
func (ld *loader) error(err error)
exitIfErrors
method
#
exitIfErrors switches toolchains if a switch is needed
or else exits if any errors have been reported.
func (ld *loader) exitIfErrors(ctx context.Context)
expandGraph
function
#
expandGraph loads the complete module graph from rs.
If the complete graph reveals that some root of rs is not actually the
selected version of its path, expandGraph computes a new set of roots that
are consistent. (With a pruned module graph, this may result in upgrades to
other modules due to requirements that were previously pruned out.)
expandGraph returns the updated roots, along with the module graph loaded
from those roots and any error encountered while loading that graph.
expandGraph returns non-nil requirements and a non-nil graph regardless of
errors. On error, the roots might not be updated to be consistent.
func expandGraph(ctx context.Context, rs *Requirements) (*Requirements, *ModuleGraph, error)
extendGraph
function
#
extendGraph loads the module graph from roots, and iteratively extends it by
unpruning the selected version of each module path that is a root in rs or in
the roots slice until the graph reaches a fixed point.
The graph is guaranteed to converge to a fixed point because unpruning a
module version can only increase (never decrease) the selected versions,
and the set of versions for each module is finite.
The extended graph is useful for diagnosing version conflicts: for each
selected module version, it can provide a complete path of requirements from
some root to that version.
func extendGraph(ctx context.Context, rootPruning modPruning, roots []module.Version, selectedRoot map[string]string) (mg *ModuleGraph, upgradedRoot map[module.Version]bool, err error)
fetch
function
#
fetch downloads the given module (or its replacement)
and returns its location.
The isLocal return value reports whether the replacement,
if any, is local to the filesystem.
func fetch(ctx context.Context, mod module.Version) (dir string, isLocal bool, err error)
filterVersions
method
#
filterVersions classifies versions into releases and pre-releases, filtering
out:
1. versions that do not satisfy the 'allowed' predicate, and
2. "+incompatible" versions, if a compatible one satisfies the predicate
and the incompatible version is not preferred.
If the allowed predicate returns an error not equivalent to ErrDisallowed,
filterVersions returns that error.
func (qm *queryMatcher) filterVersions(ctx context.Context, versions []string) (releases []string, prereleases []string, err error)
findAltConfig
function
#
func findAltConfig(dir string) (root string, name string)
findError
method
#
func (mg *ModuleGraph) findError() error
findModule
function
#
findModule searches for the module that contains the package at path.
If the package was loaded, its containing module and true are returned.
Otherwise, module.Version{} and false are returned.
func findModule(ld *loader, path string) (module.Version, bool)
findModulePath
function
#
func findModulePath(dir string) (string, error)
findModuleRoot
function
#
func findModuleRoot(dir string) (roots string)
findStandardImportPath
function
#
func findStandardImportPath(path string) string
findWorkspaceFile
function
#
func findWorkspaceFile(dir string) (root string)
fixVersion
function
#
fixVersion returns a modfile.VersionFixer implemented using the Query function.
It resolves commit hashes and branch names to versions,
canonicalizes versions that appeared in early vgo drafts,
and does nothing for versions that already appear to be canonical.
The VersionFixer sets 'fixed' if it ever returns a non-canonical version.
func fixVersion(ctx context.Context, fixed *bool) modfile.VersionFixer
forceGoStmt
function
#
func forceGoStmt(modFile *modfile.File, mod module.Version, v string)
from
method
#
func (pp *ast.IndexExpr) from(p modPruning) T
fromExternalModule
method
#
fromExternalModule reports whether pkg was loaded from a module other than
the main module.
func (pkg *loadPkg) fromExternalModule() bool
goModSummary
function
#
goModSummary returns a summary of the go.mod file for module m,
taking into account any replacements for m, exclusions of its dependencies,
and/or vendoring.
m must be a version in the module graph, reachable from the Target module.
In readonly mode, the go.sum file must contain an entry for m's go.mod file
(or its replacement). goModSummary must not be called for the Target module
itself, as its requirements may change. Use rawGoModSummary for other
module versions.
The caller must not modify the returned summary.
func goModSummary(m module.Version) (*modFileSummary, error)
goVersion
method
#
goVersion reports the Go version that should be used for the loader's
requirements: ld.TidyGoVersion if set, or ld.requirements.GoVersion()
otherwise.
func (ld *loader) goVersion() string
has
method
#
has reports whether all of the flags in cond are set in f.
func (f loadPkgFlags) has(cond loadPkgFlags) bool
has
method
#
has reports whether all of the flags in cond are set in af.
func (af *atomicLoadPkgFlags) has(cond loadPkgFlags) bool
hasRedundantRoot
method
#
hasRedundantRoot returns true if the root list contains multiple requirements
of the same module or a requirement on any version of the main module.
Redundant requirements should be pruned, but they may influence version
selection.
func (rs *Requirements) hasRedundantRoot() bool
hasWritePerm
function
#
hasWritePerm reports whether the current user has permission to write to the
file with the given info.
func hasWritePerm(path string, _ fs.FileInfo) bool
hasWritePerm
function
#
hasWritePerm reports whether the current user has permission to write to the
file with the given info.
Although the root user on most Unix systems can write to files even without
permission, hasWritePerm reports false if no appropriate permission bit is
set even if the current user is root.
func hasWritePerm(path string, fi fs.FileInfo) bool
hasWritePerm
function
#
hasWritePerm reports whether the current user has permission to write to the
file with the given info.
func hasWritePerm(_ string, fi fs.FileInfo) bool
importFromModules
function
#
importFromModules finds the module and directory in the dependency graph of
rs containing the package with the given import path. If mg is nil,
importFromModules attempts to locate the module using only the main module
and the roots of rs before it loads the full graph.
The answer must be unique: importFromModules returns an error if multiple
modules are observed to provide the same package.
importFromModules can return a module with an empty m.Path, for packages in
the standard library.
importFromModules can return an empty directory string, for fake packages
like "C" and "unsafe".
If the package is not present in any module selected from the requirement
graph, importFromModules returns an *ImportMissingError.
If the package is present in exactly one module, importFromModules will
return the module, its root directory, and a list of other modules that
lexically could have provided the package but did not.
If skipModFile is true, the go.mod file for the package is not loaded. This
allows 'go mod tidy' to preserve a minor checksum-preservation bug
(https://go.dev/issue/56222) for modules with 'go' versions between 1.17 and
1.20, preventing unnecessary go.sum churn and network access in those
modules.
func importFromModules(ctx context.Context, path string, rs *Requirements, mg *ModuleGraph, skipModFile bool) (m module.Version, modroot string, dir string, altMods []module.Version, err error)
inWorkspaceMode
function
#
func inWorkspaceMode() bool
indexModFile
function
#
indexModFile rebuilds the index of modFile.
If modFile has been changed since it was first read,
modFile.Cleanup must be called before indexModFile.
func indexModFile(data []byte, modFile *modfile.File, mod module.Version, needsFix bool) *modFileIndex
initVendor
method
#
initVendor initializes rs.graph from the given list of vendored module
dependencies, overriding the graph that would normally be loaded from module
requirements.
func (rs *Requirements) initVendor(vendorList []module.Version)
isDisqualified
method
#
func (dq dqState) isDisqualified() bool
isStandardImportPath
function
#
func isStandardImportPath(path string) bool
isTest
method
#
isTest reports whether pkg is a test of another package.
func (pkg *loadPkg) isTest() bool
keepSums
function
#
keepSums returns the set of modules (and go.mod file entries) for which
checksums would be needed in order to reload the same set of packages
loaded by the most recent call to LoadPackages or ImportFromFiles,
including any go.mod files needed to reconstruct the MVS result
or identify go versions,
in addition to the checksums for every module in keepMods.
func keepSums(ctx context.Context, ld *loader, rs *Requirements, which whichSums) map[module.Version]bool
listModules
function
#
func listModules(ctx context.Context, rs *Requirements, args []string, mode ListMode, reuse map[module.Version]*modinfo.ModulePublic) (_ *Requirements, mods []*modinfo.ModulePublic, mgErr error)
load
method
#
load loads an individual package.
func (ld *loader) load(ctx context.Context, pkg *loadPkg)
loadFromRoots
function
#
loadFromRoots attempts to load the build graph needed to process a set of
root packages and their dependencies.
The set of root packages is returned by the params.listRoots function, and
expanded to the full set of packages by tracing imports (and possibly tests)
as needed.
func loadFromRoots(ctx context.Context, params loaderParams) *loader
loadModFile
function
#
func loadModFile(ctx context.Context, opts *PackageOpts) (*Requirements, error)
loadWorkFile
function
#
func loadWorkFile(path string) (workFile *modfile.WorkFile, modRoots []string, err error)
lookupRepo
function
#
func lookupRepo(ctx context.Context, proxy string, path string) (repo versionRepo, err error)
makeMainModules
function
#
makeMainModules creates a MainModuleSet and associated variables according to
the given main modules.
func makeMainModules(ms []module.Version, rootDirs []string, modFiles []*modfile.File, indices []*modFileIndex, workFile *modfile.WorkFile) *MainModuleSet
matchLocalDirs
function
#
matchLocalDirs is like m.MatchDirs, but tries to avoid scanning directories
outside of the standard library and active modules.
func matchLocalDirs(ctx context.Context, modRoots []string, m *search.Match, rs *Requirements)
matchPackages
function
#
matchPackages is like m.MatchPackages, but uses a local variable (rather than
a global) for tags, can include or exclude packages in the standard library,
and is restricted to the given list of modules.
func matchPackages(ctx context.Context, m *search.Match, tags map[string]bool, filter stdFilter, modules []module.Version)
maybeInModule
function
#
maybeInModule reports whether, syntactically,
a package with the given import path could be supplied
by a module with the given module path (mpath).
func maybeInModule(path string, mpath string) bool
mergeOrigin
function
#
mergeOrigin returns the union of data from two origins,
returning either a new origin or one of its unmodified arguments.
If the two origins conflict including if either is nil,
mergeOrigin returns nil.
func mergeOrigin(m1 *codehost.Origin, m2 *codehost.Origin) *codehost.Origin
modFileIsDirty
method
#
modFileIsDirty reports whether the go.mod file differs meaningfully
from what was indexed.
If modFile has been changed (even cosmetically) since it was first read,
modFile.Cleanup must be called before modFileIsDirty.
func (i *modFileIndex) modFileIsDirty(modFile *modfile.File) bool
modFilePath
function
#
func modFilePath(modRoot string) string
modinfoError
function
#
modinfoError wraps an error to create an error message in
modinfo.ModuleError with minimal redundancy.
func modinfoError(path string, vers string, err error) *modinfo.ModuleError
modkey
function
#
modkey returns the module.Version under which the checksum for m's go.mod
file is stored in the go.sum file.
func modkey(m module.Version) module.Version
moduleInfo
function
#
moduleInfo returns information about module m, loaded from the requirements
in rs (which may be nil to indicate that m was not loaded from a requirement
graph).
func moduleInfo(ctx context.Context, rs *Requirements, m module.Version, mode ListMode, reuse map[module.Version]*modinfo.ModulePublic) *modinfo.ModulePublic
modulePrefixesExcludingTarget
function
#
modulePrefixesExcludingTarget returns all prefixes of path that may plausibly
exist as a module, excluding targetPrefix but otherwise including path
itself, sorted by descending length. Prefixes that are not valid module paths
but are valid package paths (like "m" or "example.com/.gen") are included,
since they might be replaced.
func modulePrefixesExcludingTarget(path string) []string
modulesTextIsForWorkspace
function
#
func modulesTextIsForWorkspace(vendorDir string) (bool, error)
mustGetSingleMainModule
method
#
func (mms *MainModuleSet) mustGetSingleMainModule() module.Version
mustHaveCompleteRequirements
function
#
func mustHaveCompleteRequirements() bool
mustHaveGoRoot
function
#
func mustHaveGoRoot(roots []module.Version)
mustHaveSums
function
#
mustHaveSums reports whether we require that all checksums
needed to load or build packages are already present in the go.sum file.
func mustHaveSums() bool
newQueryMatcher
function
#
newQueryMatcher returns a new queryMatcher that matches the versions
specified by the given query on the module with the given path.
If the query can only be resolved by statting a non-SemVer revision,
newQueryMatcher returns errRevQuery.
func newQueryMatcher(path string, query string, current string, allowed AllowedFunc) (*queryMatcher, error)
newRequirements
function
#
newRequirements returns a new requirement set with the given root modules.
The dependencies of the roots will be loaded lazily at the first call to the
Graph method.
The rootModules slice must be sorted according to gover.ModSort.
The caller must not modify the rootModules slice or direct map after passing
them to newRequirements.
If vendoring is in effect, the caller must invoke initVendor on the returned
*Requirements before any other method.
func newRequirements(pruning modPruning, rootModules []module.Version, direct map[string]bool) *Requirements
overrideRoots
function
#
func overrideRoots(ctx context.Context, rs *Requirements, replace []module.Version) *Requirements
path
method
#
path returns the path from m to the reason it is disqualified, which may be
either a module that violates constraints or an error in loading
requirements.
If m is not disqualified, path returns (nil, nil).
func (t *dqTracker) path(m module.Version, pruning modPruning) (path []module.Version, err error)
pathInModuleCache
function
#
pathInModuleCache returns the import path of the directory dir,
if dir is in the module cache copy of a module in our build list.
func pathInModuleCache(ctx context.Context, dir string, rs *Requirements) string
pkg
method
#
pkg locates the *loadPkg for path, creating and queuing it for loading if
needed, and updates its state to reflect the given flags.
The imports of the returned *loadPkg will be loaded asynchronously in the
ld.work queue, and its test (if requested) will also be populated once
imports have been resolved. When ld.work goes idle, all transitive imports of
the requested package (and its test, if requested) will have been loaded.
func (ld *loader) pkg(ctx context.Context, path string, flags loadPkgFlags) *loadPkg
pkgTest
method
#
pkgTest locates the test of pkg, creating it if needed, and updates its state
to reflect the given flags.
pkgTest requires that the imports of pkg have already been loaded (flagged
with pkgImportsLoaded).
func (ld *loader) pkgTest(ctx context.Context, pkg *loadPkg, testFlags loadPkgFlags) *loadPkg
preloadRootModules
method
#
preloadRootModules loads the module requirements needed to identify the
selected version of each module providing a package in rootPkgs,
adding new root modules to the module graph if needed.
func (ld *loader) preloadRootModules(ctx context.Context, rootPkgs []string) (changedBuildList bool)
previousVersion
function
#
previousVersion returns the tagged version of m.Path immediately prior to
m.Version, or version "none" if no prior version is tagged.
Since the version of a main module is not found in the version list,
it has no previous version.
func previousVersion(ctx context.Context, m module.Version) (module.Version, error)
pruningForGoVersion
function
#
func pruningForGoVersion(goVersion string) modPruning
queryImport
function
#
queryImport attempts to locate a module that can be added to the current
build list to provide the package with the given import path.
Unlike QueryPattern, queryImport prefers to add a replaced version of a
module *before* checking the proxies for a version to add.
func queryImport(ctx context.Context, path string, rs *Requirements) (module.Version, error)
queryLatestVersionIgnoringRetractions
function
#
queryLatestVersionIgnoringRetractions looks up the latest version of the
module with the given path without considering retracted or excluded
versions.
If all versions of the module are replaced,
queryLatestVersionIgnoringRetractions returns the replacement without making
a query.
If the queried latest version is replaced,
queryLatestVersionIgnoringRetractions returns the replacement.
func queryLatestVersionIgnoringRetractions(ctx context.Context, path string) (latest module.Version, err error)
queryPrefixModules
function
#
func queryPrefixModules(ctx context.Context, candidateModules []string, queryModule func(ctx context.Context, path string) (QueryResult, error)) (found []QueryResult, err error)
queryProxy
function
#
func queryProxy(ctx context.Context, proxy string, path string, query string, current string, allowed AllowedFunc, reuse map[module.Version]*modinfo.ModulePublic) (*modfetch.RevInfo, error)
queryReuse
function
#
queryReuse is like Query but also takes a map of module info that can be reused
if the validation criteria in Origin are met.
func queryReuse(ctx context.Context, path string, query string, current string, allowed AllowedFunc, reuse map[module.Version]*modinfo.ModulePublic) (*modfetch.RevInfo, error)
rawGoModData
function
#
rawGoModData returns the content of the go.mod file for module m, ignoring
all replacements that may apply to m.
rawGoModData cannot be used on the main module outside of workspace mode.
Unlike rawGoModSummary, rawGoModData does not cache its results in memory.
Use rawGoModSummary instead unless you specifically need these bytes.
func rawGoModData(m module.Version) (name string, data []byte, err error)
rawGoModSummary
function
#
rawGoModSummary returns a new summary of the go.mod file for module m,
ignoring all replacements that may apply to m and excludes that may apply to
its dependencies.
rawGoModSummary cannot be used on the main module outside of workspace mode.
The modFileSummary can still be used for retractions and deprecations
even if a TooNewError is returned.
func rawGoModSummary(m module.Version) (*modFileSummary, error)
readModGraph
function
#
readModGraph reads and returns the module dependency graph starting at the
given roots.
The requirements of the module versions found in the unprune map are included
in the graph even if they would normally be pruned out.
Unlike LoadModGraph, readModGraph does not attempt to diagnose or update
inconsistent roots.
func readModGraph(ctx context.Context, pruning modPruning, roots []module.Version, unprune map[module.Version]bool) (*ModuleGraph, error)
readVendorList
function
#
readVendorList reads the list of vendored modules from vendor/modules.txt.
func readVendorList(vendorDir string)
replaceRelativeTo
function
#
func replaceRelativeTo() string
replacement
function
#
func replacement(mod module.Version, replace map[module.Version]module.Version) (fromVersion string, to module.Version, ok bool)
replacementFrom
function
#
replacementFrom returns the replacement for mod, if any, the modroot of the replacement if it appeared in a go.mod,
and the source of the replacement. The replacement is relative to the go.work or go.mod file it appears in.
func replacementFrom(mod module.Version) (r module.Version, modroot string, fromFile string)
replacementStat
method
#
func (rr *replacementRepo) replacementStat(v string) (*modfetch.RevInfo, error)
require
method
#
require records that m directly requires r, in case r becomes disqualified.
(These edges are in the opposite direction from the edges in an mvs.Graph.)
If r is already disqualified, require propagates the disqualification to m
and returns the reason for the disqualification.
func (t *dqTracker) require(m module.Version, r module.Version) (ok bool)
requirementsFromModFiles
function
#
requirementsFromModFiles returns the set of non-excluded requirements from
the global modFile.
func requirementsFromModFiles(ctx context.Context, workFile *modfile.WorkFile, modFiles []*modfile.File, opts *PackageOpts) *Requirements
reset
method
#
func (ld *loader) reset()
resolveLocalPackage
function
#
resolveLocalPackage resolves a filesystem path to a package path.
func resolveLocalPackage(ctx context.Context, dir string, rs *Requirements) (string, error)
resolveMissingImports
method
#
resolveMissingImports returns a set of modules that could be added as
dependencies in order to resolve missing packages from pkgs.
The newly-resolved packages are added to the addedModuleFor map, and
resolveMissingImports returns a map from each new module version to
the first missing package that module would resolve.
func (ld *loader) resolveMissingImports(ctx context.Context) (modAddedBy map[module.Version]*loadPkg, err error)
resolveReplacement
function
#
resolveReplacement returns the module actually used to load the source code
for m: either m itself, or the replacement for m (iff m is replaced).
It also returns the modroot of the module providing the replacement if
one was found.
func resolveReplacement(m module.Version) module.Version
rootSelected
method
#
rootSelected returns the version of the root dependency with the given module
path, or the zero module.Version and ok=false if the module is not a root
dependency.
func (rs *Requirements) rootSelected(path string) (version string, ok bool)
rootsFromModFile
function
#
func rootsFromModFile(m module.Version, modFile *modfile.File, addToolchainRoot addToolchainRoot) (roots []module.Version, direct map[string]bool)
scanDir
function
#
scanDir is like imports.ScanDir but elides known magic imports from the list,
so that we do not go looking for packages that don't really exist.
The standard magic import is "C", for cgo.
The only other known magic imports are appengine and appengine/*.
These are so old that they predate "go get" and did not use URL-like paths.
Most code today now uses google.golang.org/appengine instead,
but not all code has been so updated. When we mostly ignore build tags
during "go vendor", we look into "// +build appengine" files and
may see these legacy imports. We drop them so that the module
search does not look for modules to try to satisfy them.
func scanDir(modroot string, dir string, tags map[string]bool) (imports_ []string, testImports []string, err error)
setDefaultBuildMod
function
#
setDefaultBuildMod sets a default value for cfg.BuildMod if the -mod flag
wasn't provided. setDefaultBuildMod may be called multiple times.
func setDefaultBuildMod()
shortPathErrorList
function
#
func shortPathErrorList(err error) error
spotCheckRoots
function
#
spotCheckRoots reports whether the versions of the roots in rs satisfy the
explicit requirements of the modules in mods.
func spotCheckRoots(ctx context.Context, rs *Requirements, mods map[module.Version]bool) bool
stackText
method
#
stackText builds the import stack text to use when
reporting an error in pkg. It has the general form
root imports
other imports
other2 tested by
other2.test imports
pkg
func (pkg *loadPkg) stackText() string
stdVendor
method
#
stdVendor returns the canonical import path for the package with the given
path when imported from the standard-library package at parentPath.
func (ld *loader) stdVendor(parentPath string, path string) string
suggestGopkgIn
function
#
func suggestGopkgIn(path string) string
suggestModulePath
function
#
func suggestModulePath(path string) string
switchIfErrors
method
#
switchIfErrors switches toolchains if a switch is needed.
func (ld *loader) switchIfErrors(ctx context.Context)
tidyPrunedRoots
function
#
tidyPrunedRoots returns a minimal set of root requirements that maintains the
invariants of the go.mod file needed to support graph pruning for the given
packages:
1. For each package marked with pkgInAll, the module path that provided that
package is included as a root.
2. For all packages, the module that provided that package either remains
selected at the same version or is upgraded by the dependencies of a
root.
If any module that provided a package has been upgraded above its previous
version, the caller may need to reload and recompute the package graph.
To ensure that the loading process eventually converges, the caller should
add any needed roots from the tidy root set (without removing existing untidy
roots) until the set of roots has converged.
func tidyPrunedRoots(ctx context.Context, mainModule module.Version, old *Requirements, pkgs []*loadPkg) (*Requirements, error)
tidyRoots
function
#
tidyRoots trims the root dependencies to the minimal requirements needed to
both retain the same versions of all packages in pkgs and satisfy the
graph-pruning invariants (if applicable).
func tidyRoots(ctx context.Context, rs *Requirements, pkgs []*loadPkg) (*Requirements, error)
tidyUnprunedRoots
function
#
tidyUnprunedRoots returns a minimal set of root requirements that maintains
the selected version of every module that provided or lexically could have
provided a package in pkgs, and includes the selected version of every such
module in direct as a root.
func tidyUnprunedRoots(ctx context.Context, mainModule module.Version, old *Requirements, pkgs []*loadPkg) (*Requirements, error)
toReplaceMap
function
#
func toReplaceMap(replacements []*modfile.Replace) map[module.Version]module.Version
update
method
#
update sets the given flags in af (in addition to any flags already set).
update returns the previous flag state so that the caller may determine which
flags were newly-set.
func (af *atomicLoadPkgFlags) update(flags loadPkgFlags) (old loadPkgFlags)
updatePrunedRoots
function
#
updatePrunedRoots returns a set of root requirements that maintains the
invariants of the go.mod file needed to support graph pruning:
1. The selected version of the module providing each package marked with
either pkgInAll or pkgIsRoot is included as a root.
Note that certain root patterns (such as '...') may explode the root set
to contain every module that provides any package imported (or merely
required) by any other module.
2. Each root appears only once, at the selected version of its path
(if rs.graph is non-nil) or at the highest version otherwise present as a
root (otherwise).
3. Every module path that appears as a root in rs remains a root.
4. Every version in add is selected at its given version unless upgraded by
(the dependencies of) an existing root or another module in add.
The packages in pkgs are assumed to have been loaded from either the roots of
rs or the modules selected in the graph of rs.
The above invariants together imply the graph-pruning invariants for the
go.mod file:
1. (The import invariant.) Every module that provides a package transitively
imported by any package or test in the main module is included as a root.
This follows by induction from (1) and (3) above. Transitively-imported
packages loaded during this invocation are marked with pkgInAll (1),
and by hypothesis any transitively-imported packages loaded in previous
invocations were already roots in rs (3).
2. (The argument invariant.) Every module that provides a package matching
an explicit package pattern is included as a root. This follows directly
from (1): packages matching explicit package patterns are marked with
pkgIsRoot.
3. (The completeness invariant.) Every module that contributed any package
to the build is required by either the main module or one of the modules
it requires explicitly. This invariant is left up to the caller, who must
not load packages from outside the module graph but may add roots to the
graph, but is facilitated by (3). If the caller adds roots to the graph in
order to resolve missing packages, then updatePrunedRoots will retain them,
the selected versions of those roots cannot regress, and they will
eventually be written back to the main module's go.mod file.
(See https://golang.org/design/36460-lazy-module-loading#invariants for more
detail.)
func updatePrunedRoots(ctx context.Context, direct map[string]bool, rs *Requirements, pkgs []*loadPkg, add []module.Version, rootsImported bool) (*Requirements, error)
updateRequirements
method
#
updateRequirements ensures that ld.requirements is consistent with the
information gained from ld.pkgs.
In particular:
- Modules that provide packages directly imported from the main module are
marked as direct, and are promoted to explicit roots. If a needed root
cannot be promoted due to -mod=readonly or -mod=vendor, the importing
package is marked with an error.
- If ld scanned the "all" pattern independent of build constraints, it is
guaranteed to have seen every direct import. Module dependencies that did
not provide any directly-imported package are then marked as indirect.
- Root dependencies are updated to their selected versions.
The "changed" return value reports whether the update changed the selected
version of any module that either provided a loaded package or may now
provide a package that was previously unresolved.
func (ld *loader) updateRequirements(ctx context.Context) (changed bool, err error)
updateRoots
function
#
func updateRoots(ctx context.Context, direct map[string]bool, rs *Requirements, pkgs []*loadPkg, add []module.Version, rootsImported bool) (*Requirements, error)
updateUnprunedRoots
function
#
updateUnprunedRoots returns a set of root requirements that includes the selected
version of every module path in direct as a root, and maintains the selected
version of every module selected in the graph of rs.
The roots are updated such that:
1. The selected version of every module path in direct is included as a root
(if it is not "none").
2. Each root is the selected version of its path. (We say that such a root
set is “consistent”.)
3. Every version selected in the graph of rs remains selected unless upgraded
by a dependency in add.
4. Every version in add is selected at its given version unless upgraded by
(the dependencies of) an existing root or another module in add.
func updateUnprunedRoots(ctx context.Context, direct map[string]bool, rs *Requirements, add []module.Version) (*Requirements, error)
updateWorkspaceRoots
function
#
func updateWorkspaceRoots(ctx context.Context, direct map[string]bool, rs *Requirements, add []module.Version) (*Requirements, error)
versionHasGoMod
function
#
versionHasGoMod returns whether a version has a go.mod file.
versionHasGoMod fetches the go.mod file (possibly a fake) and true if it
contains anything other than a module directive with the same path. When a
module does not have a real go.mod file, the go command acts as if it had one
that only contained a module directive. Normal go.mod files created after
1.12 at least have a go directive.
This function is a heuristic, since it's possible to commit a file that would
pass this test. However, we only need a heuristic for determining whether
+incompatible versions may be "latest", which is what this function is used
for.
This heuristic is useful for two reasons: first, when using a proxy,
this lets us fetch from the .mod endpoint which is much faster than the .zip
endpoint. The .mod file is used anyway, even if the .zip file contains a
go.mod with different content. Second, if we don't fetch the .zip, then
we don't need to verify it in go.sum. This makes 'go list -m -u' faster
and simpler.
func versionHasGoMod(_ context.Context, m module.Version) (bool, error)
versions
function
#
func versions(ctx context.Context, path string, allowed AllowedFunc) (versions []string, origin *codehost.Origin, err error)
walkFromIndex
function
#
walkFromIndex matches packages in a module using the module index. modroot
is the module's root directory on disk, index is the modindex.Module for the
module, and importPathRoot is the module's path prefix.
func walkFromIndex(index *modindex.Module, importPathRoot string, isMatch func(string) bool, treeCanMatch func(string) bool, tags map[string]bool, have map[string]bool, addPkg func(string))
why
method
#
why returns the text to use in "go mod why" output about the given package.
It is less ornate than the stackText but contains the same information.
func (pkg *loadPkg) why() string