-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathcheck_doc_coverage.sh
More file actions
executable file
·110 lines (103 loc) · 6.2 KB
/
Copy pathcheck_doc_coverage.sh
File metadata and controls
executable file
·110 lines (103 loc) · 6.2 KB
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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#!/usr/bin/env bash
# check_doc_coverage.sh — every public var without a docstring is a RECORDED
# decision, never an accident.
#
# bash scripts/check_doc_coverage.sh # gate: assert the set matches
# bash scripts/check_doc_coverage.sh --write # regenerate data/doc_coverage.txt
#
# `data/doc_coverage.txt` lists the exact set of public vars in the bundled
# namespaces that carry no `:doc`. This asserts the runtime's set equals it, so
# a var LOSING its docstring and a new var ARRIVING without one both fail here.
#
# History: `clojure.core`'s docstrings come from `core_meta.clj`, generated by
# `scripts/extract_core_meta.sh` from the JVM oracle. It was generated once and
# gated by nothing, so it rotted — on 2026-08-04 it held 291 rows where the same
# pipeline produced 628, and covered ZERO of the ~290 Zig-primitive core vars.
# `reduce`, `assoc`, `conj`, `first`, `apply` and `=` had no documentation, and
# `find-doc` — an advertised feature — was therefore searching under half of
# core and returning confidently wrong "no match" answers. Nothing surfaced it
# for a month because nothing executed the claim.
#
# Why this shape rather than a drift check against the oracle: the oracle needs
# a JVM and CI has none (the same constraint `data/core_surface_upstream.txt`
# records). This gate runs cljw alone. It cannot notice that upstream documents
# something cljw does not import — but the file it asserts against makes that
# set *visible and reviewable*, which is what the accident depended on being
# absent. Same shape as `data/core_surface_extras.txt` (AD-057): a new name
# appearing here is a decision, not a formality.
set -euo pipefail
cd "$(dirname "$0")/.."
BIN="zig-out/bin/cljw"
LEDGER="data/doc_coverage.txt"
[ -x "$BIN" ] || { echo "check_doc_coverage: building cljw…" >&2; zig build -Dwasm -Doptimize="${CLJW_OPT:-ReleaseSafe}" >/dev/null; }
# Every bundled namespace whose publics a user can reach. Kept here rather than
# derived from `FILES` so that adding a namespace is a conscious decision about
# whether its docs are gated.
read -r -d '' PROBE <<'CLJ' || true
(def nses '[clojure.core clojure.string clojure.set clojure.walk clojure.zip clojure.edn
clojure.data clojure.math clojure.pprint clojure.test clojure.template
clojure.stacktrace clojure.instant clojure.uuid clojure.java.io clojure.repl
clojure.datafy clojure.core.protocols clojure.core.reducers clojure.data.json
clojure.data.csv clojure.tools.cli])
(doseq [n nses]
(try (require n) (catch Throwable _ nil))
(doseq [s (sort (map key (filter (fn [[_ v]] (not (:doc (meta v)))) (ns-publics n))))]
(println (str n "/" s))))
CLJ
# Portable bounded run: GNU `timeout`, else coreutils `gtimeout`, else
# unbounded. The hosted macOS runners ship NEITHER — a bare `timeout` here made
# this step exit 127 on every macOS CI run while passing locally, which is the
# same trap `test/e2e/phase16_wasm_run.sh` documents. The bound is a backstop:
# the probe reads metadata from an already-built binary and finishes in ~1 s.
run_bounded() {
local secs="$1"; shift
if command -v timeout >/dev/null 2>&1; then timeout "$secs" "$@"
elif command -v gtimeout >/dev/null 2>&1; then gtimeout "$secs" "$@"
else "$@"; fi
}
actual="$(printf '%s\n' "$PROBE" | run_bounded 120 "$BIN" - | LC_ALL=C sort)"
[ -n "$actual" ] || { echo "check_doc_coverage: the probe produced nothing — did it fail to load?" >&2; exit 1; }
if [[ "${1:-}" == "--write" ]]; then
{
echo "# GENERATED by scripts/check_doc_coverage.sh --write — the exact set of"
echo "# public vars in the bundled namespaces that carry NO docstring."
echo "#"
echo "# This is a LEDGER OF DECISIONS, not a target. A name here means: this var"
echo "# is reachable by a user, \`(doc …)\` on it prints nothing, and that is"
echo "# currently accepted. Removing a name (by writing the docstring) is the"
echo "# improvement; a name APPEARING here without intent is the bug the gate"
echo "# catches."
echo "#"
echo "# Known clusters, so the list is read rather than skimmed:"
echo "# clojure.pprint — the ~50 cljw-internal \`cl-*\` formatter helpers were"
echo "# made private 2026-08-04 (upstream keeps them private too), which is"
echo "# why this cluster is now small: they were a leaked API surface, not a"
echo "# documentation gap, and \`defn-\` was the fix rather than prose."
echo "# clojure.math — DONE 2026-08-04 with AUTHORED prose, not imported:"
echo "# upstream's docstrings all end in a java.lang.Math Javadoc URL, which"
echo "# would be a Java-8 link as the reference for a runtime that has no"
echo "# java.lang.Math. Every behavioural claim in the authored text is a"
echo "# golden pair in test/diff/clj_corpus/math_doc_claims.txt."
echo "# clojure.core — the residue after core_meta.clj; mostly \`-\`-prefixed"
echo "# protocol methods and earmuffed dynamics upstream does not document"
echo "# either."
echo "#"
echo "# Regenerate with: bash scripts/check_doc_coverage.sh --write"
echo
printf '%s\n' "$actual"
} > "$LEDGER"
echo "check_doc_coverage: wrote $LEDGER ($(printf '%s\n' "$actual" | wc -l | tr -d ' ') undocumented vars)"
exit 0
fi
[ -f "$LEDGER" ] || { echo "check_doc_coverage: $LEDGER missing — run with --write" >&2; exit 1; }
expected="$(grep -v '^#' "$LEDGER" | grep -v '^$' | LC_ALL=C sort)"
if [[ "$actual" != "$expected" ]]; then
echo "check_doc_coverage: the undocumented-var set does not match $LEDGER." >&2
echo " NEWLY undocumented (a var lost its docstring, or arrived without one):" >&2
comm -23 <(printf '%s\n' "$actual") <(printf '%s\n' "$expected") | sed 's/^/ /' >&2
echo " NEWLY documented (good — refresh the ledger):" >&2
comm -13 <(printf '%s\n' "$actual") <(printf '%s\n' "$expected") | sed 's/^/ /' >&2
echo " Fix the docstring, or accept the change with: bash scripts/check_doc_coverage.sh --write" >&2
exit 1
fi
echo " doc_coverage: $(printf '%s\n' "$expected" | wc -l | tr -d ' ') recorded undocumented var(s); no drift"