On this page
Enumerating the selfdoc projects that live beside this one, reporting every sibling rather than failing on one whose configuration cannot be loaded.
#internal/fleet
#internal/fleet
Package fleet enumerates the selfdoc projects that live beside this one.
Two tools need the same answer to "which sibling directories are selfdoc projects, and can their configs be loaded?": the corpus-wide spelling run and the one-off lint-impact measurement. The enumeration is here, in one package, so both callers share one hardened implementation.
Hardened means every sibling is REPORTED, never fatal. A directory whose selfdoc.json is missing, unreadable or rejected by the config schema comes back as a [FleetProject] carrying the reason, and the caller decides what to say about it. A broken neighbour must not be able to stop a corpus run over the rest of the fleet.
Everything here is read-only with respect to the projects it enumerates. The one write is a sanitized COPY of a config, placed in a caller-supplied scratch directory, never in the project.
#RetiredVersionKeys
var RetiredVersionKeys = []string{"indexed"}RetiredVersionKeys are the keys the config schema has retired but fleet configs still carry. A project whose only load failure is one of these is loaded from a sanitized copy, and the result says so, because a retired key is stale scaffolding rather than a broken project.
#FleetProject
type FleetProject structFleetProject is one sibling directory carrying a selfdoc.json.
Config is nil exactly when Error is set: the project was found but could not be loaded, and why is the Error string.
#DocBody
type DocBody structDocBody is one docs-tree page in the shape the lint rules consume: its parsed frontmatter, the resolved-directive text (deliberately empty here), the raw body, and how many source lines the frontmatter occupied.
#ProjectDirs
func ProjectDirs(root string) []stringProjectDirs returns every immediate subdirectory of root holding a selfdoc.json, sorted by name.
Dot-directories are skipped, so archives and caches under ".archive/" are not walked. A root that does not exist yields nothing rather than failing: "no siblings" is a real answer.
#LoadProjectConfig
func LoadProjectConfig(projectDir, scratchDir string) (config.Config, bool, error)LoadProjectConfig loads projectDir's config, retrying once without the retired schema keys.
scratchDir is where a sanitized copy may be written; it is never the project itself. The returned boolean is true when the config only loaded after retired keys were dropped from that copy.
An invalid config whose failure retired keys do not explain comes back as the original diagnosis. Callers that enumerate the fleet should use [DiscoverFleet], which reports such a failure instead of returning it.
The copy is written directly rather than through the effects handle, and the reason is the one the Python recorded when it marked the same two writes exempt: the file exists only to be read back by the loader on the next line, it lands in the caller's scratch directory rather than in any project, and nothing outside this function ever sees it. Recording it as an effect would make a preview answer "unloadable" for a project that loads, which is a different answer from the one a real run gives.
#DiscoverFleet
func DiscoverFleet(root string) ([]FleetProject, error)DiscoverFleet enumerates and loads every selfdoc project directly under root.
It never reports a broken project as a failure: a config that cannot be read comes back with a nil Config and an Error naming the reason. The scratch directory used for sanitized config copies is created and removed here, so nothing survives the call. The only returned error is a scratch directory that could not be created, which would make every sanitized retry impossible.
#LoadDocsBodies
func LoadDocsBodies(docsDir string) (map[string]DocBody, error)LoadDocsBodies reads a docs tree into the shape the lint rules consume, keyed by each page's path relative to docsDir.
Frontmatter is parsed; directives are NOT resolved, because resolution runs a project's extractors over its source and a corpus pass must stay read-only and cheap over projects it does not own. The resolved slot is therefore the empty string.
The result is empty when docsDir is not a directory. Underscore-prefixed templates are not pages, and neither is anything under a _build directory.
#FleetProject.Loaded
func (p FleetProject) Loaded() bool { return p.Config != nil }Loaded reports whether the config was read successfully.