62b99f8678
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).
128 lines
4.3 KiB
Bash
Executable File
128 lines
4.3 KiB
Bash
Executable File
#!/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
|