blob: bc9155b56ca07dc7ce60cd25cfad6ad730db749e [file]
#!/bin/sh
# What docs-only.sh calls a Markdown-only change, and what it must go on sending to the
# full checks. A wrong yes skips the tests on a change that needed them, so the cases
# that must say no are the ones that matter, and the last checks hold the premise: no
# crate or tap embeds a Markdown file or opens one above its own directory, which would
# make an edit to it a change to the build.
#
# Run by `make check`.
set -eu
here=$(CDPATH='' cd -- "$(dirname -- "$0")" && pwd)
root=$(CDPATH='' cd -- "$here/.." && pwd)
script="$here/docs-only.sh"
failures=0
check() {
want=$1
shift
status=0
printf "$@" | sh "$script" || status=$?
if [ "$want" = yes ] && [ "$status" -ne 0 ]; then
printf 'not docs-only, should be: %s\n' "$(printf "$@" | tr '\n' ' ')" >&2
failures=$((failures + 1))
elif [ "$want" = no ] && [ "$status" -eq 0 ]; then
printf 'docs-only, should not be: %s\n' "$(printf "$@" | tr '\n' ' ')" >&2
failures=$((failures + 1))
fi
}
check yes 'README.md\n'
check yes 'local/README.md\nAGENTS.md\ndocs/design/a b.md\n'
check yes 'crates/core/AGENTS.md\n'
check yes 'taps/github-issues/AGENTS.md\n'
# the last line without its newline, as a caller's printf may send it
check yes 'README.md\nPLAN.md'
# nothing listed: the caller could not say what changed
check no ''
check no '\n'
check no 'crates/core/src/lib.rs\n'
check no 'README.md\ncrates/core/src/lib.rs\n'
# a last line without its newline still counts
check no 'README.md\ncrates/core/src/lib.rs'
check no 'crates/core/src/lib.rs\nREADME.md\n'
# embedded by a crate, not documentation
check no 'local/litellm.yaml\n'
check no 'crates/web/static/index.html\n'
check no '.github/workflows/ci.yml\n'
check no 'scripts/docs-only.sh\n'
# Markdown in the code: a fixture, or a README a doc attribute could include
check no 'crates/core/tests/fixtures/entry.md\n'
check no 'crates/web/README.md\n'
check no 'taps/github-issues/README.md\n'
# only the extension counts, and only in lower case
check no 'README.md.orig\n'
check no 'notes.MD\n'
check no 'mdbook\n'
check no 'scripts/build.cmd\n'
# git quotes a name with a control character in it, and the quote ends the name
check no '"docs/a\\nb.md"\n'
# A match fails, and so does a search that could not run: a grep that failed to look and
# reports nothing found is the worst of the three answers.
no_match() {
what=$1
shift
status=0
grep "$@" >&2 || status=$?
case $status in
0) printf '%s, so an edit to it changes the build\n' "$what" >&2 ;;
1) return 0 ;;
*) printf 'could not search for whether %s\n' "$what" >&2 ;;
esac
failures=$((failures + 1))
}
no_match 'a crate or tap embeds a Markdown file' \
-rPzl --include='*.rs' 'include_(str|bytes)!\s*\([^)]*\.md"' "$root/crates" "$root/taps"
no_match 'a crate or tap opens a Markdown file above its own directory' \
-rnE --include='*.rs' '"/?(\.\./)+[^"*?]*\.md"' "$root/crates" "$root/taps"
if [ "$failures" -ne 0 ]; then
printf '\n%s docs-only case(s) failed\n' "$failures" >&2
exit 1
fi
printf 'docs-only.sh: every case holds\n'