stagit-update (3878B)
1 #!/bin/sh 2 # Regenerate stagit HTML for one repo (arg) or all (no args). Rebuilds indexes 3 # and mirrors public repos into ~/repos/www-public/ for Bunny sync. 4 set -eu 5 6 REPOS=$HOME/repos 7 ASSETS=$REPOS/assets 8 PRIV=$REPOS/www 9 PUB=$REPOS/www-public 10 CACHE=$REPOS/.stagit-cache 11 12 mkdir -p "$PRIV" "$PUB" "$PUB/git" "$CACHE" 13 14 link_assets() { 15 out=$1 16 for f in style.css logo.png favicon.png; do 17 if [ -f "$ASSETS/$f" ]; then 18 ln -sfn "../$f" "$out/$f" 19 fi 20 done 21 } 22 23 is_empty() { 24 ! git --git-dir="$1" rev-parse HEAD >/dev/null 2>&1 25 } 26 27 # For every .md file stagit rendered into $out/file/, replace the <pre id="blob"> 28 # block with md4c-rendered HTML. Source comes from git HEAD (same content stagit 29 # saw), not the escaped HTML. No-op if md2html isn't installed. 30 render_markdown() { 31 out=$1 32 repo=$2 33 command -v md2html >/dev/null 2>&1 || return 0 34 [ -d "$out/file" ] || return 0 35 find "$out/file" -type f -name '*.md.html' | while read -r html; do 36 rel=${html#"$out/file/"} 37 rel=${rel%.html} 38 tmp=$(mktemp) 39 if git --git-dir="$repo" show "HEAD:$rel" 2>/dev/null | md2html > "$tmp" 2>/dev/null; then 40 awk -v mdfile="$tmp" ' 41 /<pre id="blob">/ { 42 print "<div id=\"md\">" 43 while ((getline line < mdfile) > 0) print line 44 close(mdfile) 45 print "</div>" 46 skip=1 47 next 48 } 49 skip && /<\/pre>/ { skip=0; next } 50 !skip { print } 51 ' "$html" > "$html.tmp" && mv "$html.tmp" "$html" 52 fi 53 rm -f "$tmp" 54 done 55 } 56 57 build_one() { 58 repo=$1 59 [ -d "$repo" ] || return 0 60 # Skip repos with no commits yet — stagit errors on them, and there's 61 # nothing meaningful to render until the first push. 62 is_empty "$repo" && return 0 63 name=$(basename "$repo" .git) 64 65 # Per-output cache files — stagit's -c caches commit HTMLs, keyed to the 66 # output dir that stagit wrote them to, so PRIV and PUB need separate caches. 67 out=$PRIV/$name 68 mkdir -p "$out" 69 (cd "$out" && stagit -c "$CACHE/$name.priv.cache" "$repo") 70 link_assets "$out" 71 render_markdown "$out" "$repo" 72 73 if [ -f "$repo/public" ]; then 74 out=$PUB/$name 75 mkdir -p "$out" 76 (cd "$out" && stagit -c "$CACHE/$name.pub.cache" "$repo") 77 link_assets "$out" 78 render_markdown "$out" "$repo" 79 # bare repo mirror for `git clone` (skip server-side bits) 80 mkdir -p "$PUB/git/$name.git" 81 rsync -a --delete --exclude=hooks --exclude=public "$repo/" "$PUB/git/$name.git/" 82 # github-style archive tarballs (with .b2 sidecars) under <name>/archive/ 83 "$REPOS/bin/archive-refs" "$repo" 84 else 85 # drop public copy if marker was removed (archive-refs handles its own) 86 rm -rf "$PUB/$name" "$PUB/git/$name.git" 87 fi 88 } 89 90 if [ $# -ge 1 ]; then 91 build_one "$REPOS/$1.git" 92 else 93 for r in "$REPOS"/*.git; do build_one "$r"; done 94 fi 95 96 # shared assets at tree root 97 for f in style.css logo.png favicon.png; do 98 [ -f "$ASSETS/$f" ] || continue 99 cp -u "$ASSETS/$f" "$PRIV/" 100 cp -u "$ASSETS/$f" "$PUB/" 101 done 102 103 # indexes 104 all_list="" 105 pub_list="" 106 for r in "$REPOS"/*.git; do 107 [ -d "$r" ] || continue 108 is_empty "$r" && continue 109 all_list="$all_list $r" 110 if [ -f "$r/public" ]; then 111 pub_list="$pub_list $r" 112 fi 113 done 114 115 if [ -n "$all_list" ]; then 116 # shellcheck disable=SC2086 117 stagit-index $all_list > "$PRIV/index.html" 118 else 119 : > "$PRIV/index.html" 120 fi 121 122 if [ -n "$pub_list" ]; then 123 # shellcheck disable=SC2086 124 stagit-index $pub_list > "$PUB/index.html" 125 else 126 : > "$PUB/index.html" 127 fi 128 129 # optional: user-customizable hook for pushing $PUB to Bunny 130 [ -x "$REPOS/bin/publish-public" ] && "$REPOS/bin/publish-public" || true