Files
RedBear-OS/local/scripts/bump-fork.sh
T
vasilito 137da99644 scripts/bump-fork.sh: derive BRANCH_VERSION from git branch
The script uses '${BRANCH_VERSION:-0.0.0}' as the +rb suffix when
bumping a fork to a new upstream version. BRANCH_VERSION was never
set, so any fork bump would have produced 'X.Y.Z+rb0.0.0' instead
of the correct 'X.Y.Z+rb0.3.2' (or whichever branch is current).

Derive BRANCH_VERSION from 'git branch --show-current' using the same
pattern as local/scripts/build-redbear.sh:158-165. Falls back to
'0.0.0' if the branch name doesn't match semver (e.g., on 'master').

(NO AI attribution)
2026-07-14 11:53:39 +09:00

196 lines
6.7 KiB
Bash
Executable File

#!/usr/bin/env bash
# bump-fork.sh — Auto-bump a local fork to match upstream version
#
# Usage: bump-fork.sh <component> [--version=X.Y.Z]
#
# If --version is provided, bumps to that version.
# If --version is omitted, queries Cargo to determine the required version
# from the build graph.
#
# Implements: AGENTS.md "Local Fork Priority and Version Sync (MANDATORY)"
set -euo pipefail
# Derive Red Bear OS version from the current git branch name.
# Branch "0.3.1" → BRANCH_VERSION="0.3.1". Same pattern as
# local/scripts/build-redbear.sh:158-165. Falls back to "0.0.0" if
# the branch name doesn't match semver.
BRANCH_VERSION=$(git -C "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" branch --show-current 2>/dev/null | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -1 || true)
BRANCH_VERSION="${BRANCH_VERSION:-0.0.0}"
export BRANCH_VERSION
COMPONENT="${1:-}"
if [[ -z "$COMPONENT" ]]; then
echo "Usage: $0 <component> [--version=X.Y.Z]"
echo ""
echo "Components with local forks:"
for d in local/sources/*/; do
if [[ -d "$d" ]] && [[ -f "${d}Cargo.toml" ]]; then
echo " $(basename "$d")"
fi
done
exit 1
fi
shift
VERSION=""
while [[ $# -gt 0 ]]; do
case "$1" in
--version=*)
VERSION="${1#*=}"
shift
;;
*)
echo "Unknown option: $1" >&2
exit 1
;;
esac
done
LOCAL_DIR="local/sources/${COMPONENT}"
RECIPE_DIR="recipes/core/${COMPONENT}"
if [[ ! -d "$LOCAL_DIR" ]]; then
echo "ERROR: $LOCAL_DIR does not exist" >&2
exit 1
fi
# Detect current local version
if [[ -f "${LOCAL_DIR}/Cargo.toml" ]]; then
CURRENT_VERSION=$(grep -E '^version\s*=' "${LOCAL_DIR}/Cargo.toml" | head -1 | sed 's/.*"\(.*\)".*/\1/')
echo "Current local version: ${CURRENT_VERSION:-unknown}"
else
echo "WARNING: ${LOCAL_DIR}/Cargo.toml not found — not a Cargo crate?"
CURRENT_VERSION=""
fi
# Detect required version from build graph if not specified
if [[ -z "$VERSION" ]]; then
echo "Querying build graph for required version of ${COMPONENT}..."
# Search Cargo.lock files for the required version
REQUIRED_VERSION=""
while IFS= read -r lockfile; do
# Look for [[package]] entries that match this component
entry=$(awk '
/^name = "'"${COMPONENT}"'"$/ { found=1; next }
found && /^version = / { gsub(/"/, ""); print; exit }
' "$lockfile" 2>/dev/null)
if [[ -n "$entry" ]]; then
REQUIRED_VERSION="$entry"
break
fi
done < <(find . -name 'Cargo.lock' -not -path '*/.git/*' 2>/dev/null)
if [[ -z "$REQUIRED_VERSION" ]]; then
echo "ERROR: Could not determine required version for ${COMPONENT}" >&2
echo " Pass --version=X.Y.Z explicitly" >&2
exit 1
fi
VERSION="$REQUIRED_VERSION"
echo "Required version (from Cargo.lock): ${VERSION}"
fi
# Check if bump is needed
if [[ -n "$CURRENT_VERSION" ]] && [[ "$CURRENT_VERSION" == "$VERSION" ]]; then
echo "Local fork already at v${VERSION} — no bump needed"
exit 0
fi
echo "Bumping ${COMPONENT}: v${CURRENT_VERSION:-unknown} → v${VERSION}"
# Fetch upstream source at the required version
echo "Fetching upstream source at v${VERSION}..."
# Find the upstream repo URL from the recipe
if [[ -f "${RECIPE_DIR}/recipe.toml" ]]; then
UPSTREAM_GIT=$(grep -E '^git\s*=' "${RECIPE_DIR}/recipe.toml" | head -1 | sed 's/.*"\(.*\)".*/\1/')
fi
if [[ -z "${UPSTREAM_GIT:-}" ]]; then
echo "ERROR: Cannot determine upstream git URL from ${RECIPE_DIR}/recipe.toml" >&2
echo " Set up the recipe or pass --upstream-git=<url>" >&2
exit 1
fi
echo "Upstream git: ${UPSTREAM_GIT}"
# Fetch into a staging directory
STAGING_DIR="/tmp/redbear-bump-${COMPONENT}-$$"
trap "rm -rf ${STAGING_DIR}" EXIT
echo "Cloning ${UPSTREAM_GIT} at v${VERSION} into ${STAGING_DIR}..."
if ! git clone --depth 1 --branch "v${VERSION}" "${UPSTREAM_GIT}" "${STAGING_DIR}" 2>&1; then
echo "WARNING: clone with tag v${VERSION} failed, trying without tag..."
if ! git clone --depth 1 "${UPSTREAM_GIT}" "${STAGING_DIR}" 2>&1; then
echo "ERROR: git clone of ${UPSTREAM_GIT} failed" >&2
exit 1
fi
cd "${STAGING_DIR}"
git fetch --tags --quiet
if git rev-parse --verify "refs/tags/v${VERSION}" >/dev/null 2>&1; then
git checkout "v${VERSION}" --quiet
elif git rev-parse --verify "refs/tags/${VERSION}" >/dev/null 2>&1; then
git checkout "${VERSION}" --quiet
else
echo "WARNING: tag v${VERSION} not found — using default branch HEAD"
fi
cd - >/dev/null
else
cd "${STAGING_DIR}"
git fetch --tags --quiet 2>/dev/null || true
cd - >/dev/null
fi
# Apply Red Bear patches
PATCH_DIR="local/patches/${COMPONENT}"
if [[ -d "$PATCH_DIR" ]]; then
echo "Applying Red Bear patches from ${PATCH_DIR}..."
for patch in "${PATCH_DIR}"/*.patch; do
if [[ -f "$patch" ]]; then
echo " Applying $(basename "$patch")..."
if ! patch -p1 -d "${STAGING_DIR}" --dry-run < "$patch" >/dev/null 2>&1; then
echo "ERROR: Patch $(basename "$patch") fails to apply to upstream v${VERSION}" >&2
echo " Manual intervention required — patch may need rebasing" >&2
exit 1
fi
patch -p1 -d "${STAGING_DIR}" < "$patch"
fi
done
fi
# Update version in Cargo.toml
if [[ -f "${STAGING_DIR}/Cargo.toml" && -n "${CURRENT_VERSION}" ]]; then
escaped_current=$(printf '%s\n' "${CURRENT_VERSION}" | sed 's/[.[\*^$()+?{|\\]/\\&/g')
sed -i "s/^version = \"${escaped_current}\"/version = \"${VERSION}+rb${BRANCH_VERSION:-0.0.0}\"/" "${STAGING_DIR}/Cargo.toml"
fi
# Replace local fork contents
echo "Updating ${LOCAL_DIR}..."
OLD_DIR="${LOCAL_DIR}.old-${$}"
if ! mv "${STAGING_DIR}" "${LOCAL_DIR}.new-${$}" 2>/dev/null; then
echo "ERROR: cannot move staging dir — disk full or permission denied" >&2
rm -rf "${STAGING_DIR}"
exit 1
fi
mv "${LOCAL_DIR}" "${OLD_DIR}" && mv "${LOCAL_DIR}.new-${$}" "${LOCAL_DIR}"
if [[ $? -ne 0 ]]; then
echo "ERROR: swap failed — restoring original" >&2
mv "${OLD_DIR}" "${LOCAL_DIR}" 2>/dev/null || true
rm -rf "${LOCAL_DIR}.new-${$}"
exit 1
fi
rm -rf "${OLD_DIR}"
echo ""
echo "SUCCESS: ${COMPONENT} bumped to v${VERSION}"
echo ""
echo "Next steps:"
echo " 1. cd ${LOCAL_DIR}"
echo " 2. git diff (verify patches applied correctly)"
echo " 3. git add -A && git commit -m 'bump: ${COMPONENT} v${CURRENT_VERSION} -> v${VERSION}'"
echo " 4. git push origin submodule/${COMPONENT}"
echo " 5. Update local/fork-upstream-map.toml if the upstream tag changed"
echo " 5. Rebuild affected packages: ./local/scripts/build-redbear.sh redbear-mini"