diff --git a/local/fork-upstream-map.toml b/local/fork-upstream-map.toml index 04176c2839..1e5b80c14e 100644 --- a/local/fork-upstream-map.toml +++ b/local/fork-upstream-map.toml @@ -19,6 +19,36 @@ redoxfs https://gitlab.redox-os.org/redox-os/redoxfs.git 0.9.0 redox-scheme https://gitlab.redox-os.org/redox-os/redox-scheme.git 0.11.2 relibc https://gitlab.redox-os.org/redox-os/relibc.git 0.2.5 kernel https://gitlab.redox-os.org/redox-os/kernel.git 0.5.12 -bootloader https://gitlab.redox-os.org/redox-os/bootloader.git 1.0.0 +# bootloader: KNOWN PENDING REBASE. +# +# The local fork claims to be `1.0.0-rb1` (i.e. upstream 1.0.0 + Red +# Bear patches) but the patches in `local/patches/bootloader/` do +# NOT apply cleanly to upstream 1.0.0 (verified by +# verify-fork-versions.sh). The fork was originally a 0.1.0 baseline +# with substantial Red Bear additions that pre-date the +# upstream-1.0.0 refactor (e.g. `src/arch/aarch64.rs` does not +# exist in upstream 1.0.0 — the patches reference files that +# upstream 1.0.0 doesn't have). +# +# TO REBASE: +# 1. Pick a clean upstream tag as the new base (likely the same +# 1.0.0 the label claims, or whatever tag matches the local +# patches' "before" state). +# 2. Reset the fork to that tag: `git reset --hard `. +# 3. Reapply each patch on top: `git apply local/patches/bootloader/*.patch`. +# Each patch must apply cleanly with `--fuzz=0` (no context drift). +# 4. For each patch that fails to apply, regenerate the patch from +# the CURRENT local state: `git diff ..HEAD -- path/to/file > patch`. +# 5. Once all patches apply cleanly, verify with +# `local/scripts/verify-fork-versions.sh`. +# 6. Commit the rebased state and push the new branch. +# +# Until that rebase is done, the bootloader fork is **fake-labelled** +# and the build will refuse to start (verify-fork-versions.sh +# exits 1). To proceed with builds, the user must either: +# (a) complete the rebase, OR +# (b) temporarily remove the `-rb1` from the version field AND +# remove bootloader from the build until it is fixed. +bootloader https://gitlab.redox-os.org/redox-os/bootloader.git PENDING_REBASE installer https://gitlab.redox-os.org/redox-os/installer.git 0.2.42 userutils https://gitlab.redox-os.org/redox-os/userutils.git 0.1.0 diff --git a/local/scripts/verify-fork-versions.sh b/local/scripts/verify-fork-versions.sh index 55ca1c4228..9df2524cdf 100755 --- a/local/scripts/verify-fork-versions.sh +++ b/local/scripts/verify-fork-versions.sh @@ -65,6 +65,19 @@ for fork_dir in local/sources/*/; do upstream_url=$(echo "$map_line" | awk '{print $2}') upstream_tag=$(echo "$map_line" | awk '{print $3}') + # If the upstream tag is `PENDING_REBASE` (used to mark a fork + # whose rebase is in progress), the build cannot proceed. Refuse + # with a clear error pointing the user to the rebase work. + if [ "$upstream_tag" = "PENDING_REBASE" ]; then + echo "ERROR: $fork_name is marked as PENDING_REBASE in $MAP_FILE." >&2 + echo " The local source does not match any single upstream" >&2 + echo " release. A real rebase onto a chosen upstream tag is" >&2 + echo " required. See the comment next to '$fork_name' in" >&2 + echo " $MAP_FILE for the rebase procedure." >&2 + violations=$((violations + 1)) + continue + fi + if [ "$upstream_tag" != "$base_version" ]; then echo "ERROR: $fork_name Cargo.toml declares version='$version'" >&2 echo " but the upstream map has it tracking upstream '$upstream_tag'." >&2 @@ -103,6 +116,37 @@ for fork_dir in local/sources/*/; do upstream_files=$(find . -type f -not -path './.git/*' -not -path './target/*' -not -path './Cargo.lock' | sort | sed 's|^\./||') cd "$ROOT/$fork_dir" + # Build the set of files that are EXPECTED to differ from upstream + # because of documented Red Bear patches. A file is "expected to + # differ" if it is touched by a patch in local/patches/$fork_name/. + # The verifier EXCLUDES these from the content diff so that a + # well-structured fork (with documented Red Bear patches) passes + # verification. + patch_dir="$ROOT/local/patches/$fork_name" + expected_differ=() + if [ -d "$patch_dir" ]; then + while IFS= read -r patch_file; do + [ -z "$patch_file" ] && continue + # `git apply --stat` lists files touched by the patch. + # Use the local fork's working-tree state to interpret the + # patch paths (since they are relative to the fork root). + while IFS= read -r f; do + [ -z "$f" ] && continue + # Normalize: strip leading 'a/' or 'b/' if present + f=$(echo "$f" | sed -E 's|^[ab]/||') + expected_differ+=("$f") + done < <(cd "$ROOT/$fork_dir" && git apply --stat "$patch_dir/$patch_file" 2>/dev/null \ + | tail -n +3 | head -n -2 | awk '{print $1}' | sort -u) + done < <(ls "$patch_dir" 2>/dev/null) + fi + # Deduplicate + expected_differ=($(printf '%s\n' "${expected_differ[@]}" | sort -u)) + # Always expect Cargo.toml and Cargo.toml.orig to differ (version field + # bump and auto-generated Cargo.toml are Red Bear bookkeeping). + expected_differ+=("Cargo.toml") + expected_differ+=("Cargo.toml.orig") + expected_differ=($(printf '%s\n' "${expected_differ[@]}" | sort -u)) + # Files in local but not in upstream: these are the Red Bear additions # (tracked by the local fork) OR untracked working-tree files (which # should not be present). Files in upstream but not in local: these @@ -111,6 +155,10 @@ for fork_dir in local/sources/*/; do only_upstream=$(comm -13 <(echo "$local_files") <(echo "$upstream_files")) if [ -n "$only_upstream" ]; then + # Filter out files that are EXPECTED to be absent (e.g. deleted + # by a Red Bear patch). For now, we treat all upstream-only files + # as errors — a future enhancement would parse the patch diffs + # to find deletions. echo "ERROR: $fork_name is missing files that exist in upstream $upstream_tag:" >&2 echo "$only_upstream" | sed 's/^/ /' >&2 echo " This fork claims to be '$upstream_tag' but is missing source." >&2 @@ -118,21 +166,39 @@ for fork_dir in local/sources/*/; do fi if [ -n "$only_local" ]; then - echo "ERROR: $fork_name has files that don't exist in upstream $upstream_tag:" >&2 - echo "$only_local" | sed 's/^/ /' | head -10 >&2 - count=$(echo "$only_local" | wc -l) - if [ "$count" -gt 10 ]; then - echo " ... and $((count - 10)) more" >&2 + # Filter out files in local/patches/$fork_name/ (patches + # themselves, README, etc.) — those are Red Bear bookkeeping, + # not source files. + local_non_patch=$(comm -23 <(echo "$local_files") \ + <(cd "$ROOT" && find "local/patches/$fork_name" -type f 2>/dev/null | \ + sed "s|^local/patches/$fork_name/||" | sort -u)) + if [ -n "$local_non_patch" ]; then + echo "ERROR: $fork_name has files that don't exist in upstream $upstream_tag:" >&2 + echo "$local_non_patch" | sed 's/^/ /' | head -10 >&2 + count=$(echo "$local_non_patch" | wc -l) + if [ "$count" -gt 10 ]; then + echo " ... and $((count - 10)) more" >&2 + fi + echo " These must be deleted or moved to local/patches/$fork_name/ as documented Red Bear patches." >&2 + violations=$((violations + 1)) fi - echo " These must be deleted or the version field updated." >&2 - violations=$((violations + 1)) fi - # Verify content of shared files + # Verify content of shared files. Skip files in expected_differ + # (files touched by documented Red Bear patches). diff_count=0 while IFS= read -r f; do [ -z "$f" ] && continue - if ! diff -q "$f" "/tmp/verify-$fork_name/$f" >/dev/null 2>&1; then + # Skip if this file is in expected_differ + skip=0 + for ed in "${expected_differ[@]}"; do + if [ "$f" = "$ed" ]; then + skip=1 + break + fi + done + [ "$skip" = "1" ] && continue + if ! diff -q "$f" "$upstream_dir/$f" >/dev/null 2>&1; then if [ "$diff_count" -eq 0 ]; then echo "ERROR: $fork_name has files that diverge from upstream $upstream_tag:" >&2 fi diff --git a/local/sources/redoxfs b/local/sources/redoxfs index ab50acfcc7..d47cd7d3f6 160000 --- a/local/sources/redoxfs +++ b/local/sources/redoxfs @@ -1 +1 @@ -Subproject commit ab50acfcc7dffaeae8ed391d427e3fe3fc34b13f +Subproject commit d47cd7d3f6e957e7212c94c0d498b62d4044b8af