Files
RedBear-OS/local/scripts/verify-external-source-versions.sh
T
vasilito 1c8858d14d versioning: parse Plasma PROJECT_VERSION + KDE Gear RELEASE_SERVICE_VERSION markers
The 6 Plasma modules (breeze/kdecoration/kf6-kwayland/kglobalacceld/kwin) and
konsole were 'no-marker(skip)' because src_version/the validator only knew KF's
KF_VERSION. Now both also read set(PROJECT_VERSION) (Plasma) and the split
RELEASE_SERVICE_VERSION_MAJOR/MINOR/MICRO (KDE Gear), so these vendored modules
are version-checked and rebasable. Test E23.
2026-08-01 00:50:26 +03:00

113 lines
5.7 KiB
Bash
Executable File

#!/usr/bin/env bash
# verify-external-source-versions.sh — detect recipe-vs-source VERSION divergence
# for tar-based (external upstream) recipes.
#
# Why this exists
# ---------------
# Several recipes under local/recipes/ vendor their upstream `source/` tree in
# git (the fork model) while ALSO declaring a `[source] tar = <url>` + `blake3`.
# A version bump that only rewrites `tar=`/`blake3=` (e.g. via
# bump-graphics-recipes.sh, or a manual edit) does NOT propagate into the
# committed source/ tree, nor does cookbook re-extract an existing source/ or
# re-verify an existing source.tar. The build then silently compiles the STALE
# version — exactly the Qt 6.11.0-vs-6.11.1 divergence that broke the desktop
# build (qtshadertools required 6.11.1 but qtbase was cooked from a 6.11.0 tree).
#
# This is the tar-recipe analogue of verify-fork-functions.sh (which guards the
# local/sources/ forks). It FAILS LOUDLY rather than letting a stale tree build.
#
# Checks per tar recipe (only when the relevant artifact is present):
# 1. source.tar blake3 == recipe blake3 (stale downloaded tarball)
# 2. source.tar top-dir version == recipe URL version (URL bumped, tar not)
# 3. vendored source/ version marker == recipe URL version
# (recipe bumped, committed tree not — the Qt class). Marker files:
# - .cmake.conf : QT_REPO_MODULE_VERSION "X.Y.Z" (Qt modules)
# - .redbear-src-version : plain "X.Y.Z" (generic stamp)
#
# Exit 0 = all consistent (or nothing to check). Exit 1 = divergence found.
# Gate: REDBEAR_SKIP_EXTERNAL_SOURCE_CHECK=1 bypasses (handled by caller).
set -u
ROOT="$(cd "$(dirname "$0")/../.." && pwd)"
QUIET=0
for a in "$@"; do case "$a" in --quiet) QUIET=1 ;; esac; done
have_b3() { command -v b3sum >/dev/null 2>&1; }
# Extract a dotted version (X.Y or X.Y.Z...) from a string; prints the LAST one,
# which for "qtbase-everywhere-src-6.11.1.tar.xz" is the upstream version.
ver_of() { grep -oE '[0-9]+\.[0-9]+(\.[0-9]+)*' <<<"$1" | tail -1; }
FAIL=0
CHECKED=0
declare -a PROBLEMS=()
while IFS= read -r recipe; do
dir="$(dirname "$recipe")"
# recipe-declared tar URL + blake3 (first [source] tar= wins)
url="$(grep -m1 -E '^[[:space:]]*tar[[:space:]]*=' "$recipe" 2>/dev/null | sed -E 's/^[^"]*"([^"]+)".*/\1/')"
[ -n "$url" ] || continue
rblake="$(grep -m1 -E '^[[:space:]]*blake3[[:space:]]*=' "$recipe" 2>/dev/null | grep -oE '[0-9a-f]{64}')"
rver="$(ver_of "$(basename "$url")")"
[ -n "$rver" ] || continue
name="$(basename "$dir")"
CHECKED=$((CHECKED + 1))
# 1) cached source.tar blake3 must match recipe blake3
if [ -f "$dir/source.tar" ] && [ -n "$rblake" ] && have_b3; then
dblake="$(b3sum "$dir/source.tar" 2>/dev/null | awk '{print $1}')"
if [ -n "$dblake" ] && [ "$dblake" != "$rblake" ]; then
PROBLEMS+=("$name: cached source.tar blake3 ($dblake) != recipe blake3 ($rblake) — stale downloaded tarball; rm '$dir/source.tar' to re-fetch")
FAIL=1
fi
fi
# 2) source.tar top-dir version must match recipe URL version
if [ -f "$dir/source.tar" ]; then
tver="$(ver_of "$(tar tf "$dir/source.tar" 2>/dev/null | head -1)")"
if [ -n "$tver" ] && [ "$tver" != "$rver" ]; then
PROBLEMS+=("$name: source.tar is v$tver but recipe tar= is v$rver — URL bumped, tarball not; rm '$dir/source.tar' to re-fetch")
FAIL=1
fi
fi
# 3) vendored source/ version marker must match recipe URL version.
# ACTUAL code markers (.cmake.conf, KDE KF_VERSION) win over the generic
# .redbear-src-version stamp — a stale stamp must never mask the real code
# version and let a divergent tree pass.
if [ -d "$dir/source" ]; then
sver=""
if [ -f "$dir/source/.cmake.conf" ]; then
sver="$(ver_of "$(grep -m1 QT_REPO_MODULE_VERSION "$dir/source/.cmake.conf" 2>/dev/null)")"
fi
if [ -z "$sver" ] && [ -f "$dir/source/CMakeLists.txt" ]; then
# KF (KF_VERSION), Plasma (PROJECT_VERSION), literal project(... VERSION x)
sver="$(grep -m1 -E 'set\((KF_VERSION|PROJECT_VERSION)|project\([A-Za-z0-9_]+ VERSION [0-9]' "$dir/source/CMakeLists.txt" 2>/dev/null | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -1)"
# KDE Gear split RELEASE_SERVICE_VERSION_* (konsole etc.)
if [ -z "$sver" ] && grep -q RELEASE_SERVICE_VERSION_MAJOR "$dir/source/CMakeLists.txt" 2>/dev/null; then
a="$(grep -m1 RELEASE_SERVICE_VERSION_MAJOR "$dir/source/CMakeLists.txt" | grep -oE '[0-9]+' | head -1)"
b="$(grep -m1 RELEASE_SERVICE_VERSION_MINOR "$dir/source/CMakeLists.txt" | grep -oE '[0-9]+' | head -1)"
c="$(grep -m1 RELEASE_SERVICE_VERSION_MICRO "$dir/source/CMakeLists.txt" | grep -oE '[0-9]+' | head -1)"
[ -n "$a" ] && sver="$a.$b.$c"
fi
fi
if [ -z "$sver" ] && [ -f "$dir/source/.redbear-src-version" ]; then
sver="$(ver_of "$(cat "$dir/source/.redbear-src-version" 2>/dev/null)")"
fi
if [ -n "$sver" ] && [ "$sver" != "$rver" ]; then
PROBLEMS+=("$name: vendored source/ is v$sver but recipe declares v$rver — the committed tree was never bumped; rebase source/ onto v$rver (see qt bump commits for the pattern)")
FAIL=1
fi
fi
done < <(find "$ROOT/local/recipes" -name recipe.toml -not -path '*/wip/*' 2>/dev/null)
if [ "$FAIL" != "0" ]; then
echo "FAIL: external source version divergence ($CHECKED tar recipes checked):" >&2
for p in "${PROBLEMS[@]}"; do echo " - $p" >&2; done
exit 1
fi
[ "$QUIET" = "1" ] || echo ">>> Preflight: external tar-recipe source versions consistent ($CHECKED checked)."
exit 0