Skip to content

Commit c18cc8f

Browse files
committed
Merge TASK-043: Doxygen / inline doc refresh (PRD §2 documentation NFR, §13 documentation deliverable)
2 parents 1da2ee1 + 00096cb commit c18cc8f

12 files changed

Lines changed: 697 additions & 44 deletions

File tree

Makefile.am

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ endif
4040

4141
EXTRA_DIST = libhttpserver.pc.in $(DX_CONFIG) scripts/extract-release-notes.sh scripts/validate-version.sh \
4242
scripts/check-examples.sh scripts/check-readme.sh scripts/check-release-notes.sh \
43+
scripts/check-doxygen.sh \
4344
scripts/verify-installed-examples.sh \
4445
test/headers/consumer_direct.cpp test/headers/consumer_detail.cpp test/headers/consumer_umbrella.cpp \
4546
test/headers/consumer_post_umbrella.cpp \
@@ -283,7 +284,7 @@ check-hygiene:
283284
# shared staged install to avoid paying two full `make install` costs on
284285
# every `make check`. Both sub-checks can still be invoked standalone (they
285286
# will do their own install when CHECK_*_SHARED is not set).
286-
check-local: check-headers check-examples check-readme check-release-notes
287+
check-local: check-headers check-examples check-readme check-release-notes check-doxygen
287288
@echo "=== Shared staged install for check-install-layout and check-hygiene ==="
288289
@rm -rf $(abs_top_builddir)/.shared-check-stage
289290
@$(MAKE) $(AM_MAKEFLAGS) install DESTDIR=$(abs_top_builddir)/.shared-check-stage >check-shared-install.log 2>&1 || { \
@@ -319,7 +320,15 @@ check-release-notes:
319320
@echo "=== check-release-notes: enforce TASK-042 invariants on RELEASE_NOTES.md ==="
320321
@$(top_srcdir)/scripts/check-release-notes.sh
321322

322-
.PHONY: check-headers check-install-layout check-hygiene check-examples check-readme check-release-notes
323+
# TASK-043: run doxygen and fail on any substantive warning. The script
324+
# delegates to `make doxygen-run` and parses stderr; environmental noise
325+
# (obsolete config tags, missing graphviz) is filtered out. Skips with
326+
# exit 0 if doxygen is not installed.
327+
check-doxygen:
328+
@echo "=== check-doxygen: enforce TASK-043 zero-warning invariant ==="
329+
@BUILD_DIR="$(abs_top_builddir)" $(top_srcdir)/scripts/check-doxygen.sh
330+
331+
.PHONY: check-headers check-install-layout check-hygiene check-examples check-readme check-release-notes check-doxygen
323332

324333
# TASK-039: top-level convenience rule that descends into test/ to
325334
# build and run the bench binaries (see test/Makefile.am and

scripts/check-doxygen.sh

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
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"

specs/tasks/M6-release/TASK-043.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,12 @@
88
Update inline documentation on every renamed and reshaped public method so generated docs match the v2.0 surface.
99

1010
**Action Items:**
11-
- [ ] Audit every public `*.hpp`: each public method has a `///` comment block describing parameters, return value, exception spec, and (where relevant) lifetime / threading notes.
12-
- [ ] Cross-link related methods: e.g., `block_ip` references `unblock_ip`; `register_path` references `register_prefix`.
13-
- [ ] Document the threading contract on `webserver` class-level comment (per DR-008 distilled).
14-
- [ ] Document error propagation on `internal_error_handler` setter and on the `webserver::run`/dispatch boundary (per DR-009).
15-
- [ ] Document each `feature_unavailable` throw site (which method, which flag).
16-
- [ ] Run `doxygen` and verify no warnings about missing or stale references.
11+
- [x] Audit every public `*.hpp`: each public method has a `///` comment block describing parameters, return value, exception spec, and (where relevant) lifetime / threading notes.
12+
- [x] Cross-link related methods: e.g., `block_ip` references `unblock_ip`; `register_path` references `register_prefix`.
13+
- [x] Document the threading contract on `webserver` class-level comment (per DR-008 distilled).
14+
- [x] Document error propagation on `internal_error_handler` setter and on the `webserver::run`/dispatch boundary (per DR-009).
15+
- [x] Document each `feature_unavailable` throw site (which method, which flag).
16+
- [x] Run `doxygen` and verify no warnings about missing or stale references.
1717

1818
**Dependencies:**
1919
- Blocked by: TASK-031, TASK-034, TASK-041
@@ -27,4 +27,4 @@ Update inline documentation on every renamed and reshaped public method so gener
2727
**Related Requirements:** PRD §2 documentation NFR
2828
**Related Decisions:** §13 documentation deliverable
2929

30-
**Status:** Not Started
30+
**Status:** Done

specs/tasks/_index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ Nominally: **13 sequential tasks**, each S–XL. Most other tasks parallelize of
125125
| TASK-040 | Rewrite `examples/` | M6 | Done | TASK-025, TASK-036 |
126126
| TASK-041 | Rewrite `README.md` | M6 | Done | TASK-031, TASK-032, TASK-040 |
127127
| TASK-042 | Write `RELEASE_NOTES.md` for v2.0 | M6 | Done | TASK-041 |
128-
| TASK-043 | Doxygen / inline doc refresh | M6 | Not Started | TASK-031, TASK-034, TASK-041 |
128+
| TASK-043 | Doxygen / inline doc refresh | M6 | Done | TASK-031, TASK-034, TASK-041 |
129129
| TASK-044 | SOVERSION bump and packaging | M6 | Not Started | TASK-042, TASK-043 |
130130

131131
## PRD requirement coverage

0 commit comments

Comments
 (0)