var loaded … type PackageOpts … // 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) { … } // 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) { … } // resolveLocalPackage resolves a filesystem path to a package path. func resolveLocalPackage(ctx context.Context, dir string, rs *Requirements) (string, error) { … } var errDirectoryNotFound … var errPkgIsGorootSrc … var errPkgIsBuiltin … // 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 { … } // 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) { … } // 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) { … } // PackageModule returns the module providing the package named by the import path. func PackageModule(path string) module.Version { … } // 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, realPath string, err error) { … } type loader … type loaderParams … func (ld *loader) reset() { … } // error reports an error via either os.Stderr or base.Error, // according to whether ld.AllowErrors is set. func (ld *loader) error(err error) { … } // switchIfErrors switches toolchains if a switch is needed. func (ld *loader) switchIfErrors(ctx context.Context) { … } // exitIfErrors switches toolchains if a switch is needed // or else exits if any errors have been reported. func (ld *loader) exitIfErrors(ctx context.Context) { … } // 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 { … } type loadPkg … type loadPkgFlags … const pkgInAll … const pkgIsRoot … const pkgFromRoot … const pkgImportsLoaded … // has reports whether all of the flags in cond are set in f. func (f loadPkgFlags) has(cond loadPkgFlags) bool { … } type atomicLoadPkgFlags … // 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) { … } // has reports whether all of the flags in cond are set in af. func (af *atomicLoadPkgFlags) has(cond loadPkgFlags) bool { … } // isTest reports whether pkg is a test of another package. func (pkg *loadPkg) isTest() bool { … } // fromExternalModule reports whether pkg was loaded from a module other than // the main module. func (pkg *loadPkg) fromExternalModule() bool { … } var errMissing … // 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 { … } // 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) { … } // 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) { … } // 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 { … } // 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) { … } // 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) { … } // load loads an individual package. func (ld *loader) load(ctx context.Context, pkg *loadPkg) { … } // 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 { … } // 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, path string) string { … } // 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) { … } // 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() { … } // 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) { … } // 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_, testImports []string, err error) { … } // 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() { … } // 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 { … } // 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 { … } // 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 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 { … }