11#! /bin/bash
2- # validate-docs.sh - AI-friendly documentation validation script
3- #
4- # Usage:
5- # ./bin/validate-docs.sh # Validate all docs
6- # ./bin/validate-docs.sh path/to/file.rst # Validate specific file
7- # ./bin/validate-docs.sh --changed # Validate only changed files in git
8- #
9- # This script is designed to be easily used by AI assistants and developers
10- # during documentation development, before pushing to CI.
11-
2+ # Validate RST documentation files
123set -e
134
14- # Colors for output (disabled if not terminal)
15- if [ -t 1 ]; then
16- RED=' \033[0;31m'
17- GREEN=' \033[0;32m'
18- YELLOW=' \033[1;33m'
19- NC=' \033[0m' # No Color
20- else
21- RED=' '
22- GREEN=' '
23- YELLOW=' '
24- NC=' '
25- fi
26-
27- echo_success () {
28- echo -e " ${GREEN} ✓${NC} $1 "
29- }
30-
31- echo_error () {
32- echo -e " ${RED} ✗${NC} $1 "
33- }
34-
35- echo_warning () {
36- echo -e " ${YELLOW} ⚠${NC} $1 "
37- }
38-
39- echo_info () {
40- echo -e " ℹ $1 "
41- }
42-
43- # Check if rstcheck is installed
5+ # Check rstcheck is installed
446if ! command -v rstcheck & > /dev/null; then
45- echo_error " rstcheck is not installed"
46- echo_info " Install it with: pip install rstcheck[sphinx]"
7+ echo " Error: rstcheck not installed. Install with: pip install 'rstcheck[sphinx]'"
478 exit 1
489fi
4910
50- # Check if config file exists (try multiple locations)
51- if [ -f " docs/.rstcheck.cfg" ]; then
52- CONFIG_FILE=" docs/.rstcheck.cfg"
53- elif [ -f " .rstcheck.cfg" ]; then
54- CONFIG_FILE=" .rstcheck.cfg"
11+ # Validate RST files
12+ if [ " $1 " = " --changed" ]; then
13+ # Check only changed files
14+ git diff --name-only HEAD -- ' *.rst' | xargs -r rstcheck --config docs/.rstcheck.cfg
5515else
56- echo_warning " No .rstcheck.cfg found, creating default config in docs/..."
57- CONFIG_FILE=" docs/.rstcheck.cfg"
58- mkdir -p docs
59- cat > " $CONFIG_FILE " << 'EOF '
60- [rstcheck]
61- # Ignore Sphinx-specific roles that are not part of standard RST
62- ignore_roles =
63- meth,
64- class,
65- ref,
66- doc,
67- attr,
68- mod,
69- func,
70- data,
71- const,
72- exc,
73- obj,
74- any
75-
76- # Ignore Sphinx-specific directives
77- ignore_directives =
78- automodule,
79- autoclass,
80- autofunction,
81- toctree,
82- literalinclude,
83- code-block,
84- note,
85- warning,
86- versionadded,
87- versionchanged,
88- deprecated,
89- seealso,
90- rubric,
91- centered,
92- hlist,
93- glossary,
94- productionlist
95-
96- # Ignore common informational messages
97- ignore_messages = (Hyperlink target "[^"]*" is not referenced\.$)
98-
99- # Report level: ERROR, WARNING, INFO
100- report_level = WARNING
101- EOF
102- echo_success " Created $CONFIG_FILE "
103- fi
104-
105- # Determine what files to check
106- if [ " $1 " == " --changed" ]; then
107- # Check only changed RST files
108- echo_info " Checking changed RST files..."
109- FILES=$( git diff --name-only HEAD -- ' *.rst' 2> /dev/null || true)
110- if [ -z " $FILES " ]; then
111- FILES=$( git diff --cached --name-only -- ' *.rst' 2> /dev/null || true)
112- fi
113- if [ -z " $FILES " ]; then
114- echo_info " No changed RST files to check"
115- exit 0
116- fi
117- elif [ -n " $1 " ]; then
118- # Check specific file(s) provided as arguments
119- FILES=" $@ "
120- else
121- # Check all RST files in docs/source/ (matching Docker behavior)
122- echo_info " Checking all RST files in docs/source/..."
123- FILES=$( find docs/source -name " *.rst" 2> /dev/null || true)
124- if [ -z " $FILES " ]; then
125- echo_warning " No RST files found in docs/source/"
126- exit 0
127- fi
128- fi
129-
130- # Count files
131- FILE_COUNT=$( echo " $FILES " | wc -w)
132- echo_info " Validating $FILE_COUNT RST file(s)..."
133-
134- # Run rstcheck on each file
135- ERRORS_FOUND=0
136- WARNINGS_FOUND=0
137-
138- for file in $FILES ; do
139- if [ ! -f " $file " ]; then
140- echo_warning " File not found: $file "
141- continue
142- fi
143-
144- # Run rstcheck and capture output
145- if OUTPUT=$( rstcheck --config " $CONFIG_FILE " " $file " 2>&1 ) ; then
146- echo_success " $file "
147- else
148- # Parse output for errors vs warnings
149- if echo " $OUTPUT " | grep -q " ERROR" ; then
150- echo_error " $file "
151- echo " $OUTPUT " | grep " ERROR" | sed ' s/^/ /'
152- ERRORS_FOUND=$(( ERRORS_FOUND + 1 ))
153- elif echo " $OUTPUT " | grep -q " WARNING" ; then
154- echo_warning " $file "
155- if [ " ${VERBOSE:- 0} " == " 1" ]; then
156- echo " $OUTPUT " | grep " WARNING" | head -5 | sed ' s/^/ /'
157- fi
158- WARNINGS_FOUND=$(( WARNINGS_FOUND + 1 ))
159- else
160- echo_error " $file (unknown issue)"
161- echo " $OUTPUT " | head -5 | sed ' s/^/ /'
162- ERRORS_FOUND=$(( ERRORS_FOUND + 1 ))
163- fi
164- fi
165- done
166-
167- # Summary
168- echo " "
169- if [ $ERRORS_FOUND -eq 0 ] && [ $WARNINGS_FOUND -eq 0 ]; then
170- echo_success " All RST files passed validation!"
171- exit 0
172- elif [ $ERRORS_FOUND -eq 0 ]; then
173- echo_warning " Validation completed with $WARNINGS_FOUND warning(s)"
174- echo_info " Run with VERBOSE=1 to see warning details"
175- exit 0
176- else
177- echo_error " Validation failed with $ERRORS_FOUND error(s) and $WARNINGS_FOUND warning(s)"
178- echo_info " Fix the errors above and run again"
179- exit 1
16+ # Check all source files
17+ rstcheck --config docs/.rstcheck.cfg docs/source/** /* .rst
18018fi
0 commit comments