-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcheck-links.sh
More file actions
67 lines (57 loc) · 1.75 KB
/
check-links.sh
File metadata and controls
67 lines (57 loc) · 1.75 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
#!/usr/bin/env bash
# check-links.sh — Scan exported site for broken internal links.
DIST="${1:-dist}"
if [ ! -d "$DIST" ]; then
echo "Error: $DIST/ not found. Run export-site.sh first."
exit 1
fi
echo "Link Checker: scanning $DIST/"
echo "================================"
BROKEN_LOG=$(mktemp)
# Collect all internal links
for htmlfile in $(find "$DIST" -name '*.html' -type f); do
# Extract href="..." and src="..." values
for link in $(grep -oP '(?:href|src)="\K[^"]+' "$htmlfile" 2>/dev/null || true); do
# Skip external, anchors, javascript
case "$link" in
http://*|https://*|mailto:*|javascript:*|//*|\#*|data:*) continue ;;
esac
# Resolve path
if [ "${link:0:1}" = "/" ]; then
TARGET="$DIST$link"
else
TARGET="$(dirname "$htmlfile")/$link"
fi
# Strip fragment and query
TARGET="${TARGET%%#*}"
TARGET="${TARGET%%\?*}"
[ -z "$TARGET" ] && continue
# Check existence
if [ -f "$TARGET" ]; then
continue
elif [ -d "$TARGET" ] && [ -f "$TARGET/index.html" ]; then
continue
elif [ "${TARGET: -1}" = "/" ] && [ -f "${TARGET}index.html" ]; then
continue
else
REL="${htmlfile#$DIST/}"
echo " BROKEN $REL -> $link"
echo "$link" >> "$BROKEN_LOG"
fi
done
done
echo ""
echo "================================"
if [ -s "$BROKEN_LOG" ]; then
COUNT=$(wc -l < "$BROKEN_LOG")
echo "$COUNT broken link(s) found."
echo ""
echo "Summary:"
sort "$BROKEN_LOG" | uniq -c | sort -rn | head -10
rm -f "$BROKEN_LOG"
exit 1
else
echo "All internal links resolve."
rm -f "$BROKEN_LOG"
exit 0
fi