feat(scripts): docs-check.sh gate against untested doc examples
- new scripts/docs-check.sh, the pre-publish docs gate: rustdoc build with -D warnings (broken intra-doc links and doc lints fail locally, docs.rs does not fail on warnings, so this is stricter than production), doctests in both feature configurations with a hard zero-ignored-assertion (ignored = uncompiled = untested, convention 16), and a badge scan over the rendered HTML for the stable 'example-wrap ignore' markup class (tooltip wording varies across rustdoc versions, the class does not) - verified both directions: green on the current tree; a temporary scratch ignore block fails the gate at the doctests step - Cargo.toml exclude gains scripts/ so the helper never ships in the package; AGENTS.md verification commands and convention 16 reference the gate
This commit is contained in:
1 parent
faa1c9ba10
commit
f215748f7b
3 files changed
+59
-2
No files matched your search
@@ -255,7 +255,9 @@ implementation agents.
|
||||
compiles (as an empty body) under default features and
|
||||
compile-checks under `--all-features`. Verify with `cargo test`
|
||||
(the doctest run) in both feature configurations; the crate-root
|
||||
assembly example in `src/lib.rs` is the reference pattern.
|
||||
assembly example in `src/lib.rs` is the reference pattern. The
|
||||
`scripts/docs-check.sh` docs gate automates the whole rule (see
|
||||
below) and also fails on any `ignore` block it finds.
|
||||
|
||||
## Verification Commands
|
||||
|
||||
@@ -271,6 +273,7 @@ cargo test --manifest-path fuzz/shared/Cargo.toml # fuzz corpus replay: the s
|
||||
cargo check --target wasm32-unknown-unknown # the default crate stays wasm-clean
|
||||
cargo clippy --target wasm32-unknown-unknown -- -D warnings
|
||||
cargo publish --dry-run --allow-dirty # before a release
|
||||
./scripts/docs-check.sh # docs gate: rustdoc -D warnings, zero ignored doctests, no untested badges
|
||||
```
|
||||
|
||||
The wasm check is the structural guard for the "default crate is
|
||||
|
||||
+1
-1
@@ -9,7 +9,7 @@ repository = "https://git.alk.dev/alkdev/alktty"
|
||||
readme = "README.md"
|
||||
keywords = ["tty", "terminal", "pty", "channels", "alkcall"]
|
||||
categories = ["network-programming", "asynchronous"]
|
||||
exclude = [".opencode/", "AGENTS.md", "docs/reviews/", "docs/plans/", "docs/sdd_process.md", "fuzz/"]
|
||||
exclude = [".opencode/", "AGENTS.md", "scripts/", "docs/reviews/", "docs/plans/", "docs/sdd_process.md", "fuzz/"]
|
||||
|
||||
[workspace]
|
||||
members = ["."]
|
||||
|
||||
Executable
+54
@@ -0,0 +1,54 @@
|
||||
#!/usr/bin/env bash
|
||||
# Docs sanity gate: run before a publish (AGENTS.md convention 16).
|
||||
# Catches what `cargo doc` alone does not: ignore-marked doc examples,
|
||||
# which rustdoc renders with the untested badge that docs.rs surfaces on
|
||||
# the crate page (the tooltip "This example is not tested"; the wording
|
||||
# varies by rustdoc version, so we grep the stable `example-wrap ignore`
|
||||
# markup class instead).
|
||||
#
|
||||
# 1. rustdoc build with warnings as errors: broken intra-doc links,
|
||||
# broken anchors, and doc lints fail here instead of surfacing on
|
||||
# docs.rs (docs.rs does not fail on warnings, so the local gate is
|
||||
# stricter than production).
|
||||
# 2. doctests in both feature configurations, with the rule that zero
|
||||
# doctests are ignored (ignored = uncompiled = untested). The lib
|
||||
# doctest count is expected: 1 compiled (the assembly example), 0
|
||||
# ignored. Feature-gated example bodies compile as empty under
|
||||
# default features and fully under --all-features.
|
||||
# 3. badge scan over the rendered HTML: no `example-wrap ignore` markup
|
||||
# and no "example is ... tested" tooltip text anywhere in target/doc.
|
||||
set -euo pipefail
|
||||
root="$(git rev-parse --show-toplevel)"
|
||||
cd "$root"
|
||||
|
||||
echo "== rustdoc build, warnings as errors (default features)"
|
||||
RUSTDOCFLAGS="-D warnings" cargo doc --no-deps
|
||||
|
||||
ignored_count() {
|
||||
echo "$1" | grep -o '[0-9]* ignored' | awk '{s += $1} END {print s + 0}'
|
||||
}
|
||||
|
||||
for cfg in "" "--all-features"; do
|
||||
label="default features"
|
||||
[ -n "$cfg" ] && label="--all-features"
|
||||
echo "== doctests ($label)"
|
||||
out="$(cargo test --doc $cfg 2>&1)"
|
||||
echo "$out" | grep -E '^test result' | sed "s/^/ $label: /"
|
||||
ignored="$(ignored_count "$out")"
|
||||
if [ "$ignored" != "0" ]; then
|
||||
echo "FAIL: $ignored ignored doctest(s) ($label); convention 16:" \
|
||||
"examples are tested or no_run, never ignore" >&2
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
echo "== untested-badge scan over target/doc"
|
||||
badges="$(grep -rlE 'example-wrap[ "]?ignore|This example is (not |un)?tested' \
|
||||
target/doc/alktty/*.html 2>/dev/null || true)"
|
||||
if [ -n "$badges" ]; then
|
||||
echo "FAIL: untested-documentation badge(s) in the rendered docs:" >&2
|
||||
echo "$badges" | sed 's/^/ /' >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "docs-check: ok"
|
||||
Reference in new issue
Block a user