-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Expand file tree
/
Copy pathlint-docs.sh
More file actions
executable file
·197 lines (190 loc) · 6.73 KB
/
Copy pathlint-docs.sh
File metadata and controls
executable file
·197 lines (190 loc) · 6.73 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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
#!/bin/bash
#
# Convenience wrapper for documentation linters
# Can run from any directory!
#
# Usage:
# ./lint-docs.sh seo file1.txt file2.rst ...
# ./lint-docs.sh 404 file1.txt file2.rst ...
# ./lint-docs.sh redirects netlify.toml ...
# ./lint-docs.sh all file1.txt file2.rst ...
#
# Find repo root - try git first, then fall back to script location
REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null)"
if [ -z "$REPO_ROOT" ]; then
# Not in a git repo - use script's own location
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
if [ -d "$SCRIPT_DIR/.github/lint-docs" ]; then
REPO_ROOT="$SCRIPT_DIR"
else
echo "❌ Cannot find repo root. Run from within the repo or use absolute path to this script."
exit 1
fi
fi
LINT_DIR="$REPO_ROOT/.github/lint-docs"
# Run Vale and strip suppressed-severity counts from its summary line.
# Uses CLICOLOR_FORCE=1 so Vale keeps colors even when stdout is a pipe.
_vale_run() {
CLICOLOR_FORCE=1 vale --config "$REPO_ROOT/vale.ini" --minAlertLevel "$VALE_MIN_ALERT_LEVEL" "$@" | \
awk -v level="$VALE_MIN_ALERT_LEVEL" '
NR > 1 { print prev }
{ prev = $0 }
END {
if (NR == 0) exit
gsub(/\033\[[0-9;]*m/, "", prev)
if (level == "suggestion") {
sub(/ and /, ", and ", prev)
} else if (level == "warning") {
match(prev, /[0-9]+ warnings?/)
w = substr(prev, RSTART, RLENGTH)
sub(/,.*in /, " and " w " in ", prev)
} else if (level == "error")
gsub(/, [0-9]+ warnings? and [0-9]+ suggestions? in /, " in ", prev)
print prev
}
'
return ${PIPESTATUS[0]}
}
# Vale alert threshold. Defaults to warning to match CI; override per-run, e.g.:
# VALE_MIN_ALERT_LEVEL=suggestion ./lint-docs.sh vale my-file.txt
VALE_MIN_ALERT_LEVEL="${VALE_MIN_ALERT_LEVEL:-warning}"
case "$VALE_MIN_ALERT_LEVEL" in
suggestion|warning|error) ;;
*)
echo "❌ Invalid VALE_MIN_ALERT_LEVEL: '$VALE_MIN_ALERT_LEVEL' (expected: suggestion, warning, or error)"
exit 1
;;
esac
# Check if node is available
if ! command -v node &> /dev/null; then
echo "❌ Node.js is required but not installed"
exit 1
fi
# Parse command
CMD="${1:-help}"
shift
case "$CMD" in
seo)
npx tsx "$LINT_DIR/seo-lint-cli.ts" "$@"
seo_exit=$?
if [ $seo_exit -ne 0 ]; then
echo ""
echo "⚠️ SEO issues found. How would you like to proceed?"
echo " 1. Fix now — invoke the fix-seo skill (use the findings above as the"
echo " working list; skip the linter re-run in Step 1)"
echo " 2. Skip — continue without fixing"
echo ""
echo " Please choose an option before continuing."
fi
exit $seo_exit
;;
404|links)
npx tsx "$LINT_DIR/404-lint-cli.ts" "$@"
lint_exit=$?
if [ $lint_exit -ne 0 ] && [ ! -t 1 ]; then
echo ""
echo "⚠️ Broken links found."
echo " The fix-404s skill can resolve these for you: it checks each URL"
echo " for redirects, searches for live replacements, and confirms changes"
echo " with you before applying them."
echo ""
echo " How would you like to proceed?"
echo " 1. Fix now — invoke the fix-404s skill"
echo " 2. Skip — leave broken links for now and continue"
fi
exit $lint_exit
;;
redirects|redirect)
npx tsx "$LINT_DIR/redirect-lint-cli.ts" "$@"
;;
findability|find)
npx tsx "$LINT_DIR/findability-lint-cli.ts" "$@"
;;
nested)
npx tsx "$LINT_DIR/nested-components-lint-cli.ts" "$@"
;;
vale)
if ! command -v vale &> /dev/null; then
echo "❌ Vale is required but not installed."
echo " Install: https://vale.sh/docs/vale-cli/installation/"
exit 1
fi
_vale_run "$@"
;;
all|both)
exit_code=0
echo "=== SEO Linter ==="
npx tsx "$LINT_DIR/seo-lint-cli.ts" "$@"
seo_exit=$?
if [ $seo_exit -ne 0 ]; then
echo ""
echo "⚠️ SEO issues found. How would you like to proceed?"
echo " 1. Fix now — invoke the fix-seo skill (use the findings above as the"
echo " working list; skip the linter re-run in Step 1)"
echo " 2. Skip — continue without fixing"
echo ""
echo " Please choose an option before continuing."
exit_code=1
fi
echo ""
echo "=== 404 Linter ==="
npx tsx "$LINT_DIR/404-lint-cli.ts" "$@"
link_exit=$?
if [ $link_exit -ne 0 ] && [ ! -t 1 ]; then
echo ""
echo "⚠️ Broken links found."
echo " The fix-404s skill can resolve these for you: it checks each URL"
echo " for redirects, searches for live replacements, and confirms changes"
echo " with you before applying them."
echo ""
echo " How would you like to proceed?"
echo " 1. Fix now — invoke the fix-404s skill"
echo " 2. Skip — leave broken links for now and continue"
exit_code=1
fi
echo ""
echo "=== Findability Linter ==="
npx tsx "$LINT_DIR/findability-lint-cli.ts" "$@" || exit_code=1
echo ""
echo "=== Nested Components Linter ==="
npx tsx "$LINT_DIR/nested-components-lint-cli.ts" "$@" || exit_code=1
echo ""
echo "=== Vale Prose Linter ==="
if command -v vale &> /dev/null; then
_vale_run "$@" || exit_code=1
else
echo "⚠️ Vale is not installed. Skipping prose lint. Install: https://vale.sh/docs/vale-cli/installation/"
fi
exit $exit_code
;;
help|--help|-h)
echo "Documentation Linters"
echo ""
echo "Usage: ./lint-docs.sh <command> <files...>"
echo ""
echo "Commands:"
echo " seo Run SEO linter (titles, descriptions, headings)"
echo " 404 Run broken link checker"
echo " redirects Run circular redirect checker"
echo " findability Run findability linter (facets, keywords, docs URLs)"
echo " nested Run nested components linter (forbidden RST directive nesting)"
echo " vale Run Vale prose linter (requires Vale installed)"
echo " all Run SEO + 404 + findability + nested + Vale prose linters"
echo ""
echo "Examples:"
echo " ./lint-docs.sh seo content/manual/source/intro.txt"
echo " ./lint-docs.sh 404 content/atlas/source/*.txt"
echo " ./lint-docs.sh redirects content/atlas/netlify.toml"
echo " ./lint-docs.sh vale content/atlas/source/my-page.txt"
echo " ./lint-docs.sh all my-file.rst another-file.md"
echo ""
echo "Environment variables:"
echo " VALE_MIN_ALERT_LEVEL Vale threshold: suggestion, warning (default), or error"
echo " e.g. VALE_MIN_ALERT_LEVEL=suggestion ./lint-docs.sh vale my-file.txt"
;;
*)
echo "Unknown command: $CMD"
echo "Run './lint-docs.sh help' for usage"
exit 1
;;
esac