7c7399e0a6
Add guard-recipes.sh with four modes: - --verify: check all local/recipes have correct symlinks into recipes/ - --fix: repair broken symlinks (run before builds) - --save-all: snapshot all recipe.toml into local/recipes/ - --restore: recreate all symlinks from local/recipes/ (run after sync-upstream) Wired into apply-patches.sh (post-patch) and sync-upstream.sh (post-sync). This prevents the build system from deleting recipe files during cargo cook, make distclean, or upstream source refresh.
360 lines
16 KiB
Bash
Executable File
360 lines
16 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# apply-patches.sh — Apply all Red Bear OS overlays on top of upstream Redox build system.
|
|
#
|
|
# Usage: ./local/scripts/apply-patches.sh [--force] [--dry-run]
|
|
#
|
|
# This script:
|
|
# 1. Applies build-system patches (rebranding, cookbook fixes, config, docs)
|
|
# 2. Ensures recipe patches are symlinked from local/patches/
|
|
# 3. Ensures custom recipe symlinks exist in recipes/
|
|
#
|
|
# WIP policy note:
|
|
# If upstream work is still under recipes/wip/, Red Bear may still ship from local/recipes/
|
|
# instead. This script therefore treats the local overlay as the durable source of truth.
|
|
#
|
|
# With --force: reapplies even if patches appear already applied.
|
|
# With --dry-run: shows what would change without making changes.
|
|
#
|
|
# SAFE: does not touch local/ directory. Only modifies upstream files.
|
|
|
|
set -euo pipefail
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
|
PATCHES_DIR="$REPO_ROOT/local/patches"
|
|
FORCE=""
|
|
DRY_RUN=0
|
|
|
|
cd "$REPO_ROOT"
|
|
|
|
# ── Helper ──────────────────────────────────────────────────────────
|
|
usage() {
|
|
cat <<'EOF'
|
|
Usage: ./local/scripts/apply-patches.sh [--force] [--dry-run]
|
|
|
|
Options:
|
|
--force attempt re-application even when checks fail
|
|
--dry-run show what would change without modifying files
|
|
EOF
|
|
}
|
|
|
|
for arg in "$@"; do
|
|
case "$arg" in
|
|
--force) FORCE="--force" ;;
|
|
--dry-run) DRY_RUN=1 ;;
|
|
-h|--help)
|
|
usage
|
|
exit 0
|
|
;;
|
|
*)
|
|
usage
|
|
exit 1
|
|
;;
|
|
esac
|
|
done
|
|
|
|
symlink() {
|
|
local target="$1" link="$2"
|
|
if [ -L "$link" ]; then
|
|
current="$(readlink "$link")"
|
|
if [ "$current" = "$target" ]; then
|
|
return 0 # already correct
|
|
fi
|
|
fi
|
|
if [ "$DRY_RUN" = "1" ]; then
|
|
dry_run_msg "would remove and relink $link -> $target"
|
|
return 0
|
|
fi
|
|
rm -f "$link"
|
|
ln -s "$target" "$link"
|
|
echo " linked $link -> $target"
|
|
}
|
|
|
|
dry_run_msg() {
|
|
if [ "$DRY_RUN" = "1" ]; then
|
|
echo " [dry-run] $*"
|
|
fi
|
|
}
|
|
|
|
# ── 1. Build-system patches ─────────────────────────────────────────
|
|
echo "==> Applying build-system patches..."
|
|
for patch_file in "$PATCHES_DIR"/build-system/[0-9]*.patch; do
|
|
[ -f "$patch_file" ] || continue
|
|
patch_name="$(basename "$patch_file")"
|
|
|
|
# Check if patch applies cleanly
|
|
if ! git apply --check "$patch_file" 2>/dev/null; then
|
|
# Patch does NOT apply cleanly — check if it's already applied
|
|
if git apply --reverse --check "$patch_file" 2>/dev/null; then
|
|
echo " SKIP $patch_name (already applied)"
|
|
continue
|
|
fi
|
|
|
|
# Reverse-check failed — maybe working tree diverged but patch is
|
|
# effectively applied. Use signature markers for robustness.
|
|
already_applied=0
|
|
case "$patch_name" in
|
|
001-rebrand-and-build.patch)
|
|
grep -q 'Red Bear OS' Makefile 2>/dev/null && already_applied=1
|
|
;;
|
|
002-cookbook-fixes.patch)
|
|
grep -q 'redbear_cookbook' Cargo.toml 2>/dev/null \
|
|
&& grep -q 'redbear_protected_recipe' src/cook/fetch.rs 2>/dev/null \
|
|
&& already_applied=1
|
|
;;
|
|
003-config.patch)
|
|
grep -q 'redbear-full' config/redbear-full.toml 2>/dev/null && already_applied=1
|
|
;;
|
|
004-docs-and-cleanup.patch)
|
|
grep -q 'Red Bear OS' README.md 2>/dev/null && already_applied=1
|
|
;;
|
|
005-qtbase-toolchain-elf-header.patch)
|
|
# This patch touches recipes/libs/qtbase; check for our marker
|
|
grep -q 'REDBEAR' recipes/libs/qtbase/recipe.toml 2>/dev/null && already_applied=1
|
|
;;
|
|
esac
|
|
if [ "$already_applied" -eq 1 ]; then
|
|
echo " SKIP $patch_name (already applied via signature marker)"
|
|
continue
|
|
fi
|
|
|
|
# Patch conflicts and is NOT already applied — this is a real problem
|
|
echo " FAIL $patch_name — conflicts with current tree"
|
|
echo " This likely means upstream has changed the target files."
|
|
echo " Patch file: $patch_file"
|
|
echo " Options:"
|
|
echo " 1. Resolve conflicts: edit the patch file to match new upstream"
|
|
echo " 2. Use --force to attempt re-application (may fail)"
|
|
if [ "$FORCE" != "--force" ]; then
|
|
echo " ABORT: unresolved patch conflict (use --force to override)"
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
if [ "$DRY_RUN" = "1" ]; then
|
|
dry_run_msg "would apply $patch_name"
|
|
continue
|
|
fi
|
|
|
|
if git apply --whitespace=nowarn "$patch_file"; then
|
|
echo " OK $patch_name"
|
|
else
|
|
echo " FAIL $patch_name — apply failed (check conflicts above)"
|
|
echo " Patch file: $patch_file"
|
|
exit 1
|
|
fi
|
|
done
|
|
|
|
# ── 2. Recipe patches (kernel, base) ───────────────────────────────
|
|
echo "==> Linking recipe patches from local/patches/..."
|
|
symlink "../../../local/patches/kernel/redox.patch" "recipes/core/kernel/redox.patch"
|
|
symlink "../../../local/patches/base/redox.patch" "recipes/core/base/redox.patch"
|
|
symlink "../../../local/patches/base/P2-boot-runtime-fixes.patch" "recipes/core/base/P2-boot-runtime-fixes.patch"
|
|
|
|
# ── 3. Custom recipe symlinks ──────────────────────────────────────
|
|
echo "==> Linking custom recipes from local/recipes/..."
|
|
|
|
# Branding
|
|
mkdir -p recipes/branding
|
|
symlink "../../local/recipes/branding/redbear-release" "recipes/branding/redbear-release"
|
|
|
|
# Drivers
|
|
mkdir -p recipes/drivers
|
|
symlink "../../local/recipes/drivers/linux-kpi" "recipes/drivers/linux-kpi"
|
|
symlink "../../local/recipes/drivers/redbear-btusb" "recipes/drivers/redbear-btusb"
|
|
symlink "../../local/recipes/drivers/redbear-iwlwifi" "recipes/drivers/redbear-iwlwifi"
|
|
symlink "../../local/recipes/drivers/redox-driver-sys" "recipes/drivers/redox-driver-sys"
|
|
|
|
# GPU
|
|
mkdir -p recipes/gpu
|
|
symlink "../../local/recipes/gpu/amdgpu" "recipes/gpu/amdgpu"
|
|
symlink "../../local/recipes/gpu/redox-drm" "recipes/gpu/redox-drm"
|
|
|
|
# Library stubs / custom libs
|
|
mkdir -p recipes/libs
|
|
symlink "../../local/recipes/libs/libqrencode" "recipes/libs/libqrencode"
|
|
symlink "../../local/recipes/libs/libepoxy-stub" "recipes/libs/libepoxy-stub"
|
|
symlink "../../local/recipes/libs/libudev-stub" "recipes/libs/libudev-stub"
|
|
symlink "../../local/recipes/libs/lcms2-stub" "recipes/libs/lcms2-stub"
|
|
symlink "../../local/recipes/libs/libdisplay-info-stub" "recipes/libs/libdisplay-info-stub"
|
|
symlink "../../local/recipes/libs/libxcvt-stub" "recipes/libs/libxcvt-stub"
|
|
symlink "../../local/recipes/libs/zbus" "recipes/libs/zbus"
|
|
|
|
# System
|
|
mkdir -p recipes/system
|
|
symlink "../../local/recipes/system/cub" "recipes/system/cub"
|
|
symlink "../../local/recipes/system/evdevd" "recipes/system/evdevd"
|
|
symlink "../../local/recipes/system/redbear-firmware" "recipes/system/redbear-firmware"
|
|
symlink "../../local/recipes/system/firmware-loader" "recipes/system/firmware-loader"
|
|
symlink "../../local/recipes/system/iommu" "recipes/system/iommu"
|
|
symlink "../../local/recipes/system/redbear-hwutils" "recipes/system/redbear-hwutils"
|
|
symlink "../../local/recipes/system/redbear-info" "recipes/system/redbear-info"
|
|
symlink "../../local/recipes/system/redbear-btctl" "recipes/system/redbear-btctl"
|
|
symlink "../../local/recipes/system/redbear-netstat" "recipes/system/redbear-netstat"
|
|
symlink "../../local/recipes/system/redbear-netctl" "recipes/system/redbear-netctl"
|
|
symlink "../../local/recipes/system/redbear-netctl-console" "recipes/system/redbear-netctl-console"
|
|
symlink "../../local/recipes/system/redbear-wifictl" "recipes/system/redbear-wifictl"
|
|
symlink "../../local/recipes/system/redbear-traceroute" "recipes/system/redbear-traceroute"
|
|
symlink "../../local/recipes/system/redbear-mtr" "recipes/system/redbear-mtr"
|
|
symlink "../../local/recipes/system/redbear-nmap" "recipes/system/redbear-nmap"
|
|
symlink "../../local/recipes/system/redbear-meta" "recipes/system/redbear-meta"
|
|
symlink "../../local/recipes/system/udev-shim" "recipes/system/udev-shim"
|
|
symlink "../../local/recipes/system/redbear-sessiond" "recipes/system/redbear-sessiond"
|
|
symlink "../../local/recipes/system/redbear-authd" "recipes/system/redbear-authd"
|
|
symlink "../../local/recipes/system/redbear-session-launch" "recipes/system/redbear-session-launch"
|
|
symlink "../../local/recipes/system/redbear-greeter" "recipes/system/redbear-greeter"
|
|
symlink "../../local/recipes/system/redbear-dbus-services" "recipes/system/redbear-dbus-services"
|
|
symlink "../../local/recipes/system/redbear-notifications" "recipes/system/redbear-notifications"
|
|
symlink "../../local/recipes/system/redbear-upower" "recipes/system/redbear-upower"
|
|
symlink "../../local/recipes/system/redbear-udisks" "recipes/system/redbear-udisks"
|
|
symlink "../../local/recipes/system/redbear-polkit" "recipes/system/redbear-polkit"
|
|
|
|
# Core additions
|
|
mkdir -p recipes/core
|
|
symlink "../../local/recipes/core/ext4d" "recipes/core/ext4d"
|
|
symlink "../../local/recipes/core/grub" "recipes/core/grub"
|
|
|
|
# Resolve WIP conflict: recipes/wip/services/grub also exists,
|
|
# so redirect the entire directory to our local overlay to ensure
|
|
# COOKBOOK_RECIPE resolves to a directory that contains grub.cfg
|
|
if [ -d "recipes/wip/services/grub" ] && [ ! -L "recipes/wip/services/grub" ]; then
|
|
backup_name="recipes/wip/services/grub.upstream-backup-$(date +%Y%m%d-%H%M%S)"
|
|
if [ "$DRY_RUN" = "1" ]; then
|
|
dry_run_msg "would backup recipes/wip/services/grub to $backup_name and replace with symlink"
|
|
else
|
|
echo " backing up upstream recipes/wip/services/grub -> $backup_name"
|
|
mv "recipes/wip/services/grub" "$backup_name"
|
|
fi
|
|
fi
|
|
if [ ! -e "recipes/wip/services/grub" ]; then
|
|
symlink "../../../local/recipes/core/grub" "recipes/wip/services/grub"
|
|
fi
|
|
|
|
# Wayland additions
|
|
mkdir -p recipes/wip/wayland
|
|
symlink "../../../local/recipes/wayland/qt6-wayland-smoke" "recipes/wip/wayland/qt6-wayland-smoke"
|
|
|
|
# KDE / Phase 6 recipes
|
|
mkdir -p recipes/kde
|
|
symlink "../../local/recipes/kde/plasma-desktop" "recipes/kde/plasma-desktop"
|
|
symlink "../../local/recipes/kde/plasma-workspace" "recipes/kde/plasma-workspace"
|
|
symlink "../../local/recipes/kde/plasma-framework" "recipes/kde/plasma-framework"
|
|
symlink "../../local/recipes/kde/plasma-wayland-protocols" "recipes/kde/plasma-wayland-protocols"
|
|
symlink "../../local/recipes/kde/kwin" "recipes/kde/kwin"
|
|
symlink "../../local/recipes/kde/kirigami" "recipes/kde/kirigami"
|
|
symlink "../../local/recipes/kde/kirigami" "recipes/kde/kf6-kirigami"
|
|
symlink "../../local/recipes/kde/kdecoration" "recipes/kde/kdecoration"
|
|
symlink "../../local/recipes/kde/kf6-extra-cmake-modules" "recipes/kde/kf6-extra-cmake-modules"
|
|
symlink "../../local/recipes/kde/kf6-kcoreaddons" "recipes/kde/kf6-kcoreaddons"
|
|
symlink "../../local/recipes/kde/kf6-kwidgetsaddons" "recipes/kde/kf6-kwidgetsaddons"
|
|
symlink "../../local/recipes/kde/kf6-kconfig" "recipes/kde/kf6-kconfig"
|
|
symlink "../../local/recipes/kde/kf6-ki18n" "recipes/kde/kf6-ki18n"
|
|
symlink "../../local/recipes/kde/kf6-kcodecs" "recipes/kde/kf6-kcodecs"
|
|
symlink "../../local/recipes/kde/kf6-kguiaddons" "recipes/kde/kf6-kguiaddons"
|
|
symlink "../../local/recipes/kde/kf6-kcolorscheme" "recipes/kde/kf6-kcolorscheme"
|
|
symlink "../../local/recipes/kde/kf6-kauth" "recipes/kde/kf6-kauth"
|
|
symlink "../../local/recipes/kde/kf6-kitemmodels" "recipes/kde/kf6-kitemmodels"
|
|
symlink "../../local/recipes/kde/kf6-kitemviews" "recipes/kde/kf6-kitemviews"
|
|
symlink "../../local/recipes/kde/kf6-karchive" "recipes/kde/kf6-karchive"
|
|
symlink "../../local/recipes/kde/kf6-kwindowsystem" "recipes/kde/kf6-kwindowsystem"
|
|
symlink "../../local/recipes/kde/kf6-knotifications" "recipes/kde/kf6-knotifications"
|
|
symlink "../../local/recipes/kde/kf6-kjobwidgets" "recipes/kde/kf6-kjobwidgets"
|
|
symlink "../../local/recipes/kde/kf6-kconfigwidgets" "recipes/kde/kf6-kconfigwidgets"
|
|
symlink "../../local/recipes/kde/kf6-kcrash" "recipes/kde/kf6-kcrash"
|
|
symlink "../../local/recipes/kde/kf6-kdbusaddons" "recipes/kde/kf6-kdbusaddons"
|
|
symlink "../../local/recipes/kde/kf6-kglobalaccel" "recipes/kde/kf6-kglobalaccel"
|
|
symlink "../../local/recipes/kde/kf6-kservice" "recipes/kde/kf6-kservice"
|
|
symlink "../../local/recipes/kde/kf6-kpackage" "recipes/kde/kf6-kpackage"
|
|
symlink "../../local/recipes/kde/kf6-kiconthemes" "recipes/kde/kf6-kiconthemes"
|
|
symlink "../../local/recipes/kde/kf6-kxmlgui" "recipes/kde/kf6-kxmlgui"
|
|
symlink "../../local/recipes/kde/kf6-ktextwidgets" "recipes/kde/kf6-ktextwidgets"
|
|
symlink "../../local/recipes/kde/kf6-solid" "recipes/kde/kf6-solid"
|
|
symlink "../../local/recipes/kde/kf6-sonnet" "recipes/kde/kf6-sonnet"
|
|
symlink "../../local/recipes/kde/kf6-kio" "recipes/kde/kf6-kio"
|
|
symlink "../../local/recipes/kde/kf6-kbookmarks" "recipes/kde/kf6-kbookmarks"
|
|
symlink "../../local/recipes/kde/kf6-kcompletion" "recipes/kde/kf6-kcompletion"
|
|
symlink "../../local/recipes/kde/kf6-kdeclarative" "recipes/kde/kf6-kdeclarative"
|
|
symlink "../../local/recipes/kde/kf6-kcmutils" "recipes/kde/kf6-kcmutils"
|
|
symlink "../../local/recipes/kde/kf6-kidletime" "recipes/kde/kf6-kidletime"
|
|
symlink "../../local/recipes/kde/kf6-kwayland" "recipes/kde/kf6-kwayland"
|
|
symlink "../../local/recipes/kde/kf6-knewstuff" "recipes/kde/kf6-knewstuff"
|
|
symlink "../../local/recipes/kde/kf6-kwallet" "recipes/kde/kf6-kwallet"
|
|
symlink "../../local/recipes/kde/kf6-prison" "recipes/kde/kf6-prison"
|
|
|
|
# ── 4. New files not in upstream ────────────────────────────────────
|
|
echo "==> Ensuring Red Bear OS-specific files exist..."
|
|
|
|
# redbear.ipxe (network boot)
|
|
if [ ! -f redbear.ipxe ] && [ ! -L redbear.ipxe ]; then
|
|
if [ "$DRY_RUN" = "1" ]; then
|
|
dry_run_msg "would create redbear.ipxe"
|
|
else
|
|
cat > redbear.ipxe <<'IPXE'
|
|
#!ipxe
|
|
|
|
kernel bootloader-live.efi
|
|
initrd http://${next-server}:8080/redbear-live.iso
|
|
boot
|
|
IPXE
|
|
echo " created redbear.ipxe"
|
|
fi
|
|
fi
|
|
|
|
# redbear-full config (not in upstream)
|
|
if [ ! -f config/redbear-full.toml ] && [ ! -L config/redbear-full.toml ]; then
|
|
if [ "$DRY_RUN" = "1" ]; then
|
|
dry_run_msg "would create config/redbear-full.toml"
|
|
else
|
|
cat > config/redbear-full.toml <<'TOML'
|
|
# Red Bear OS Full Configuration
|
|
# Complete desktop + all Red Bear OS custom drivers and tools
|
|
#
|
|
# Build: make all CONFIG_NAME=redbear-full
|
|
# Live: make live CONFIG_NAME=redbear-live-full
|
|
|
|
include = ["desktop.toml"]
|
|
|
|
[general]
|
|
# 2GB filesystem — plenty for full desktop + drivers
|
|
# (desktop.toml sets 650MB, but we want headroom for our custom packages)
|
|
filesystem_size = 2048
|
|
|
|
[packages]
|
|
# Red Bear OS branding (os-release, hostname, motd)
|
|
redbear-release = {}
|
|
|
|
# ext4 filesystem support (our custom port)
|
|
ext4d = {}
|
|
|
|
# Red Bear OS driver infrastructure
|
|
redox-driver-sys = {}
|
|
linux-kpi = {}
|
|
firmware-loader = {}
|
|
|
|
# Input layer
|
|
evdevd = {}
|
|
udev-shim = {}
|
|
|
|
# GPU driver (AMD — modesetting display core)
|
|
redox-drm = {}
|
|
amdgpu = {}
|
|
|
|
# Red Bear OS meta-package (dependencies, default config)
|
|
redbear-meta = {}
|
|
TOML
|
|
echo " created config/redbear-full.toml"
|
|
fi
|
|
else
|
|
echo " config/redbear-full.toml already exists — not overwriting"
|
|
fi
|
|
|
|
echo ""
|
|
echo "==> All Red Bear OS patches applied. Ready to build."
|
|
if [ "$DRY_RUN" = "1" ]; then
|
|
echo " [dry-run mode — no changes were made]"
|
|
fi
|
|
echo ""
|
|
echo "==> Guarding recipe durability..."
|
|
./local/scripts/guard-recipes.sh --fix 2>/dev/null || echo " (guard-recipes.sh not found — run manually)"
|
|
echo " make all CONFIG_NAME=redbear-full"
|