|
| 1 | +#!/usr/bin/env bash |
| 2 | +# |
| 3 | +# check-doxygen.sh — enforce TASK-043 invariant on the doxygen build. |
| 4 | +# |
| 5 | +# Runs `make doxygen-run` in the active build tree and asserts that the |
| 6 | +# output contains zero substantive warnings or errors. Substantive means: |
| 7 | +# anything from the doxygen parser about the SOURCE under |
| 8 | +# `src/httpserver/` — e.g. an undocumented @param, a mismatched parameter |
| 9 | +# name, a stale @copydoc target. |
| 10 | +# |
| 11 | +# Lines we deliberately filter OUT (environmental, not doc-content issues): |
| 12 | +# |
| 13 | +# E1. "Tag '<NAME>' at line N of file '...doxyconfig.in' has become |
| 14 | +# obsolete." — older config tags carried over from doxywizard. |
| 15 | +# E2. "doxygen no longer ships with the FreeSans font." — packaging. |
| 16 | +# E3. "the dot tool could not be found ..." — graphviz absent locally. |
| 17 | +# E4. "Failed to rename ... .dot.png to ... .png" — dot post-processing |
| 18 | +# failure (typically dot absent or installed late). |
| 19 | +# E5. "Problems running dot: exit code=..." — same root cause as E4. |
| 20 | +# E6. "Caller graph for '<sym>' not generated, too many nodes (N), |
| 21 | +# threshold is M." — informational, DOT_GRAPH_MAX_NODES threshold. |
| 22 | +# |
| 23 | +# Everything else under the keywords `warning:` or `error:` is a real |
| 24 | +# doc issue and FAILS the gate. Exits non-zero on the first violation. |
| 25 | +# |
| 26 | +# Behaviour when doxygen is not installed: SKIP (exit 0). The gate is |
| 27 | +# CI-runnable on developer machines without doxygen; CI is expected to |
| 28 | +# install it. This mirrors how scripts/check-readme.sh and friends are |
| 29 | +# tolerant of missing tools. |
| 30 | + |
| 31 | +set -euo pipefail |
| 32 | + |
| 33 | +REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)" |
| 34 | + |
| 35 | +# Locate the build tree. Prefer $BUILD_DIR, else REPO_ROOT/build, else |
| 36 | +# fall back to the current working directory (assumes invoker is already |
| 37 | +# inside the build dir, mirroring `make` behaviour). |
| 38 | +BUILD_DIR="${BUILD_DIR:-}" |
| 39 | +if [ -z "$BUILD_DIR" ]; then |
| 40 | + if [ -d "$REPO_ROOT/build" ] && [ -f "$REPO_ROOT/build/Makefile" ]; then |
| 41 | + BUILD_DIR="$REPO_ROOT/build" |
| 42 | + elif [ -f "Makefile" ]; then |
| 43 | + BUILD_DIR="$(pwd)" |
| 44 | + else |
| 45 | + echo "check-doxygen: FAIL: no build directory found (set BUILD_DIR)" >&2 |
| 46 | + exit 1 |
| 47 | + fi |
| 48 | +fi |
| 49 | + |
| 50 | +if ! command -v doxygen >/dev/null 2>&1; then |
| 51 | + echo "check-doxygen: SKIP — doxygen not installed (gate is enforced in CI)" |
| 52 | + exit 0 |
| 53 | +fi |
| 54 | + |
| 55 | +LOGFILE="$(mktemp -t check-doxygen.XXXXXX)" |
| 56 | +trap 'rm -f "$LOGFILE"' EXIT |
| 57 | + |
| 58 | +echo "check-doxygen: invoking 'make doxygen-run' in $BUILD_DIR" |
| 59 | +# Force a fresh doxygen invocation. The make rule's recipe already does |
| 60 | +# `rm -rf doxygen-doc` but only fires when an input is newer than the |
| 61 | +# tag file. When NO header has changed (e.g. CI rerun) doxygen does not |
| 62 | +# re-execute and warnings from a prior good run would not reappear here. |
| 63 | +# Removing the tag file forces the rule to fire every time. |
| 64 | +rm -f "$BUILD_DIR/doxygen-doc/libhttpserver.tag" |
| 65 | +if ! ( cd "$BUILD_DIR" && make doxygen-run ) >"$LOGFILE" 2>&1; then |
| 66 | + echo "check-doxygen: FAIL: 'make doxygen-run' exited non-zero" >&2 |
| 67 | + sed -n '1,200p' "$LOGFILE" >&2 |
| 68 | + exit 1 |
| 69 | +fi |
| 70 | + |
| 71 | +# Strip the noisy-but-harmless environmental lines. The grep is portable |
| 72 | +# (BSD/GNU): -E for ERE alternation, single anchored pattern per line. |
| 73 | +FILTER='Tag .* has become obsolete\.' |
| 74 | +FILTER+='|doxygen no longer ships with the FreeSans font' |
| 75 | +FILTER+='|the dot tool could not be found' |
| 76 | +FILTER+='|Failed to rename .*\.dot\.png to' |
| 77 | +FILTER+='|Problems running dot: exit code=' |
| 78 | +FILTER+='|Caller graph for .* not generated, too many nodes' |
| 79 | + |
| 80 | +REAL_WARNINGS="$(grep -E '(^|: )(warning|error):' "$LOGFILE" | grep -Ev "$FILTER" || true)" |
| 81 | + |
| 82 | +if [ -n "$REAL_WARNINGS" ]; then |
| 83 | + echo "check-doxygen: FAIL: substantive doxygen warnings/errors found:" >&2 |
| 84 | + echo "$REAL_WARNINGS" >&2 |
| 85 | + echo "" >&2 |
| 86 | + echo "(Full log: $LOGFILE — copy aside if needed before this script exits.)" >&2 |
| 87 | + # Preserve log on failure for inspection. |
| 88 | + trap - EXIT |
| 89 | + exit 1 |
| 90 | +fi |
| 91 | + |
| 92 | +echo "check-doxygen: PASS — doxygen-run produced zero substantive warnings" |
0 commit comments