From ea6d4a124f63fe3482eb7ab504220188b1fd3e3a Mon Sep 17 00:00:00 2001 From: vasilito Date: Sat, 1 Aug 2026 04:55:40 +0300 Subject: [PATCH] build: vendor-recipe.sh tool + defer xwayland from redbear-full vendor-recipe.sh converts a transient recipe to the vendored full-fork model (repo fetch -> strip .git -> [source] path=source with provenance comment -> un-ignore -> stamp). Used to vendor 23 of the 26 transients. xwayland deferred (corrupt redox.patch needs regeneration; X11-compat, not login-critical); smallvil + seatd-redox not in the full set. --- config/redbear-full.toml | 9 +++- local/scripts/vendor-recipe.sh | 88 ++++++++++++++++++++++++++++++++++ 2 files changed, 95 insertions(+), 2 deletions(-) create mode 100755 local/scripts/vendor-recipe.sh diff --git a/config/redbear-full.toml b/config/redbear-full.toml index 652356deac..20863a47dd 100644 --- a/config/redbear-full.toml +++ b/config/redbear-full.toml @@ -64,7 +64,12 @@ description = "Display manager, greeter, auth, and session bootstrap" packages = [ "kwin", "kdecoration", "breeze", "kirigami", "sddm", "redbear-authd", "redbear-session-launch", "seatd", - "redbear-greeter", "pam-redbear", "xwayland", + "redbear-greeter", "pam-redbear", + # TODO(xwayland): deferred from the build — its redox.patch is doubly corrupt + # (malformed hunk counts + wrong a/source vs b/source-new strip prefix) and + # needs full regeneration. xwayland is X11-app compat under Wayland, NOT + # required for the SDDM login / Plasma-Wayland session. Re-add once vendored. + # "xwayland", ] [package_groups.kde-desktop] @@ -225,7 +230,7 @@ seatd = {} redbear-greeter = {} pam-redbear = {} sddm = {} -xwayland = {} +# xwayland = {} # deferred — see packages[] TODO(xwayland) # D-Bus Rust bindings + media zbus = {} diff --git a/local/scripts/vendor-recipe.sh b/local/scripts/vendor-recipe.sh new file mode 100755 index 0000000000..038ae2e10b --- /dev/null +++ b/local/scripts/vendor-recipe.sh @@ -0,0 +1,88 @@ +#!/usr/bin/env bash +# vendor-recipe.sh — convert a transient recipe (fetches upstream at build time) +# into a vendored full-fork recipe (builds from a committed source/ tree, offline). +# +# For each recipe: +# 1. `repo fetch` it — cookbook clones/extracts upstream into source/ and BAKES +# the recipe's patches in ([ATOMIC] N/N patches applied). +# 2. Strip any embedded .git (git-fetched sources carry one; committing it would +# store a useless gitlink instead of the files). +# 3. Rewrite [source] to `path = "source"` (cookbook then uses source/ as-is, no +# network), preserving the upstream url/rev/blake3/patches as a provenance +# comment. The .patch files stay tracked so a version bump can re-apply them. +# 4. Drop any `.../source` line from .gitignore so the tree is committable. +# 5. Stamp source/.redbear-src-version. +# Leaves everything staged-but-uncommitted for review (unless --commit). +# +# Usage: vendor-recipe.sh [--commit] ... (recipe = dir or name) +set -uo pipefail +ROOT="$(cd "$(dirname "$0")/../.." && pwd)" +REPO="$ROOT/target/release/repo" +COMMIT=0; declare -a WANT=() +for a in "$@"; do case "$a" in --commit) COMMIT=1;; --*) echo "unknown: $a">&2; exit 1;; *) WANT+=("$a");; esac; done + +resolve(){ local t="${1%/}"; t="${t#"$ROOT"/}"; t="${t#local/recipes/}" + [ -f "$ROOT/local/recipes/$t/recipe.toml" ] && { echo "$ROOT/local/recipes/$t"; return; } + local h; h=$(find "$ROOT/local/recipes" -name recipe.toml -not -path '*/wip/*' -path "*/$t/recipe.toml" 2>/dev/null|head -1) + [ -n "$h" ] && echo "$(dirname "$h")"; } + +rc=0 +for tok in "${WANT[@]}"; do + dir="$(resolve "$tok")"; [ -n "$dir" ] || { echo "!! not found: $tok">&2; rc=1; continue; } + name="$(basename "$dir")" + if grep -qE '^\s*path\s*=\s*"source"' "$dir/recipe.toml"; then echo "[$name] already vendored (path=source)"; continue; fi + + echo "[$name] fetching (bakes patches)…" + if ! ( cd "$ROOT" && REDBEAR_CANONICAL_BUILD=1 REPO_OFFLINE=0 COOKBOOK_OFFLINE=false "$REPO" fetch "$name" ) >/"$ROOT"/.vendor-fetch.log 2>&1; then + echo "[$name] FETCH/PATCH FAILED — see .vendor-fetch.log (likely a broken patch to fix by hand)"; rc=1; continue + fi + [ -d "$dir/source" ] || { echo "[$name] no source/ after fetch"; rc=1; continue; } + rm -rf "$dir/source/.git" + + # capture provenance (bash) for the stamp before the [source] rewrite + up_url="$(grep -m1 -E '^\s*(tar|git)\s*=' "$dir/recipe.toml" | grep -oE '"[^"]+"' | tr -d '"')" + up_rev="$(grep -m1 -E '^\s*rev\s*=' "$dir/recipe.toml" | grep -oE '"[^"]+"' | tr -d '"')" + stamp="${up_rev:-}"; [ -z "$stamp" ] && stamp="$(basename "${up_url:-unknown}")" + + # rewrite [source] -> path="source" + provenance comment, via python + python3 - "$dir/recipe.toml" <<'PY' +import re,sys +p=sys.argv[1]; s=open(p).read() +m=re.search(r'(?ms)^\[source\]\s*\n(.*?)(?=^\[|\Z)', s) +if not m: sys.exit(0) +body=m.group(1) +def val(k): + mm=re.search(r'^\s*%s\s*=\s*"([^"]*)"'%k, body, re.M); return mm.group(1) if mm else None +url=val('tar') or val('git'); rev=val('rev'); blake=val('blake3') +pats=re.findall(r'"([^"]+\.patch)"', body) +c=['[source]', + '# Vendored local fork (full-fork model): builds from the committed source/', + '# tree (offline, reproducible). source/ = pristine upstream + the patches below', + '# BAKED IN. .patch files kept tracked so a version bump can re-apply them via', + '# sync-recipe-source.sh.'] +if url: c.append('# upstream: %s'%url) +if rev: c.append('# rev: %s'%rev) +if blake: c.append('# blake3: %s'%blake) +for pt in pats: c.append('# patch (baked): %s'%pt) +c.append('path = "source"') +s=s[:m.start()]+'\n'.join(c)+'\n\n'+s[m.end():] +open(p,'w').write(s) +PY + + # un-ignore + if grep -qE "^local/recipes/.*/$name/source" "$ROOT/.gitignore" 2>/dev/null; then + grep -vE "^local/recipes/.*/$name/source" "$ROOT/.gitignore" > "$ROOT/.gitignore.tmp" && mv "$ROOT/.gitignore.tmp" "$ROOT/.gitignore" + fi + # stamp + printf '%s\n' "$stamp" > "$dir/source/.redbear-src-version" 2>/dev/null || true + + git -C "$ROOT" add -A "$dir" "$ROOT/.gitignore" >/dev/null 2>&1 + nfiles=$(git -C "$ROOT" diff --cached --name-only -- "$dir/source" | wc -l | tr -d ' ') + echo "[$name] vendored: $nfiles source files staged, baked $(grep -rlI '__redox__\|Q_OS_REDOX' "$dir/source" 2>/dev/null|wc -l) redox-marked" + if [ "$COMMIT" = 1 ]; then + git -C "$ROOT" -c commit.gpgsign=false commit -q -m "$name: vendor as full-fork recipe (path=source, patches baked)" -- "$dir" "$ROOT/.gitignore" + echo "[$name] committed $(git -C "$ROOT" log -1 --format=%h)" + fi +done +rm -f "$ROOT/.vendor-fetch.log" +exit $rc