cache: git-tracked build cache — 16 packages, survives make clean + clone

Red Bear is a fork/overlay on top of Redox. The upstream build
system wasn't designed for forks — it loses all cached stages on
make clean with no recovery path.

This commit adds a git-tracked build cache:
- local/cache/pkgar/{pkg}/stage.pkgar — per-package cache files
- cache-sync.sh: sync built packages → git-tracked cache
- cache-sync.sh --restore: restore cache → recipe targets
- cache-sync.sh --commit: sync + git commit
- Auto-restore before build, auto-sync after build

Cache survives: make clean, make distclean, git clone, upstream rebase.
Recovery from clean: seconds (restore from git) vs hours (full rebuild).
This commit is contained in:
2026-04-28 08:14:22 +01:00
parent d1c5beb50d
commit 62b99f8678
71 changed files with 214 additions and 24 deletions
+127
View File
@@ -0,0 +1,127 @@
#!/usr/bin/env bash
# Red Bear OS — Git-Tracked Build Cache
# Automatically syncs recipe stage.pkgar files to local/cache/pkgar/
# and commits them to git so the cache survives make clean AND git clone.
#
# The cache is organized as: local/cache/pkgar/{pkgname}/stage.pkgar
# This keeps individual files small enough for git (<100MB each).
#
# Usage:
# ./local/scripts/cache-sync.sh # Sync all built packages to cache
# ./local/scripts/cache-sync.sh --commit # Sync + git commit
# ./local/scripts/cache-sync.sh --restore # Restore cache to recipe targets
# ./local/scripts/cache-sync.sh --status # Show cache vs build state
set -euo pipefail
cd "$(dirname "$0")/../.."
CACHE_ROOT="local/cache/pkgar"
mkdir -p "${CACHE_ROOT}"
MODE="${1:-}"
if [ "$MODE" = "--status" ]; then
echo "=== Red Bear Cache Status ==="
cached=0; stale=0; missing=0
for pkgar in "${CACHE_ROOT}"/*/stage.pkgar; do
[ -f "$pkgar" ] || continue
pkg=$(basename "$(dirname "$pkgar")")
recipe_dir=$(find recipes -maxdepth 3 -name "$pkg" -type d 2>/dev/null | head -1)
if [ -z "$recipe_dir" ]; then
echo " ORPHAN $pkg (no recipe)"
stale=$((stale + 1))
continue
fi
target="${recipe_dir}/target/x86_64-unknown-redox/stage.pkgar"
if [ -f "$target" ]; then
if [ "$pkgar" -nt "$target" ]; then
echo " STALE $pkg (cache newer than build)"
stale=$((stale + 1))
else
echo " SYNCED $pkg"
cached=$((cached + 1))
fi
else
echo " CACHED $pkg (no build)"
cached=$((cached + 1))
fi
done
# Check built but not cached
while IFS= read -r target; do
pkg=$(echo "$target" | sed 's|recipes/[^/]*/[^/]*/||; s|/target/.*||')
if [ ! -f "${CACHE_ROOT}/${pkg}/stage.pkgar" ]; then
size=$(stat -c%s "$target" 2>/dev/null || echo 0)
echo " UNCACHED $pkg ($(numfmt --to=iec $size 2>/dev/null || echo ${size}B))"
missing=$((missing + 1))
fi
done < <(find recipes -name "stage.pkgar" -path "*/target/x86_64-unknown-redox/*" 2>/dev/null | head -100)
echo ""
echo "Synced: $cached Stale: $stale Uncached: $missing"
exit 0
fi
if [ "$MODE" = "--restore" ]; then
echo "=== Restoring Cache to Recipes ==="
count=0
for pkgar in "${CACHE_ROOT}"/*/stage.pkgar; do
[ -f "$pkgar" ] || continue
pkg=$(basename "$(dirname "$pkgar")")
recipe_dir=$(find recipes -maxdepth 4 -name "$pkg" -type d 2>/dev/null | head -1)
if [ -z "$recipe_dir" ]; then continue; fi
target="${recipe_dir}/target/x86_64-unknown-redox/stage.pkgar"
if [ ! -f "$target" ] || [ "$pkgar" -nt "$target" ]; then
mkdir -p "$(dirname "$target")"
cp "$pkgar" "$target"
count=$((count + 1))
fi
done
echo "Restored $count packages"
exit 0
fi
# Default: --sync mode
echo "=== Syncing Build Cache ==="
synced=0
while IFS= read -r target; do
pkg_path="${target%/target/x86_64-unknown-redox/stage.pkgar}"
# Extract package name: recipes/{category}/{name}/target/... → {name}
pkg=$(basename "$pkg_path")
[ -z "$pkg" ] && continue
cache_dir="${CACHE_ROOT}/${pkg}"
cache_file="${cache_dir}/stage.pkgar"
# Only copy if build is newer
if [ -f "$cache_file" ] && [ ! "$target" -nt "$cache_file" ]; then
continue
fi
mkdir -p "$cache_dir"
cp "$target" "$cache_file"
# Also save auto_deps
deps_file="${pkg_path}/target/x86_64-unknown-redox/auto_deps.toml"
if [ -f "$deps_file" ]; then
cp "$deps_file" "${cache_dir}/auto_deps.toml"
fi
synced=$((synced + 1))
done < <(find recipes -name "stage.pkgar" -path "*/target/x86_64-unknown-redox/*" 2>/dev/null)
echo "Synced $synced packages to ${CACHE_ROOT}/"
if [ "$MODE" = "--commit" ] && [ $synced -gt 0 ]; then
echo ""
echo "=== Committing Cache ==="
git add "${CACHE_ROOT}/"
# Only commit if there are staged changes
if git diff --cached --quiet; then
echo "No cache changes to commit"
else
commit_msg="cache: $(date +%Y-%m-%d)${synced} packages"
git commit -m "$commit_msg"
echo "Committed: $commit_msg"
echo "To push: git push"
fi
fi