b9874d0941
Add redbear-usb-storage-check in-guest binary that validates USB mass storage read and write I/O: discovers /scheme/disk/ devices, writes a test pattern to sector 2048, reads it back, verifies match, restores original content. Updates test-usb-storage-qemu.sh with write-proof verification step. Includes all accumulated Red Bear OS work: kernel patches, relibc patches, driver infrastructure, DRM/GPU, KDE recipes, firmware, validation tooling, build system hardening, and documentation.
124 lines
3.6 KiB
Bash
Executable File
124 lines
3.6 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# validate-patches.sh — Check that all recipe patches apply cleanly.
|
|
#
|
|
# Usage: ./local/scripts/validate-patches.sh [--rebase] [recipe...]
|
|
#
|
|
# Without arguments, validates all recipes with patches.
|
|
# With --rebase, runs patch --dry-run -R to check if the patch can
|
|
# be reverse-applied (meaning it IS currently applied).
|
|
# With recipe names/paths, validates only those recipes.
|
|
#
|
|
# Exit code: number of failed patches (0 = all clean).
|
|
|
|
set -euo pipefail
|
|
|
|
ROOT="$(cd "$(dirname "$0")/../.." && pwd)"
|
|
cd "$ROOT"
|
|
|
|
MODE="apply" # apply | rebase
|
|
FAILED=0
|
|
CHECKED=0
|
|
TOTAL_PATCHES=0
|
|
|
|
red() { printf "\033[1;31m%s\033[0m\n" "$*"; }
|
|
green(){ printf "\033[1;32m%s\033[0m\n" "$*"; }
|
|
cyan() { printf "\033[1;36m%s\033[0m\n" "$*"; }
|
|
|
|
while [[ $# -gt 0 ]]; do
|
|
case "$1" in
|
|
--rebase) MODE="rebase"; shift ;;
|
|
*) break ;;
|
|
esac
|
|
done
|
|
|
|
RECIPE_DIRS=("$@")
|
|
if [ ${#RECIPE_DIRS[@]} -eq 0 ]; then
|
|
mapfile -t RECIPE_DIRS < <(find recipes -name "recipe.toml" -exec dirname {} \; | sort)
|
|
fi
|
|
|
|
validate_patch() {
|
|
local recipe_dir="$1"
|
|
local patch_name="$2"
|
|
local patch_file="$3"
|
|
local source_dir="$4"
|
|
|
|
local flags="--strip=1 --batch --fuzz=0"
|
|
if [ "$MODE" = "rebase" ]; then
|
|
# Check if patch can be reverse-applied (it IS currently applied)
|
|
if patch --dry-run --directory "$source_dir" $flags -R < "$patch_file" >/dev/null 2>&1; then
|
|
return 0 # already applied → OK
|
|
else
|
|
echo " $(red NEEDS REBASE) $patch_name"
|
|
FAILED=$((FAILED + 1))
|
|
return 1
|
|
fi
|
|
fi
|
|
|
|
# Forward-apply check
|
|
if patch --dry-run --directory "$source_dir" $flags < "$patch_file" >/dev/null 2>&1; then
|
|
return 0
|
|
fi
|
|
|
|
# Show the actual error for diagnosis
|
|
echo " $(red FAILED) $patch_name"
|
|
patch --dry-run --directory "$source_dir" $flags < "$patch_file" 2>&1 | head -5 | sed 's/^/ /'
|
|
FAILED=$((FAILED + 1))
|
|
return 1
|
|
}
|
|
|
|
for recipe_dir in "${RECIPE_DIRS[@]}"; do
|
|
recipe_toml="$recipe_dir/recipe.toml"
|
|
[ -f "$recipe_toml" ] || continue
|
|
|
|
# Extract patch list from recipe.toml
|
|
patches=$(grep -o '"[^"]*\.patch"' "$recipe_toml" 2>/dev/null | tr -d '"')
|
|
|
|
[ -n "$patches" ] || continue
|
|
|
|
source_dir="$recipe_dir/source"
|
|
if [ ! -d "$source_dir" ]; then
|
|
echo "$(cyan SKIP) $recipe_dir — no source directory"
|
|
continue
|
|
fi
|
|
|
|
recipe_failed=0
|
|
recipe_checked=0
|
|
|
|
for patch_name in $patches; do
|
|
# Resolve patch file path (handle relative paths like ../../../local/patches/...)
|
|
patch_file="$recipe_dir/$patch_name"
|
|
if [ ! -f "$patch_file" ]; then
|
|
echo " $(red MISSING) $patch_name ($patch_file)"
|
|
FAILED=$((FAILED + 1))
|
|
continue
|
|
fi
|
|
|
|
recipe_checked=$((recipe_checked + 1))
|
|
TOTAL_PATCHES=$((TOTAL_PATCHES + 1))
|
|
|
|
validate_patch "$recipe_dir" "$patch_name" "$patch_file" "$source_dir" || true
|
|
done
|
|
|
|
if [ "$recipe_checked" -gt 0 ]; then
|
|
CHECKED=$((CHECKED + 1))
|
|
if [ "$recipe_failed" -eq 0 ]; then
|
|
echo "$(green OK) $recipe_dir — $recipe_checked patch(es) clean"
|
|
fi
|
|
fi
|
|
done
|
|
|
|
echo ""
|
|
echo "──────────────────────────────────────────"
|
|
echo " Recipes checked: $CHECKED"
|
|
echo " Total patches: $TOTAL_PATCHES"
|
|
echo " Failed: $FAILED"
|
|
echo "──────────────────────────────────────────"
|
|
|
|
if [ "$FAILED" -eq 0 ]; then
|
|
echo "$(green All patches apply cleanly)"
|
|
else
|
|
red "$FAILED patch(es) need rebasing or fixing"
|
|
fi
|
|
|
|
exit $FAILED
|