diff --git a/file-list b/file-list index 4c8bb54..531a691 100644 --- a/file-list +++ b/file-list @@ -5,10 +5,12 @@ backend/package.json backend/pnpm-workspace.yaml # express/framework cmd +file-list develop diachron logger master mgmt sync.sh -templates \ No newline at end of file +templates +upgrade.sh diff --git a/upgrade.sh b/upgrade.sh old mode 100644 new mode 100755 index 38d3384..7393615 --- a/upgrade.sh +++ b/upgrade.sh @@ -1,38 +1,109 @@ #!/bin/bash -# shellcheck disable=SC2002 set -eu set -o pipefail IFS=$'\n\t' -# print useful message on failure -trap 's=$?; echo >&2 "$0: Error on line "$LINENO": $BASH_COMMAND"; exit $s' ERR - -# shellcheck disable=SC2034 DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -cd "$DIR" +new_ref="${1:?Usage: upgrade.sh }" -# - Check if the file .diachron-version exists; save its value in a variable -# named old_diachron_version +cached_repo="$HOME/.cache/diachron/v1/repositories/diachron.git" +tmpdir="" -# - Check if the repository is dirty; if there are any files that git knows -# about that have been changed but not committed, abort with a message +cleanup() { + if [ -n "$tmpdir" ]; then + rm -rf "$tmpdir" + fi +} +trap cleanup EXIT -# - Get the current commit and store it in a variable +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 -# - Perform a two checkouts of -# https://gitea.philologue.net/philologue/diachron, each in its own -# temporary directory. We'll call one "old" and one "new" +# Update cached repository +"$DIR/update-cached-repository.sh" -# - In old, check out $old_diachron_version; in our working application -# directory, delete all of the files in file-list using git rm +# 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") -# - In new, check out whatever was passed as argv[1] +# 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 -# - Copy all of the files in file-list to the working application and stage -# them with git add +# 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 -# - Commit +echo "" +echo "Upgrading: $old_ref -> $new_ref" +echo "" -# - Should we run sync.sh or should we advise the user to run sync.sh? +# 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"