#!/usr/bin/env bash # repair-archive-format.sh — Normalize unversioned/old-format archives to standard format. # # Standard format: {cat}-{pkg}-v{version}-patched.tar.gz containing: # source/ — recipe source tree # recipe.toml — recipe metadata # # Repairs archives that: # 1. Have raw repo content at root (not inside source/ dir) # 2. Missing recipe.toml # 3. Include build artifacts (source/target/) # # Usage: # ./local/scripts/repair-archive-format.sh [--dry-run] set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" POOL="$PROJECT_ROOT/sources/x86_64-unknown-redox" WORK="/tmp/redbear-archive-repair-$$" DRY_RUN=0 [ "${1:-}" = "--dry-run" ] && DRY_RUN=1 GREEN='\033[1;32m' YELLOW='\033[1;33m' NC='\033[0m' mkdir -p "$WORK" repaired=0 skipped=0 for archive in "$POOL"/*.tar.gz; do name=$(basename "$archive") # Skip already properly versioned (has -v HEX or -v DIGITS) if echo "$name" | grep -qE '\-v[a-f0-9]{7,}|\-v\d+\.'; then skipped=$((skipped + 1)) continue fi # Extract category and package from filename: {cat}-{pkg}-*.tar.gz # For unversioned: core-base.tar.gz -> cat=core, pkg=base # For vunknown: core-base-vunknown-patched.tar.gz -> cat=core, pkg=base base="${name%.tar.gz}" base="${base%-patched}" base="${base%-vunknown}" cat_name=$(echo "$base" | cut -d- -f1) pkg_name=$(echo "$base" | cut -d- -f2-) # Find the recipe.toml recipe="" for candidate in \ "$PROJECT_ROOT/recipes/$cat_name/$pkg_name/recipe.toml" \ "$PROJECT_ROOT/local/recipes/$cat_name/$pkg_name/recipe.toml"; do [ -f "$candidate" ] && recipe="$candidate" && break done if [ -z "$recipe" ]; then echo -e "${YELLOW}SKIP${NC} $name (no recipe.toml found in recipes/)" continue fi # Determine version version=$(python3 -c " import tomllib, subprocess from pathlib import Path with open('$recipe', 'rb') as f: data = tomllib.load(f) src = data.get('source', {}) if not isinstance(src, dict): print('unknown') elif 'tar' in src: import re m = re.search(r'/?v?(\d+\.\d+(?:\.\d+)?)(?:\.tar|/$)', src['tar']) print(m.group(1) if m else 'unknown') elif 'git' in src: rev = src.get('rev', '') if rev: print(rev[:7]) else: pkg_dir = Path('$recipe').parent / 'source' if (pkg_dir / '.git').exists(): r = subprocess.run(['git','-C',str(pkg_dir),'rev-parse','--short','HEAD'], capture_output=True, text=True) print(r.stdout.strip() if r.returncode == 0 else 'unknown') else: print('unknown') else: print('unknown') " 2>/dev/null || echo "unknown") new_name="${cat_name}-${pkg_name}-v${version}-patched.tar.gz" new_path="$POOL/$new_name" if [ -f "$new_path" ] && [ "$new_name" != "$name" ]; then echo -e "${YELLOW}SKIP${NC} $name (target $new_name already exists)" continue fi # Check current format has_source=$(tar tf "$archive" 2>/dev/null | grep -c '^source/' || true) has_recipe=$(tar tf "$archive" 2>/dev/null | grep -c '^recipe.toml$' || true) has_target=$(tar tf "$archive" 2>/dev/null | grep -c 'source/target/' || true) if [ "$has_source" -gt 0 ] && [ "$has_recipe" -gt 0 ] && [ "$has_target" -eq 0 ] && [ "$new_name" = "$name" ]; then skipped=$((skipped + 1)) continue fi echo -e "${GREEN}REPAIR${NC} $name -> $new_name (v$version)" if [ "$DRY_RUN" -eq 1 ]; then echo " [dry-run] would repackage: source/=$has_source recipe=$has_recipe target=$has_target" repaired=$((repaired + 1)) continue fi # Create temp dir for repackaging tmpdir="$WORK/$base" rm -rf "$tmpdir" mkdir -p "$tmpdir/source" # Extract archive tar xzf "$archive" -C "$tmpdir" 2>/dev/null # If content is at root (not in source/), move it into source/ if [ "$has_source" -eq 0 ]; then for item in "$tmpdir"/*; do [ "$item" = "$tmpdir/source" ] && continue mv "$item" "$tmpdir/source/" 2>/dev/null || true done fi # Add recipe.toml if missing if [ "$has_recipe" -eq 0 ]; then cp "$recipe" "$tmpdir/recipe.toml" fi # Strip build artifacts rm -rf "$tmpdir/source/target" 2>/dev/null || true # Create new archive tar czf "$new_path" -C "$tmpdir" source recipe.toml 2>/dev/null if [ "$new_name" != "$name" ]; then rm -f "$archive" fi repaired=$((repaired + 1)) done # Update BLAKE3SUMS for repaired archives if [ "$DRY_RUN" -eq 0 ] && [ "$repaired" -gt 0 ]; then (cd "$POOL" && b3sum *.tar.gz 2>/dev/null) > "$POOL/../redbear-0.1.0/BLAKE3SUMS" fi rm -rf "$WORK" echo "" echo "=========================================" echo " Repair complete" echo " Repaired: $repaired" echo " Skipped: $skipped" echo "========================================="