whiskers.git / web / tools / screens
screens34 lines · 1.8 KB · raw
1#!/usr/bin/env bash
2# Makes the page's screenshots (worker/public/screens/) from the Android screenshot tests' goldens,
3# so they are always the app's current look: each golden named in site/src/config.rs's `SHOTS`,
4# shrunk to fit SCREEN_FIT on its longest side (never enlarged). A file is made again only when its
5# golden's content hash differs from the one stamped beside it.
6#
7#     web/tools/screens [dir]          (default worker/public/screens; `tools/build` runs it)
8set -euo pipefail
9cd "$(dirname "$0")/.."
10out="${1:-worker/public/screens}"
11config=site/src/config.rs
12goldens=../android/app/screenshots
13fit="$(grep -oP 'SCREEN_FIT: u32 = \K[0-9]+' "$config")"
14mkdir -p "$out"
15shots="$(sed -n 's/^pub const SHOT_[A-Z_]*: Shot = Shot { name: "\([^"]*\)", width: [0-9]*, height: [0-9]*, keep: \([0-9]*\),.*/\1 \2/p' "$config")"
16names="$(cut -d' ' -f1 <<<"$shots")"
17[ -n "$names" ] || { echo "screens: no screenshots found in $config" >&2; exit 1; }
18while read -r name keep; do
19  src="$goldens/$name.png"
20  [ -f "$src" ] || { echo "screens: the golden $src is missing" >&2; exit 1; }
21  sum="$(sha256sum "$src" | cut -d' ' -f1)-$fit-$keep"
22  if [ -f "$out/$name.png" ] && [ "$(cat "$out/.$name.stamp" 2>/dev/null)" = "$sum" ]; then continue; fi
23  ffmpeg -nostdin -hide_banner -loglevel error -y -i "$src" \
24    -vf "crop=iw:min($keep\,ih):0:0,scale=w='min($fit,iw)':h='min($fit,ih)':force_original_aspect_ratio=decrease:flags=lanczos" \
25    -compression_level 9 "$out/$name.png"
26  printf '%s' "$sum" > "$out/.$name.stamp"
27done <<<"$shots"
28# Nothing is left from a screenshot the page no longer shows.
29for f in "$out"/*.png; do
30  [ -e "$f" ] || continue
31  base="$(basename "$f" .png)"
32  grep -qx "$base" <<<"$names" || rm -f "$f" "$out/.$base.stamp"
33done
34echo "screens: $(echo "$names" | wc -l) screenshots in $out"