Documentation
¶
Overview ¶
Package goprogram is the one go/packages front end for the gates that type-check this repository's own source.
Four of them do it: cmd/audit_md_escaping walks the calls that interpolate a GitLab-authored value into Markdown, cmd/audit_readonly_graphql walks the calls a read-only action can reach, cmd/internal/graphqldocs folds every raw GraphQL document to the one string GitLab would receive, and cmd/audit_graphql_shapes pairs each of those documents with the struct that decodes it. They ask four different questions of the loaded program and index it four different ways, which is why only the front end lives here: the load mode, the config, and the rule that a package which did not type-check stops the run.
That last rule is why this package exists rather than being four tidy copies. Each of the four gates answers "cannot tell" for anything it cannot resolve, and a partially typed package resolves nothing: the escaping audit would classify every value as unfollowable, the read-only audit would find no handlers, and the document collector and the shape audit would fold no constants. All four would then report a clean run over source they never understood, which is the one failure mode a gate must not have. The refusal was written four times with four wordings, so a change to it was a four-file edit with one file easy to forget.
What stays with each gate is everything above the load: its own indexers, its own detectors, its own question and its own binary.
github.com/jmrplens/gitlab-mcp-server/v3/cmd/audit_1to1/internal/shared.LoadToolPackages is deliberately not folded in. It loads with NeedDeps, so it pays for the dependency tree these four refuse to pay for, and it refuses more widely than Load does: it collects every error of every loaded package, the dependencies included, and aborts on all of them at once, where Load stops at the first error of a package the caller asked for. It also returns a subset rather than what it loaded, keeping the packages under internal/tools and dropping the rest, and memoizes that result per root. That is a different contract, not a different wording of this one.
Index ¶
Constants ¶
const LoadMode = packages.NeedName | packages.NeedFiles | packages.NeedCompiledGoFiles | packages.NeedSyntax | packages.NeedTypes | packages.NeedTypesInfo | packages.NeedImports
LoadMode is what the gates need from the loader: syntax to walk, types so an identifier resolves to the object it names and a constant expression folds to the one string it denotes, and imports so an object has one identity across the packages that share it.
NeedDeps is deliberately absent, for one reason that holds for all four callers: each of them only ever reads bodies written inside the patterns it loads, so type-checking the dependency tree from source would cost minutes and change no answer. What a dependency's function returns is judged by its name and its signature, both of which come in through export data, which also gives each of its objects the same identity the packages using them see.
Variables ¶
This section is empty.
Functions ¶
func Load ¶
Load type-checks the packages named by patterns, rooted at dir, and returns them in the loader's order. Every returned package type-checked without error, so a caller may read TypesInfo without checking it first.
The overlay is how a test supplies source that is not on disk: a fixture package written in the test file itself type-checks against the real packages it imports, so a gate is exercised on the shapes it has to handle rather than on a mock of them. Production passes nil.
A pattern that matches nothing is an error rather than an empty result. A gate that audited no package would otherwise pass, which is the same silence [packageLoadError] refuses one package at a time.
Types ¶
This section is empty.