Help us shape the future of Go! Take the 2026 Go Developer Survey

doccheck

command
v0.53.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 20, 2026 License: Apache-2.0 Imports: 12 Imported by: 0

Documentation

Overview

Command doccheck verifies that every documentation reference in the repository resolves to a file that exists.

It checks three surfaces that nothing off-the-shelf covers together:

  1. Relative links in Markdown — `[text](../spec/foo.md)`, including links that point at source files. External URLs and pure `#anchor` links are skipped.

  2. Repo-relative Markdown paths cited inside **Go comments** — the `docs/spec/manifest-system.md`-style references the packages use to point at their contract, and the ones that live next to the code they describe, like `internal/git/manifestedit/DECISION.md`. These are the ones that rot silently: a doc gets moved, the comment keeps pointing at the old path, and nothing notices. Seventeen of them were dangling before this check existed.

  3. The same repo-relative paths cited in **YAML and shell** — Taskfiles, CI workflows, chart values, hack scripts. This surface was added after a docs reorg left eight of them dangling: the Markdown and Go citations had all been repointed, and nothing was looking at the Taskfiles.

A citation must contain a slash. A bare `README.md` in prose names no particular file — relative to which directory? — so it is not treated as a reference.

The Go side parses the AST and reads only comments, never string literals. That distinction matters: the gittargetignore tests build in-memory filesystems whose entries are named like documentation paths. Those are fixtures, not citations. A regex cannot tell the two apart; the parser can.

YAML and shell have no comparable parser worth carrying, so they are scanned as plain text. The one distinction that must be made there is a docs path in a URL (`https://github.com/…/docs/spec/foo.md`), which names a rendered page rather than a repo-relative file; those are skipped.

Only git-tracked files are scanned, so gitignored scratch notes and the local upstream checkouts under external-sources/ are out of scope for free.

A reference must resolve to a git-tracked file or directory, not merely to something on disk. Resolving against the filesystem would make this check pass on the author's machine and fail in CI: a link into a gitignored path — `.agents/`, a local scratch file, an untracked upstream checkout — exists locally and does not exist in a fresh clone. That is precisely the reference this check must catch, so existence is decided by `git ls-files`, never by os.Stat.

Usage:

doccheck [-root DIR]

Exits non-zero and prints file:line for every unresolved reference.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL