6a7abe0b87
Add local/scripts/cleanup-build.sh - a git-aware cleanup script that uses 'git ls-files' to whitelist tracked files before deletion. Prevents the class of cleanup disasters that deleted local recipe sources and local fork sources. Update AGENTS.md with the new safe cleanup procedure. Update CONSOLE-TO-KDE-DESKTOP-PLAN.md to v5.8 with the qtdeclarative qfeatures.h fix and the new safe cleanup script.
152 lines
5.1 KiB
Bash
Executable File
152 lines
5.1 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Safe cleanup for Red Bear OS build artifacts.
|
|
#
|
|
# This script removes ONLY build artifacts. It NEVER touches:
|
|
# - Tracked source files in local/recipes/*/source/
|
|
# - Tracked source files in local/sources/
|
|
# - Tracked patches in local/patches/
|
|
# - Tracked docs in local/docs/
|
|
# - Any file tracked by git
|
|
#
|
|
# Usage:
|
|
# ./local/scripts/cleanup-build.sh # Remove build artifacts only
|
|
# ./local/scripts/cleanup-build.sh --all # Remove all artifacts including sources/
|
|
# ./local/scripts/cleanup-build.sh --nuclear # Remove everything including target/ in local/
|
|
#
|
|
# SAFETY: Every deletion is checked against `git ls-files` before removing.
|
|
# If a path is tracked by git, it is SKIPPED with a warning.
|
|
|
|
set -euo pipefail
|
|
|
|
COOKBOOK_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
|
cd "${COOKBOOK_ROOT}"
|
|
|
|
MODE="${1:-artifacts}"
|
|
case "${MODE}" in
|
|
artifacts) REMOVE_TARGETS=1; REMOVE_SOURCES=0; REMOVE_LOCAL_TARGETS=0 ;;
|
|
--all) REMOVE_TARGETS=1; REMOVE_SOURCES=1; REMOVE_LOCAL_TARGETS=0 ;;
|
|
--nuclear) REMOVE_TARGETS=1; REMOVE_SOURCES=1; REMOVE_LOCAL_TARGETS=1 ;;
|
|
*)
|
|
echo "Usage: $0 [artifacts|--all|--nuclear]" >&2
|
|
echo " artifacts (default) Remove only build/ and repo/" >&2
|
|
echo " --all Also remove recipe target/ directories (forces full rebuild)" >&2
|
|
echo " --nuclear Also remove local/recipes/*/target/ (DANGEROUS - local sources may be wiped)" >&2
|
|
exit 1
|
|
;;
|
|
esac
|
|
|
|
# Safety: refuse to run if we're not in a git repo
|
|
if ! git rev-parse --git-dir > /dev/null 2>&1; then
|
|
echo "ERROR: Not in a git repository. Aborting for safety." >&2
|
|
exit 1
|
|
fi
|
|
|
|
# Counters
|
|
removed=0
|
|
skipped=0
|
|
protected=0
|
|
|
|
# Function: safely remove a path if it exists and is NOT tracked by git
|
|
safe_remove() {
|
|
local path="$1"
|
|
if [ ! -e "${path}" ]; then
|
|
return 0
|
|
fi
|
|
# Check if the path is tracked by git
|
|
if git ls-files --error-unmatch "${path}" > /dev/null 2>&1; then
|
|
echo "PROTECTED: ${path} is tracked by git, skipping" >&2
|
|
protected=$((protected + 1))
|
|
return 0
|
|
fi
|
|
echo "Removing: ${path}"
|
|
rm -rf "${path}"
|
|
removed=$((removed + 1))
|
|
}
|
|
|
|
# Function: safely remove all contents of a directory except tracked files
|
|
safe_clean_dir() {
|
|
local dir="$1"
|
|
if [ ! -d "${dir}" ]; then
|
|
return 0
|
|
fi
|
|
# Find all entries in the directory
|
|
while IFS= read -r -d '' entry; do
|
|
local relpath="${entry#${COOKBOOK_ROOT}/}"
|
|
if git ls-files --error-unmatch "${relpath}" > /dev/null 2>&1; then
|
|
echo "PROTECTED: ${relpath} is tracked by git, skipping" >&2
|
|
protected=$((protected + 1))
|
|
else
|
|
echo "Removing: ${relpath}"
|
|
rm -rf "${entry}"
|
|
removed=$((removed + 1))
|
|
fi
|
|
done < <(find "${dir}" -mindepth 1 -maxdepth 1 -print0)
|
|
}
|
|
|
|
echo "=== Red Bear OS Safe Cleanup ==="
|
|
echo "Mode: ${MODE}"
|
|
echo "Repository: ${COOKBOOK_ROOT}"
|
|
echo ""
|
|
|
|
# Always safe: build artifacts
|
|
echo "--- Removing build artifacts ---"
|
|
safe_remove "build/"
|
|
safe_remove "repo/"
|
|
|
|
if [ "${REMOVE_TARGETS}" -eq 1 ]; then
|
|
echo ""
|
|
echo "--- Removing recipe target/ directories ---"
|
|
# Remove target/ from each recipe, but only if not tracked
|
|
if [ -d "recipes" ]; then
|
|
safe_clean_dir "recipes"
|
|
fi
|
|
if [ -d "local/recipes" ]; then
|
|
# For local recipes, we need special handling: target/ is safe to remove
|
|
# but source/ must be preserved
|
|
while IFS= read -r -d '' recipe_dir; do
|
|
if [ -d "${recipe_dir}/target" ]; then
|
|
safe_remove "${recipe_dir}/target"
|
|
fi
|
|
done < <(find "local/recipes" -mindepth 2 -maxdepth 2 -type d -name "target" -print0 2>/dev/null)
|
|
fi
|
|
fi
|
|
|
|
if [ "${REMOVE_SOURCES}" -eq 1 ]; then
|
|
echo ""
|
|
echo "--- WARNING: Removing recipe source/ directories ---"
|
|
echo "--- This will force re-download of all upstream sources ---"
|
|
if [ -d "recipes" ]; then
|
|
while IFS= read -r -d '' source_dir; do
|
|
safe_remove "${source_dir}"
|
|
done < <(find "recipes" -mindepth 2 -maxdepth 2 -type d -name "source" -print0 2>/dev/null)
|
|
fi
|
|
fi
|
|
|
|
if [ "${REMOVE_LOCAL_TARGETS}" -eq 1 ]; then
|
|
echo ""
|
|
echo "--- NUCLEAR: Removing local/recipes/*/target/ ---"
|
|
if [ -d "local/recipes" ]; then
|
|
while IFS= read -r -d '' target_dir; do
|
|
safe_remove "${target_dir}"
|
|
done < <(find "local/recipes" -mindepth 2 -maxdepth 2 -type d -name "target" -print0 2>/dev/null)
|
|
fi
|
|
# Also remove local/sources/*/target if they exist
|
|
if [ -d "local/sources" ]; then
|
|
while IFS= read -r -d '' target_dir; do
|
|
safe_remove "${target_dir}"
|
|
done < <(find "local/sources" -mindepth 2 -maxdepth 2 -type d -name "target" -print0 2>/dev/null)
|
|
fi
|
|
fi
|
|
|
|
echo ""
|
|
echo "=== Summary ==="
|
|
echo "Removed: ${removed} paths"
|
|
echo "Skipped: ${skipped} paths (not found)"
|
|
echo "Protected: ${protected} paths (tracked by git, NOT removed)"
|
|
|
|
if [ "${protected}" -gt 0 ]; then
|
|
echo ""
|
|
echo "NOTE: Some paths were protected because they are tracked by git."
|
|
echo "If you need to remove tracked files, use 'git rm' explicitly."
|
|
fi
|