1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
|
#!/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
|