#!/usr/bin/env bash # # Compare the scripts/repos.list clone list against the Gitea server # (tea repo list --output json). # # - MISSING: exists on the server but is neither in the clone list # nor in repos.ignore # - STALE: listed as a Gitea repo but does not exist on the server # # Exit code: 0 if everything matches; 1 if either list has hits. set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" LIST="$SCRIPT_DIR/repos.list" IGNORE="$SCRIPT_DIR/repos.ignore" GITEA_HOST="git.teletypegames.org" command -v tea >/dev/null 2>&1 || { echo "ERROR: tea CLI not found. Run: make tea" >&2 exit 1 } # Repos on the server: owner/name. # # Paginated on purpose. Gitea caps a page at MAX_RESPONSE_ITEMS (50 by default) # whatever --limit says, so `tea repo list --limit 1000` silently returns the # first 50 — which looked like a repo had vanished from the server the day the # estate grew past fifty. Pages are requested until a short one comes back. server=$( page=1 while :; do batch=$(tea api "/user/repos?limit=50&page=$page" | jq -r '.[].full_name') [ -z "$batch" ] && break echo "$batch" [ "$(echo "$batch" | wc -l)" -lt 50 ] && break page=$((page + 1)) done | sort -u ) [ -n "$server" ] || { echo "ERROR: the server returned no repos — is the tea login still valid?" >&2; exit 1; } # Gitea repos in the clone list: owner/name extracted from the clone URL listed=$(sed -nE "s#^[^|#]+\|ssh://git@${GITEA_HOST}:[0-9]+/(.+)\$#\1#p" "$LIST" | sed 's/\.git$//' | sort) # Intentionally excluded repos ignored=$(sed -e 's/#.*//' -e '/^[[:space:]]*$/d' "$IGNORE" 2>/dev/null | sort || true) missing=$(comm -23 <(echo "$server") <(sort -u <(echo "$listed") <(echo "$ignored"))) stale=$(comm -13 <(echo "$server") <(echo "$listed")) status=0 if [ -n "$missing" ]; then echo "MISSING from the clone list (exists on the server):" echo "$missing" | sed 's/^/ - /' status=1 fi if [ -n "$stale" ]; then echo "STALE in the clone list (not on the server):" echo "$stale" | sed 's/^/ - /' status=1 fi if [ "$status" -eq 0 ]; then echo "OK: the clone list covers all $(echo "$server" | wc -l | tr -d ' ') repos on the server ($(echo "$ignored" | grep -c . || true) intentionally excluded)." fi exit "$status"