Skip to content

Commit 4f26943

Browse files
committed
website_zola: add site diff script for Hakyll vs Zola comparison
Compares built Hakyll output against Zola output, accounting for URL structure differences (flat .html vs directory/index.html). Reports identical, different, and missing files with inline diffs for text.
1 parent 46b2452 commit 4f26943

File tree

1 file changed

+140
-0
lines changed

1 file changed

+140
-0
lines changed

website_zola/diff_sites.sh

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
#!/usr/bin/env bash
2+
# Compare a Hakyll-generated site against a Zola-generated site.
3+
# Accounts for URL structure differences (flat .html vs directory/index.html).
4+
#
5+
# Usage: diff_sites.sh <hakyll_dir> <zola_dir>
6+
7+
set -euo pipefail
8+
9+
HAKYLL="${1:?Usage: diff_sites.sh <hakyll_dir> <zola_dir>}"
10+
ZOLA="${2:?Usage: diff_sites.sh <hakyll_dir> <zola_dir>}"
11+
12+
# Colors
13+
RED='\033[0;31m'
14+
GREEN='\033[0;32m'
15+
YELLOW='\033[0;33m'
16+
CYAN='\033[0;36m'
17+
BOLD='\033[1m'
18+
NC='\033[0m'
19+
20+
identical=0
21+
differing=0
22+
hakyll_only=0
23+
zola_only=0
24+
25+
# Map a Hakyll relative path to the expected Zola relative path.
26+
hakyll_to_zola_path() {
27+
local h="$1"
28+
case "$h" in
29+
# Top-level pages: foo.html -> foo/index.html
30+
about.html) echo "about/index.html" ;;
31+
found.html) echo "found/index.html" ;;
32+
nfc.html) echo "nfc/index.html" ;;
33+
nfc-armband.html) echo "nfc-armband/index.html" ;;
34+
archive.html) echo "archive/index.html" ;;
35+
# Posts: posts/slug.html -> posts/slug/index.html
36+
posts/*.html)
37+
local slug="${h%.html}"
38+
echo "${slug}/index.html"
39+
;;
40+
# These stay the same
41+
index.html | atom.xml | rss.xml | robots.txt | sitemap.xml)
42+
echo "$h"
43+
;;
44+
# CSS: Hakyll css/default.css -> Zola default.css (compiled SASS)
45+
css/default.css) echo "default.css" ;;
46+
css/default.scss) echo "__SKIP__" ;; # source file, not in Zola output
47+
# Everything else: try same path
48+
*) echo "$h" ;;
49+
esac
50+
}
51+
52+
echo -e "${BOLD}=== Site Diff: Hakyll vs Zola ===${NC}"
53+
echo -e "Hakyll: ${HAKYLL}"
54+
echo -e "Zola: ${ZOLA}"
55+
echo
56+
57+
# --- Phase 1: Check Hakyll files against Zola ---
58+
echo -e "${BOLD}--- Hakyll files ---${NC}"
59+
60+
while IFS= read -r hakyll_file; do
61+
rel="${hakyll_file#"$HAKYLL"/}"
62+
zola_rel=$(hakyll_to_zola_path "$rel")
63+
64+
if [[ "$zola_rel" == "__SKIP__" ]]; then
65+
continue
66+
fi
67+
68+
zola_file="${ZOLA}/${zola_rel}"
69+
70+
if [[ ! -f "$zola_file" ]]; then
71+
echo -e " ${YELLOW}HAKYLL-ONLY${NC} ${rel} (expected: ${zola_rel})"
72+
((hakyll_only++)) || true
73+
continue
74+
fi
75+
76+
# Binary or text comparison
77+
case "$rel" in
78+
*.html | *.xml | *.css | *.txt)
79+
if diff -q <(sed 's/[[:space:]]*$//' "$hakyll_file") \
80+
<(sed 's/[[:space:]]*$//' "$zola_file") &>/dev/null; then
81+
echo -e " ${GREEN}IDENTICAL${NC} ${rel}"
82+
((identical++)) || true
83+
else
84+
echo -e " ${RED}DIFFERENT${NC} ${rel} <-> ${zola_rel}"
85+
((differing++)) || true
86+
# Show first 30 lines of diff
87+
diff -u \
88+
--label "hakyll/${rel}" \
89+
--label "zola/${zola_rel}" \
90+
<(sed 's/[[:space:]]*$//' "$hakyll_file") \
91+
<(sed 's/[[:space:]]*$//' "$zola_file") \
92+
| head -60 || true
93+
echo
94+
fi
95+
;;
96+
*)
97+
if cmp -s "$hakyll_file" "$zola_file"; then
98+
echo -e " ${GREEN}IDENTICAL${NC} ${rel}"
99+
((identical++)) || true
100+
else
101+
echo -e " ${RED}DIFFERENT${NC} ${rel} <-> ${zola_rel} (binary)"
102+
((differing++)) || true
103+
fi
104+
;;
105+
esac
106+
done < <(find "$HAKYLL" -type f | sort)
107+
108+
# --- Phase 2: Check for Zola-only files ---
109+
echo
110+
echo -e "${BOLD}--- Zola-only files (not in Hakyll) ---${NC}"
111+
112+
# Build a set of expected Zola paths from Hakyll
113+
declare -A expected_zola_paths
114+
while IFS= read -r hakyll_file; do
115+
rel="${hakyll_file#"$HAKYLL"/}"
116+
zola_rel=$(hakyll_to_zola_path "$rel")
117+
if [[ "$zola_rel" != "__SKIP__" ]]; then
118+
expected_zola_paths["$zola_rel"]=1
119+
fi
120+
done < <(find "$HAKYLL" -type f | sort)
121+
122+
while IFS= read -r zola_file; do
123+
rel="${zola_file#"$ZOLA"/}"
124+
if [[ -z "${expected_zola_paths[$rel]+x}" ]]; then
125+
echo -e " ${CYAN}ZOLA-ONLY${NC} ${rel}"
126+
((zola_only++)) || true
127+
fi
128+
done < <(find "$ZOLA" -type f | sort)
129+
130+
# --- Summary ---
131+
echo
132+
echo -e "${BOLD}=== Summary ===${NC}"
133+
echo -e " ${GREEN}Identical${NC}: ${identical}"
134+
echo -e " ${RED}Different${NC}: ${differing}"
135+
echo -e " ${YELLOW}Hakyll-only${NC}: ${hakyll_only}"
136+
echo -e " ${CYAN}Zola-only${NC}: ${zola_only}"
137+
138+
if ((differing > 0 || hakyll_only > 0)); then
139+
exit 1
140+
fi

0 commit comments

Comments
 (0)