feat: build system hardening — collision detection, validation gates, init path enforcement
5-phase hardening to prevent silent file-layer collisions (the D-Bus regression class): Phase 1: lint-config-paths.sh + make lint-config in depends.mk Phase 2: CollisionTracker in installer (content-hash comparison) Phase 3: installs manifests in recipe.toml + validate-file-ownership.sh Phase 4: validate-init-services.sh + make validate in disk.mk Phase 5: documentation (AGENTS.md, BUILD-SYSTEM-HARDENING-PLAN.md) Both redbear-mini and redbear-full build and validate clean. 66 declared install paths in base, zero conflicts.
This commit is contained in:
Executable
+74
@@ -0,0 +1,74 @@
|
||||
#!/bin/bash
|
||||
# generate-installs-manifest.sh — Inspect recipe stage directory and output
|
||||
# suggested `installs = [...]` declarations for recipe.toml
|
||||
#
|
||||
# Usage:
|
||||
# scripts/generate-installs-manifest.sh <recipe-name>
|
||||
# scripts/generate-installs-manifest.sh base
|
||||
# scripts/generate-installs-manifest.sh evdevd
|
||||
#
|
||||
# The script examines the recipe's stage directory after a successful build
|
||||
# and lists all installed files relative to the sysroot root.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
if [ $# -lt 1 ]; then
|
||||
echo "Usage: $0 <recipe-name>" >&2
|
||||
echo " Inspects the recipe's stage directory and outputs suggested installs = [...]" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
RECIPE_NAME="$1"
|
||||
|
||||
# Find the recipe directory
|
||||
RECIPE_DIR=""
|
||||
for category_dir in recipes/*/; do
|
||||
if [ -d "${category_dir}${RECIPE_NAME}" ]; then
|
||||
RECIPE_DIR="${category_dir}${RECIPE_NAME}"
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if [ -z "$RECIPE_DIR" ]; then
|
||||
echo "ERROR: Recipe '$RECIPE_NAME' not found in recipes/*/" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Determine target architecture
|
||||
source mk/config.mk 2>/dev/null || true
|
||||
TARGET_ARCH="${ARCH:-x86_64}"
|
||||
STAGE_DIR="${RECIPE_DIR}/target/${TARGET_ARCH}-unknown-redox/stage"
|
||||
|
||||
if [ ! -d "$STAGE_DIR" ]; then
|
||||
STAGE_DIR="${RECIPE_DIR}/target/${TARGET_ARCH}-unknown-redox/stage.tmp"
|
||||
fi
|
||||
|
||||
if [ ! -d "$STAGE_DIR" ]; then
|
||||
echo "ERROR: Stage directory not found: $STAGE_DIR" >&2
|
||||
echo " Build the recipe first: ./target/release/repo cook $RECIPE_DIR" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "# Generated installs manifest for $RECIPE_NAME"
|
||||
echo "# Recipe: $RECIPE_DIR"
|
||||
echo "# Stage: $STAGE_DIR"
|
||||
echo ""
|
||||
echo "[package]"
|
||||
|
||||
# Collect all files, sorted
|
||||
FILES=$(cd "$STAGE_DIR" && find . -type f -o -type l | sed 's|^\./||' | sort)
|
||||
|
||||
if [ -z "$FILES" ]; then
|
||||
echo "# No files found in stage directory"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "installs = ["
|
||||
while IFS= read -r file; do
|
||||
echo " \"/${file}\","
|
||||
done <<< "$FILES"
|
||||
echo "]"
|
||||
|
||||
echo ""
|
||||
echo "# Total: $(echo "$FILES" | wc -l) files"
|
||||
echo "# To apply: copy the installs = [...] block into $RECIPE_DIR/recipe.toml"
|
||||
Reference in New Issue
Block a user