Documentation
¶
Overview ¶
Package packagesload is the single sanctioned entry point for golang.org/x/tools/go/packages.Load across GoCell tooling. It forces every caller to declare the workspace Mode explicitly, so no loader silently inherits the ambient GOWORK from the committed repo-root go.work.
WHY: PR #1554 commits a go.work (`use .`), putting `go` into workspace mode repo-wide. Most loaders analyze either the root module or an isolated standalone module (the archtest / depgraph fixtures under testdata/*, or a release-pinned per-module build) and MUST use ModeModule (GOWORK=off) — workspace mode otherwise rejects any directory whose module is not in the `use` set ("directory ... does not contain modules listed in go.work"). A future cross-module archtest loader that genuinely wants to see every member module's AST through go.work (Plan D §"Cross-Module archtest") uses ModeWorkspace. Encoding the choice as a mandatory typed parameter — rather than an ad-hoc GOWORK=off ban on every packages.Config — keeps both intents expressible and prevents silent ambient inheritance.
Enforced by archtest PACKAGES-LOAD-FUNNEL-01: packages.Load may be called directly ONLY from this package.
Index ¶
- func Load(mode Mode, cfg *packages.Config, patterns ...string) ([]*packages.Package, error)
- func LoadFlatCached(root string, cfg packages.Config, patterns ...string) ([]*packages.Package, []packages.Error, error)
- func LoadWorkspace(root string, cfgTemplate packages.Config, patterns ...string) ([]*packages.Package, []packages.Error, error)
- func LoadWorkspaceCached(root string, cfg packages.Config, patterns ...string) ([]*packages.Package, []packages.Error, error)
- type Mode
- type WorkspaceCache
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Load ¶
Load runs packages.Load with the GOWORK semantics dictated by mode. The caller supplies cfg (Mode/Dir/Tests/BuildFlags/Context); Load owns cfg.Env, deriving GOWORK from mode (any caller-set cfg.Env is preserved, with GOWORK=off appended last for ModeModule so it wins). This is the only place in the repo permitted to call packages.Load directly (archtest PACKAGES-LOAD-FUNNEL-01).
func LoadFlatCached ¶
func LoadFlatCached(root string, cfg packages.Config, patterns ...string) ([]*packages.Package, []packages.Error, error)
LoadFlatCached is WorkspaceCache.LoadFlat on the process-wide cache.
func LoadWorkspace ¶
func LoadWorkspace(root string, cfgTemplate packages.Config, patterns ...string) ([]*packages.Package, []packages.Error, error)
LoadWorkspace is the single sanctioned satellite-aware loader: it loads patterns against the go.work workspace at root, EXPANDING multi-member satellite parent-prefixes ("./cmd/...", "./adapters/...", "./examples/...") into their owning members so they are actually scanned, never silently skipped.
Routing (faithful to the pre-#2147 typeseval loader it consolidates):
- a span across multiple members, OR a single group that IS the workspace root (parent-of-member / root-level patterns), loads FROM the root in ModeWorkspace using the rewritten rootPatterns (post-#1565 the root has no module to anchor a relative "./parent/..." pattern, so it is rewritten to import-path form);
- a single member's patterns load per-member in ModeModule (GOWORK=off, via the member's own go.mod);
- a tree with no go.work loads as a single ModeModule module at root.
cfgTemplate supplies Mode (the go/packages Need* bits), Tests, BuildFlags, and Context; Dir/Env are owned per group (Env via Load's mode handling). Do NOT set packages.NeedDeps in cfgTemplate.Mode: it keeps full Syntax+TypesInfo resident for every transitive dependency (~1GB RSS, the #1499 regression); the scan callers deliberately omit it.
The returned []packages.Error is the flat, dir-prefixed set collected from every loaded package. Callers MUST treat any non-empty []packages.Error as a scan failure and fail closed — the returned packages may be incomplete; do not scan them and report "clean".
This is the ONLY satellite-aware package loader in the repo; both the OBS-01 metric-PII scan (tools/metricschema) and the archtest typed façade (tools/archtest) route through it. Carrier strength (per ai-robust.md, upstream vs downstream): a satellite loader OUTSIDE packagesload cannot be expressed — the expansion atom expandParentPrefix is package-private (unreachable) AND any reimplementation must reach packages.Load, itself funneled here by PACKAGES-LOAD-FUNNEL-01 (Hard upstream). WITHIN packagesload a parallel loader is only convention-guarded (Medium); this is the sanctioned single home, and tightening it to a private sub-package is a tracked Hard-ization follow-up.
Types ¶
type Mode ¶
type Mode int
Mode selects the module-resolution semantics for a load.
const ( // ModeModule forces module mode by appending GOWORK=off to the environment: // the load resolves against the target directory's own go.mod, ignoring any // repo-root go.work. Required for loading standalone modules not listed in // the workspace `use` set (archtest / depgraph testdata fixtures) and for // release-pinned per-module builds. ModeModule Mode = iota // ModeWorkspace uses the target workspace: the load resolves across all // `use` member modules. For loaders that genuinely need a cross-module view. // If the process has GOWORK=off but cfg.Dir points at a directory containing // go.work, [applyMode] pins that exact go.work path; otherwise GOWORK=off is // rejected fail-closed so the scan cannot silently degrade to one module. ModeWorkspace )
type WorkspaceCache ¶
type WorkspaceCache struct {
// contains filtered or unexported fields
}
WorkspaceCache memoizes LoadWorkspace / [LoadFlat] results across calls within a process: repeated identical loads run packages.Load once and reuse the loaded packages, collapsing concurrent identical loads via singleflight.
Single source (#2165): this is the sanctioned single package-load cache in GoCell tooling. Both the OBS-01 metric scan (tools/metricschema) and the archtest typed façade (tools/archtest/internal/typeseval) route their cached loads here, rather than each re-implementing a parallel singleflight+map cache. The loading itself is Hard-funneled by PACKAGES-LOAD-FUNNEL-01 (packages.Load reachable only from this package), so a re-introduced parallel cache could not bypass the loader (Hard) — it could only fail to reuse this cache (a perf regression, not a correctness gap). The "single cache" boundary is documented, not separately enforced.
Unbounded by design: entries are held for the process lifetime. The consumers are short-lived batch processes (`gocell generate`, the archtest gate) that load a bounded set of (mode, cfg, patterns) once and exit — exactly the in-process warmup pattern this cache exists for. A bounded LRU has no good operating point here: a small cap evicts the large production scans and triggers re-loads (the regression this fixes), a safe-large cap never evicts.
func NewWorkspaceCache ¶
func NewWorkspaceCache() *WorkspaceCache
NewWorkspaceCache returns an empty cache. Tests construct isolated instances; production routes through the process-wide LoadWorkspaceCached / LoadFlatCached.
func (*WorkspaceCache) LoadFlat ¶
func (c *WorkspaceCache) LoadFlat( root string, cfg packages.Config, patterns ...string, ) ([]*packages.Package, []packages.Error, error)
LoadFlat is the cached form of a flat ModeWorkspace Load from root (no satellite parent-prefix expansion) — the cross-module workspace production scan typeseval's LoadProductionPackages performs.
Keyed distinctly from WorkspaceCache.LoadWorkspace (kind "F" vs "W"): the two load different package sets, so a warm-up via LoadFlat does NOT pre-heat LoadWorkspace callers (SharedResolver) and vice versa — each holds its own entry.
func (*WorkspaceCache) LoadWorkspace ¶
func (c *WorkspaceCache) LoadWorkspace( root string, cfg packages.Config, patterns ...string, ) ([]*packages.Package, []packages.Error, error)
LoadWorkspace is the cached form of the package-level LoadWorkspace (the satellite-aware loader). Used by metricschema's OBS-01 scan and typeseval's SharedResolver.