#!/bin/bash set -eu set -o pipefail IFS=$'\n\t' DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" new_ref="${1:?Usage: upgrade.sh }" cached_repo="$HOME/.cache/diachron/v1/repositories/diachron.git" tmpdir="" cleanup() { if [ -n "$tmpdir" ]; then rm -rf "$tmpdir" fi } trap cleanup EXIT echo "=== Diachron Framework Upgrade ===" echo "" echo "This will replace all framework files in your project." echo "Make sure you have committed or backed up any local changes." echo "" read -r -p "Continue? [y/N] " answer if [[ ! "$answer" =~ ^[Yy]$ ]]; then echo "Aborted." exit 0 fi # Update cached repository "$DIR/update-cached-repository.sh" # Read current version if [ ! -f "$DIR/.diachron-version" ]; then echo "Error: .diachron-version not found." >&2 echo "Is this a diachron project?" >&2 exit 1 fi old_ref=$(cat "$DIR/.diachron-version") # Verify both refs exist in cached repo if ! git -C "$cached_repo" rev-parse --verify "$old_ref^{commit}" >/dev/null 2>&1; then echo "Error: current version '$old_ref' not found in cached repository." >&2 exit 1 fi if ! git -C "$cached_repo" rev-parse --verify "$new_ref^{commit}" >/dev/null 2>&1; then echo "Error: target version '$new_ref' not found in cached repository." >&2 exit 1 fi # Require a clean working tree if [ -n "$(git -C "$DIR" status --porcelain)" ]; then echo "Error: working tree is not clean." >&2 echo "Commit or stash all changes (including untracked files) before upgrading." >&2 exit 1 fi echo "" echo "Upgrading: $old_ref -> $new_ref" echo "" # Read current file-list (files to remove) old_files=() while IFS= read -r line; do [[ "$line" =~ ^[[:space:]]*# ]] && continue [[ -z "$line" ]] && continue old_files+=("$line") done < "$DIR/file-list" # Clone and checkout new version into a temp directory tmpdir=$(mktemp -d) git clone --quiet "$cached_repo" "$tmpdir/diachron" git -C "$tmpdir/diachron" checkout --quiet "$new_ref" # Read new file-list (files to add) new_files=() while IFS= read -r line; do [[ "$line" =~ ^[[:space:]]*# ]] && continue [[ -z "$line" ]] && continue new_files+=("$line") done < "$tmpdir/diachron/file-list" # Remove old framework files for f in "${old_files[@]}"; do git -C "$DIR" rm -rf --quiet --ignore-unmatch "$f" done # Copy in new framework files (cd "$tmpdir/diachron" && tar cf - "${new_files[@]}") | (cd "$DIR" && tar xf -) # Stage them for f in "${new_files[@]}"; do git -C "$DIR" add "$f" done # Update version marker echo "$new_ref" > "$DIR/.diachron-version" git -C "$DIR" add "$DIR/.diachron-version" echo "=== Upgrade staged: $old_ref -> $new_ref ===" echo "" echo "Framework files have been removed, replaced, and staged." echo "" echo "Next steps:" echo " 1. Review: git diff --cached" echo " 2. Commit: git commit -m 'Upgrade diachron to $new_ref'" echo " 3. Install: ./sync.sh"