Documentation
¶
Overview ¶
Package workspace enumerates the Go modules of a GoCell workspace.
It is the single source from which archtest, tools/depgraph, and the `gocell graph` CLI learn "which modules exist". The module set is DERIVED from go.work's `use` directives — the Go toolchain's own truth about which modules it compiles in workspace mode — so a module extracted into a nested go.mod and added to go.work is automatically covered by the production scan. There is no hand-maintained module list to forget (zero drift surface); this is the keystone that lets archtest survive the go.work multi-module migration without silently losing coverage of an extracted module.
go.work is authoritative for the Go module set. .gocell/manifest.yaml declares the (smaller-or-equal) set of modules that carry GoCell metadata (cells/contracts/journeys); Modules cross-checks the two in BOTH directions and fails closed on drift:
- forward — manifest.modules ⊆ go.work.use: a metadata module the toolchain does not compile is a configuration bug.
- reverse — every go.work member that carries GoCell metadata must appear in the manifest: an undeclared metadata-bearing member is compiled but invisible to metadata tooling (a silent coverage hole). A pure-tool / pure-library member with no metadata may stay out of the manifest.
A workspace without a manifest has no metadata-module contract to cross-check (the Go scan still derives from go.work).
Allowed import surface: this package imports only stdlib, kernel/metadata (manifest cross-check), and tools/gomodutil; it must not import golang.org/x/tools, cells/, runtime/, or adapters/.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func WorkspaceRoot ¶
WorkspaceRoot walks up from the process working directory to the workspace root and returns its absolute path. Resolution is go.work-FIRST: the nearest go.work wins, and only when no go.work exists above cwd does it fall back to the nearest go.mod.
This is honest mode detection across the two contexts archtest serves, NOT a silent default:
- GoCell's own monorepo (and the multi-module fixtures): go.work is present, so the walk anchors to the WORKSPACE root — never to a nested module's go.mod when run from a subdirectory (the single-module bug #1555 fixes).
- An external single-module consumer repo (Operator-SDK, #1081) that has a go.mod but no go.work: there is no workspace, so the single module's root is correct. Without this branch RunStandardCellRules could not scan an external module.
go.work-first guarantees the monorepo never falls through to go.mod (its go.work sits above every nested module), so the fallback only fires where it is the right answer. A tree with neither marker returns an error.
Types ¶
type Module ¶
type Module struct {
// Dir is the use-directive disk path relative to the workspace root.
Dir string
// ImportPath is the module path from <Dir>/go.mod (e.g.
// "github.com/ghbvf/gocell" or "github.com/ghbvf/gocell/mdm").
ImportPath string
}
Module pairs a workspace member's on-disk directory (relative to the workspace root, filepath.Clean'd — "." for the root module) with the Go module import path declared in that directory's go.mod.
func Modules ¶
Modules returns the member modules of the workspace (or the single module) rooted at root, each paired with the Go module import path from its go.mod.
- When root/go.work exists: the members are its `use` directives, in `use` order; if root/.gocell/manifest.yaml also exists its modules[].path set MUST be a subset of the `use` dirs (fail-closed on drift). A workspace without a manifest has no metadata modules and skips the cross-check.
- When root/go.work does NOT exist: root is a single (external) module; the result is the one module {Dir ".", ImportPath read from root/go.mod}.