#!/bin/sh # SPDX-License-Identifier: GPL-3.0-or-later # # man-lint: check the mdoc man pages for real errors, not just "did it run". # # Prefers `mandoc -Tlint -Wwarning`. -W sets the lowest message level that # mandoc reports and counts in its exit status, so this fails (exit 2 or # higher) on any WARNING, ERROR or UNSUPP message. STYLE and BASE messages # (for example "referenced manual not found" for pages not yet installed) # are below that level: not shown, and never a failure. -Werror would not # do: it hides warnings and exits 0 on them. # # Falls back to `groff -ww -z -mdoc` when mandoc is not installed. Two traps # with that fallback, both deliberate here: # - the pages are written in the mdoc macro package, not man(7), so this # must ask groff for -mdoc specifically; the wrong package produces # noise (or silently accepts things mdoc would reject); # - groff exits 0 whether or not it complained - -z asks it to run only # the diagnostics pass (no formatted output), so anything at all on its # stderr, not its exit code, is what "failed" means here. # # Skips with a printed notice, exit 0, when neither tool is installed: a # machine with no man toolchain must not fail this gate, the same way # internal/ignore's git-oracle test skips itself when git is absent. # # Usage: scripts/man-lint [FILE...] (default: man/*.[15]) set -eu cd "$(git rev-parse --show-toplevel)" if [ "$#" -gt 0 ]; then # shellcheck disable=SC2124 # deliberately captured as one word list below files="$*" else files='man/*.[15]' fi # shellcheck disable=SC2086 # $files is a glob pattern or an arg list, meant to split/expand set -- $files if [ "$#" -eq 0 ] || [ ! -e "$1" ]; then echo "man-lint: no man pages found ($files)" >&2 exit 1 fi if command -v mandoc >/dev/null 2>&1; then echo "man-lint: mandoc -Tlint -Wwarning $*" exec mandoc -Tlint -Wwarning "$@" fi if command -v groff >/dev/null 2>&1; then fail=0 for f in "$@"; do echo "man-lint: groff -ww -z -mdoc $f" out=$(groff -ww -z -mdoc "$f" 2>&1 >/dev/null) || true if [ -n "$out" ]; then printf 'man-lint: %s:\n%s\n' "$f" "$out" | sed '2,$s/^/ /' >&2 fail=1 fi done if [ "$fail" -ne 0 ]; then echo "man-lint: groff reported the warnings above; it exits 0 regardless, so stderr output alone is the failure signal here" >&2 exit 1 fi exit 0 fi echo "man-lint: neither mandoc nor groff is installed; skipping man page lint" >&2 exit 0