phase 16.1: sync-versions.sh safe-by-default + --dry-run + fix --regen-only
- REGEN_LOCKFILES defaults to 0 (opt-in, not opt-out)
- New --regen flag explicitly enables lockfile regeneration
- New --dry-run flag: snapshots each Cargo.lock, regens, diffs, reverts
Reports per-lockfile changes that WOULD occur without modifying files
- Fixed --regen-only deadlock: CHECK_ONLY=1 no longer blocks regen
(mode_regen_only gate added to CHECK_ONLY skip check)
- Fixed ROOT_DRIFT unbound variable in --regen-only mode
(: ${ROOT_DRIFT:=0} before summary section)
- Moved regen_lockfile_for() definition before dry-run block
(was defined after call site — caused 'command not found')
This commit is contained in:
@@ -31,10 +31,12 @@
|
||||
# - Meson test-case crates
|
||||
#
|
||||
# Usage:
|
||||
# ./local/scripts/sync-versions.sh # Apply
|
||||
# ./local/scripts/sync-versions.sh --check # Check only
|
||||
# ./local/scripts/sync-versions.sh --no-regen # Apply without Cargo.lock regen
|
||||
# ./local/scripts/sync-versions.sh --regen-only # Only regenerate Cargo.lock files
|
||||
# ./local/scripts/sync-versions.sh # Apply version sync (SAFE — no lockfile regen by default)
|
||||
# ./local/scripts/sync-versions.sh --regen # Apply sync + regen Cargo.lock files
|
||||
# ./local/scripts/sync-versions.sh --check # Check only, exit 1 if drift
|
||||
# ./local/scripts/sync-versions.sh --dry-run # Preview: show what --regen WOULD change in lockfiles
|
||||
# ./local/scripts/sync-versions.sh --no-regen # Same as default (for backward compat)
|
||||
# ./local/scripts/sync-versions.sh --regen-only # Only regenerate Cargo.lock files
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
@@ -42,13 +44,16 @@ ROOT="$(cd "$(dirname "$0")/../.." && pwd)"
|
||||
cd "$ROOT"
|
||||
|
||||
CHECK_ONLY=0
|
||||
REGEN_LOCKFILES=1
|
||||
REGEN_LOCKFILES=0 # Phase 16.0: safe-by-default — lockfile regen is opt-in
|
||||
DRY_RUN=0
|
||||
for arg in "$@"; do
|
||||
case "$arg" in
|
||||
--check) CHECK_ONLY=1 ;;
|
||||
--regen) REGEN_LOCKFILES=1 ;;
|
||||
--no-regen) REGEN_LOCKFILES=0 ;;
|
||||
--regen-only) REGEN_LOCKFILES=1; mode_regen_only=1 ;;
|
||||
-h|--help) sed -n '1,40p' "$0"; exit 0 ;;
|
||||
--dry-run) DRY_RUN=1; REGEN_LOCKFILES=1 ;; # dry-run implies --regen
|
||||
-h|--help) sed -n '1,45p' "$0"; exit 0 ;;
|
||||
*) echo "Unknown option: $arg" >&2; exit 1 ;;
|
||||
esac
|
||||
done
|
||||
@@ -247,6 +252,8 @@ echo ""
|
||||
|
||||
# ---- Summary ----
|
||||
|
||||
: ${ROOT_DRIFT:=0}
|
||||
|
||||
if [[ $CHECK_ONLY -eq 1 ]]; then
|
||||
echo "Cat 0 (cookbook root): drift $ROOT_DRIFT"
|
||||
echo "Cat 1: checked $CAT1_CHECKED, drift $CAT1_DRIFT"
|
||||
@@ -273,21 +280,21 @@ fi
|
||||
# that has a Cargo.lock. The path-dep + [patch.crates-io] config in each
|
||||
# fork ensures the right crates are pulled in.
|
||||
#
|
||||
# Skip when --check or --no-regen; only --regen-only also opts in.
|
||||
# Skip when --check (but NOT --regen-only: that opts IN to regen)
|
||||
# Skip when --no-regen is active (REGEN_LOCKFILES=0)
|
||||
|
||||
if [[ $CHECK_ONLY -eq 1 ]]; then
|
||||
if [[ $CHECK_ONLY -eq 1 && "${mode_regen_only:-0}" != "1" ]]; then
|
||||
echo ""
|
||||
echo "(lockfile regeneration skipped in --check mode)"
|
||||
exit 0
|
||||
fi
|
||||
if [[ $REGEN_LOCKFILES -eq 0 ]]; then
|
||||
echo ""
|
||||
echo "(lockfile regeneration skipped via --no-regen)"
|
||||
echo "(lockfile regeneration skipped — use --regen to enable)"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "=== Phase 3: Regenerate Cargo.lock files ==="
|
||||
# ---- Phase 3: Lockfile regeneration utilities ----
|
||||
|
||||
REGEN_DONE=0
|
||||
REGEN_FAILED=0
|
||||
@@ -314,6 +321,74 @@ regen_lockfile_for() {
|
||||
cd "$ROOT"
|
||||
}
|
||||
|
||||
# ---- Phase 3: Dry-run preview (--dry-run flag) ----
|
||||
# Snapshot each fork's Cargo.lock, regen, show diff, then revert.
|
||||
# This lets operators preview lockfile changes before a real branch bump.
|
||||
if [[ $DRY_RUN -eq 1 ]]; then
|
||||
echo ""
|
||||
echo "=== Phase 3: Dry-run lockfile regen preview ==="
|
||||
echo "(existing Cargo.lock files will NOT be modified)"
|
||||
echo ""
|
||||
|
||||
# Preserve all lockfiles first
|
||||
declare -A LOCK_BACKUPS=()
|
||||
for lock_dir in "$ROOT" local/sources/*/; do
|
||||
[ -d "$lock_dir" ] || continue
|
||||
[ -f "${lock_dir}/Cargo.toml" ] || continue
|
||||
lock="${lock_dir}/Cargo.lock"
|
||||
if [ -f "$lock" ]; then
|
||||
LOCK_BACKUPS["$lock"]=$(cat "$lock")
|
||||
fi
|
||||
done
|
||||
|
||||
# Regenerate in-place (reverts after)
|
||||
regen_lockfile_for "$ROOT" "root"
|
||||
for fork_dir in local/sources/*/; do
|
||||
[ -d "$fork_dir" ] || continue
|
||||
fork_name=$(basename "$fork_dir")
|
||||
[ -f "${fork_dir}Cargo.toml" ] || continue
|
||||
regen_lockfile_for "${fork_dir%/}" "local/sources/${fork_name}"
|
||||
done
|
||||
|
||||
# Show diffs
|
||||
changed=0
|
||||
echo ""
|
||||
echo "--- Lockfile changes that would occur on a real bump ---"
|
||||
for lock in "${!LOCK_BACKUPS[@]}"; do
|
||||
backup="${LOCK_BACKUPS[$lock]}"
|
||||
current=""
|
||||
[ -f "$lock" ] && current=$(cat "$lock")
|
||||
if [ "$backup" != "$current" ]; then
|
||||
changed=$((changed + 1))
|
||||
label="${lock#$ROOT/}"
|
||||
echo ""
|
||||
echo " === $label ==="
|
||||
diff <(echo "$backup") <(echo "$current") | head -30
|
||||
if [ $(diff <(echo "$backup") <(echo "$current") | wc -l) -gt 30 ]; then
|
||||
echo " ... (truncated — $(( $(diff <(echo "$backup") <(echo "$current") | wc -l) - 30 )) more lines)"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
# Restore originals
|
||||
for lock in "${!LOCK_BACKUPS[@]}"; do
|
||||
echo "${LOCK_BACKUPS[$lock]}" > "$lock"
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo "=== Dry-run summary ==="
|
||||
echo " Lockfiles with changes: $changed"
|
||||
if [ $changed -eq 0 ]; then
|
||||
echo " ALL CLEAR — no lockfile changes would occur. Safe to --regen."
|
||||
else
|
||||
echo " Review the diffs above. If acceptable, run: $0 --regen"
|
||||
fi
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "=== Phase 3: Regenerate Cargo.lock files ==="
|
||||
|
||||
# Regenerate root cookbook lockfile
|
||||
regen_lockfile_for "$ROOT" "root"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user