Files
RedBear-OS/local/scripts/post-checkout-version-sync.sh
T
vasilito 6d8ef13dc1 LG Gram Round 1: redox-driver-sys stub replacements + doc reference fixes
Round 1 of the LG Gram 16Z90TP compatibility work. Two parallel
workstreams in one commit:

1. Stub replacements in redox-driver-sys (per project zero-tolerance
   policy):

   - load_dmi_acpi_quirks() (was hardcoded AcpiQuirkFlags::empty()):
     real loader walking a new compiled-in DMI_ACPI_QUIRK_RULES table
     (currently empty — documented why) plus a new [[dmi_acpi_quirk]]
     TOML section parser in toml_loader.rs. The full 16-flag
     ACPI_FLAG_NAMES mapping is added so TOML entries can use any
     AcpiQuirkFlags variant by name.

   - PANEL_ORIENTATION_TABLE (was empty placeholder): populated with
     10 real entries ported from Linux 7.x
     drivers/gpu/drm/drm_panel_orientation.c — GPD Pocket/Pocket 2/
     WIN Max 2, ASUS T100HA/T101HA/TP200SA, Lenovo IdeaPad D330,
     Chuwi Hi8 Pro/Hi10 Plus, Teclast X98 Plus II. Each entry cites
     its Linux source commit.

   - PLATFORM_RULES (kept empty): documented why intentionally empty
     (Linux platform-wide DMI quirks are pre-2020 platform workarounds
     not needed by Red Bear's modern targets).

2. Broken reference fixes after the 2026-07-25 archive
   (commit 589a1044e6 moved 9 docs to legacy-obsolete-2026-07-25/
   but didn't update references). 30+ files referenced the moved
   docs by their old local/docs/<name>.md path. This commit updates
   every reference to point at local/docs/legacy-obsolete-2026-07-25/
   <name>.md so links work again. Files touched: AGENTS.md,
   README.md, docs/{AGENTS,README,07-RED-BEAR-OS-IMPLEMENTATION-PLAN}.md,
   local/AGENTS.md, 14 docs under local/docs/, local/patches/README.md,
   5 scripts under local/scripts/.

The matching acpid+ps2d consumer wiring landed earlier today in
submodule/base commit 45452c5a (force_s2idle, no_legacy_pm1b,
kbd_deactivate_fixup). The bootstrap reference fix is submodule/base
commit 263a41a9. Both are tracked by the updated submodule pointer
in this commit.

Build verification: redox-driver-sys 80 cargo tests pass. acpid/ps2d
host tests not runnable (require cross-compile). Canonical build
attempts uncovered two pre-existing failures unrelated to Round 1:
relibc edition-2024 unsafe-block issue in crtn, and the base fork's
'common' path resolution relies on the build script's overlay
integrity auto-repair which is currently failing. Neither is in code
touched by Round 1.

See local/docs/evidence/lg-gram/ASSESSMENT-2026-07-26.md for the full
round-by-round assessment and next-round plan.
2026-07-26 16:59:32 +09:00

215 lines
9.5 KiB
Bash
Executable File

#!/usr/bin/env bash
# post-checkout-version-sync.sh — Optional post-checkout hook for Red Bear OS.
#
# Purpose:
# When an operator switches to a release branch whose name is an anchored
# semver (e.g. `0.3.1`, `0.3.2`), automatically synchronise every Cat 1
# (in-house) and Cat 2 (upstream fork) crate version label to match that
# branch. This is the label-only half of a release bump — it does NOT
# touch fork source content, regenerate lockfiles, or commit anything.
#
# Why label-only:
# Labels are cheap and mechanical (sed rewrites performed by
# sync-versions.sh). Source upgrades (rebasing a fork onto a newer upstream
# tag) and lockfile regen are expensive and operator-judgement steps, so
# they remain explicit (`bump-release.sh --with-sources --with-external`
# and `sync-versions.sh --regen`). See
# local/docs/RELEASE-BUMP-WORKFLOW.md for the full release model.
#
# Git post-checkout contract (git invokes this hook with three arguments):
# $1 = previous HEAD sha
# $2 = new HEAD sha
# $3 = 1 for a branch checkout, 0 for a file checkout
#
# Install (operator opt-in — NEVER auto-installed):
# cp local/scripts/post-checkout-version-sync.sh .git/hooks/post-checkout
# chmod +x .git/hooks/post-checkout
#
# Or via the installer (preferred):
# ./local/scripts/install-git-hooks.sh # post-checkout only
# ./local/scripts/install-git-hooks.sh --all # + pre-push + commit-msg
#
# Bypass for a single checkout:
# REDBEAR_NO_AUTO_SYNC=1 git checkout 0.3.2
#
# Hard guarantees (a failing hook MUST NEVER block a checkout):
# - Always exits 0. Any internal failure degrades to a stderr note + exit 0.
# - No network access. No git mutations (no commit / branch / push / stash).
# - No lockfile regeneration (NEVER calls `sync-versions.sh --regen`).
# - Does not run on non-semver branches (master, submodule/*, recovered/*,
# detached HEAD).
# - Does not run inside an in-progress rebase / cherry-pick / merge.
# - Does not run when the working tree is dirty (warns + skips).
# - Total runtime budget: < ~5 seconds on a warm tree.
#
# See: local/docs/legacy-obsolete-2026-07-25/HOOKS.md, local/docs/RELEASE-BUMP-WORKFLOW.md,
# local/AGENTS.md § "Version conventions — two categories".
# NOTE: deliberately `set -uo pipefail` and NOT `-e`. A post-checkout hook
# must never abort mid-way and leave the operator staring at a non-zero exit
# that blocks the checkout. Every fallible step is either guarded or wrapped
# so that failure degrades to an exit 0 with a stderr note.
set -uo pipefail
# ---------------------------------------------------------------------------
# Locate the repo root. We prefer `git rev-parse --show-toplevel` over a
# dirname-relative derivation because git places the hook under `.git/hooks/`
# which may itself be a gitdir pointer (worktrees, linked checkouts).
# ---------------------------------------------------------------------------
ROOT="$(git rev-parse --show-toplevel 2>/dev/null || true)"
if [[ -z "$ROOT" ]]; then
# Not inside a git work tree — nothing to do.
exit 0
fi
# Git passes exactly three arguments to post-checkout. If invoked manually
# without them, treat $3 as unknown (skip the branch-flag guard).
BRANCH_FLAG="${3:-}"
# ---------------------------------------------------------------------------
# Guard (a): branch checkouts only. $3 == 1 means a branch checkout;
# $3 == 0 means a file checkout (e.g. `git checkout -- path`). Silently
# skip file checkouts — there is no branch context to sync against.
# ---------------------------------------------------------------------------
if [[ "$BRANCH_FLAG" != "1" ]]; then
exit 0
fi
# ---------------------------------------------------------------------------
# Guard (b): the new branch name MUST be an anchored semver
# `^[0-9]+\.[0-9]+\.[0-9]+$`. This silently excludes master, main,
# submodule/* branches, recovered/* branches, and detached HEAD.
# ---------------------------------------------------------------------------
BRANCH="$(git branch --show-current 2>/dev/null || true)"
if [[ -z "$BRANCH" ]]; then
# Detached HEAD — no branch name to anchor a version against.
exit 0
fi
if ! printf '%s' "$BRANCH" | grep -qE '^[0-9]+\.[0-9]+\.[0-9]+$'; then
# Non-semver branch (master, submodule/*, recovered/*, feature/*, …).
# Silently skip — version labels are only meaningful on release branches.
exit 0
fi
# ---------------------------------------------------------------------------
# Guard (c): never run inside an in-progress rebase / cherry-pick / merge.
# Touching version labels mid-sequence would corrupt the operator's
# in-flight history rewrite. Silently skip in all such states.
# ---------------------------------------------------------------------------
GIT_DIR="$(git rev-parse --git-dir 2>/dev/null || true)"
if [[ -n "$GIT_DIR" ]]; then
# Resolve relative to the worktree root for linked worktrees.
[[ "$GIT_DIR" = /* ]] || GIT_DIR="$ROOT/$GIT_DIR"
for marker in rebase-merge rebase-apply CHERRY_PICK_HEAD MERGE_HEAD; do
if [[ -e "$GIT_DIR/$marker" ]]; then
# An interactive operation is in progress — stay out of the way.
exit 0
fi
done
fi
# ---------------------------------------------------------------------------
# Guard (d): honour the explicit opt-out env var.
# ---------------------------------------------------------------------------
if [[ -n "${REDBEAR_NO_AUTO_SYNC:-}" ]]; then
exit 0
fi
# ---------------------------------------------------------------------------
# Guard (e): working tree MUST be clean. A bump rewrites Cargo.toml files in
# place; running it over uncommitted operator edits would silently swallow
# those edits into the bump. Warn + skip instead.
# ---------------------------------------------------------------------------
if ! git -C "$ROOT" diff --quiet --ignore-submodules HEAD 2>/dev/null \
|| [[ -n "$(git -C "$ROOT" status --porcelain 2>/dev/null)" ]]; then
echo "post-checkout-version-sync: skipping version auto-sync: uncommitted changes present" >&2
echo " (commit or stash, then run: ./local/scripts/sync-versions.sh --no-regen)" >&2
exit 0
fi
# ---------------------------------------------------------------------------
# All guards passed. Compare the root cookbook Cargo.toml `[package] version`
# against the branch version. They are the canonical indicator of whether a
# label sync is needed: sync-versions.sh Phase 0 keeps them in lock-step,
# so if the root is already at the branch version, every Cat 1/Cat 2 label
# is already correct too.
# ---------------------------------------------------------------------------
ROOT_CARGO="$ROOT/Cargo.toml"
if [[ ! -f "$ROOT_CARGO" ]]; then
# Not a Red Bear OS checkout (no root Cargo.toml). Stay silent.
exit 0
fi
CURRENT_VERSION=""
if grep -qE '^\[package\]' "$ROOT_CARGO" 2>/dev/null; then
# Must match sync-versions.sh Phase 0's extraction so both scripts agree.
CURRENT_VERSION="$(awk '
/^\[package\]/ { in_pkg=1; next }
/^\[/ { in_pkg=0 }
in_pkg && /^version[[:space:]]*=/ { print; exit }
' "$ROOT_CARGO" 2>/dev/null | sed 's/.*"\(.*\)".*/\1/' || true)"
fi
if [[ "$CURRENT_VERSION" == "$BRANCH" ]]; then
# Labels already synced for this branch — nothing to do.
exit 0
fi
# ---------------------------------------------------------------------------
# Drift detected. Run the label-only sync (NEVER --regen — lockfile regen is
# an explicit operator step). sync-versions.sh is the single executor of
# suffix-only label rewrites; this hook never duplicates that sed logic.
# ---------------------------------------------------------------------------
SYNC="$ROOT/local/scripts/sync-versions.sh"
if [[ ! -x "$SYNC" ]]; then
echo "post-checkout-version-sync: $SYNC not found or not executable — skipping label sync" >&2
echo " run manually: ./local/scripts/sync-versions.sh --no-regen" >&2
exit 0
fi
echo "post-checkout-version-sync: branch '$BRANCH' root Cargo.toml at '$CURRENT_VERSION' -> '$BRANCH'"
echo "post-checkout-version-sync: running sync-versions.sh --no-regen (labels only, no lockfile regen)"
# Run label sync. Capture output so the operator sees a concise summary.
# We do NOT propagate a non-zero exit: even if sync fails, the checkout
# itself must not be blocked.
SYNC_OUTPUT="$("$SYNC" --no-regen 2>&1)" || true
if [[ -n "$SYNC_OUTPUT" ]]; then
printf '%s\n' "$SYNC_OUTPUT"
fi
echo "post-checkout-version-sync: label sync complete for branch '$BRANCH'."
# ---------------------------------------------------------------------------
# Follow-up hint. The hook handles ONLY mechanical label rewrites. The
# expensive half of a release bump — fork source upgrades to newer upstream
# tags and external desktop-stack version refresh — is the operator's
# explicit decision and is never triggered automatically.
# ---------------------------------------------------------------------------
cat >&2 <<EOF
post-checkout-version-sync: follow-up steps (NOT run automatically):
- source upgrades (Cat 2 forks to newer upstream tags):
./local/scripts/bump-release.sh --with-sources --with-external
- lockfile regeneration (after labels settle):
./local/scripts/sync-versions.sh --regen
- check-only verification:
./local/scripts/sync-versions.sh --check
See local/docs/RELEASE-BUMP-WORKFLOW.md for the full runbook.
EOF
# Always exit 0. A hook that blocks the checkout is strictly worse than a
# hook that no-ops; git treats a non-zero exit from post-checkout as a
# warning and clutters the operator's terminal on every checkout.
exit 0