Documentation
¶
Overview ¶
Package doclint resolves the doc links in this module's comments and reports the ones that name nothing.
Why ¶
A removed symbol leaves its doc links behind. Go's own tooling does not complain: godoc renders a link to a symbol that no longer exists as an ordinary link, and golangci-lint's documentation linters check style, not reference resolution. Two releases in a row shipped documentation advertising API that had been cut, and neither was found by a gate — the first by a cleanup pass that happened to open the file, the second by a consumer trying to upgrade.
What a link is ¶
Only a bracketed name whose final component is a capitalized Go identifier is a link: Name, Type.Method, Type.Field, pkg.Name, pkg.Type.Method, each in brackets. That is go/doc/comment's own rule, deliberately inherited here: a bracketed lowercase name such as someHelper renders as literal text in published documentation, so it is not a link and this package does not resolve it. A reference of that shape naming a deleted symbol is real rot, but it is rot of a different class and needs a different instrument.
Resolution ¶
The resolution unit is the directory, not the package: every .go file in a directory contributes names, test files included. That is what lets a production doc comment anchor a regression test by name — the convention the repo's comment rules sanction — while still catching an anchor that names a test somebody deleted.
A qualified link resolves its package part against the referencing file's own imports first. This module has an adapter/json package, so a bare package-name match for a json-qualified link would collide with encoding/json. When the file does not import the name, a unique in-module package with that name is the fallback, which is how a comment can reference a package that would be an import cycle to depend on. Links resolving outside the module are skipped: the standard library and this module's dependencies are not this gate's business.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func AssertNoDanglingLinks ¶
AssertNoDanglingLinks reports every doc link under root that names nothing, and returns how many links it resolved.
The count is returned rather than asserted internally so the caller keeps its own floor visible: a walk that reaches no source resolves no links and would otherwise pass.
Types ¶
type Link ¶
type Link struct {
// Pos is "file:line" of the comment group holding the link.
Pos string
// Text is the link as it appears between the brackets.
Text string
// ImportPath is the target package, empty for the referencing package.
ImportPath string
// Recv is the receiver or owning type, empty for a package-level name.
Recv string
// Name is the symbol name.
Name string
}
Link is one doc link, with where it was written and what it names.
type Module ¶
Module is a parsed module: every package under the walk root, indexed for resolution by import path and by package name.
func Load ¶
Load parses every Go file under root, skipping directories that hold no source a consumer reads: testdata, node_modules, and anything whose name starts with "." or "_". Files that do not parse are an error rather than a skip — a gate that quietly drops the file it cannot read reports a clean run over nothing.
func (*Module) Dangling ¶
Dangling returns every link in m that names nothing, in walk order.
A link whose target package is outside the module is not resolved and not reported: the standard library and this module's dependencies keep their own promises. Checked reports how many links were resolved, so a caller can tell "nothing dangles" from "nothing was read".
type Package ¶
type Package struct {
// Dir is the slash-separated path from the walk root, "." for the root.
Dir string
// ImportPath is the module path joined with Dir.
ImportPath string
// Name is the package clause of the directory's non-test files, falling
// back to a test file's when a directory holds only tests.
Name string
// contains filtered or unexported fields
}
Package is one directory's Go files and every name they declare.
The directory rather than the package is the unit, so a name declared in an external test package (package foo_test beside package foo) resolves for a link written in either.
type TB ¶
TB is the slice of testing.TB this gate uses, which *testing.T satisfies.
It is an interface of this package's own rather than testing.TB itself because testing.TB is deliberately unimplementable outside the standard library, and a gate whose failure path is unreachable from a test is a gate that can silently stop failing.