bootstrap.sh wrote .diachron-version to the temp clone directory instead of the target project, causing upgrade.sh to fail. Fix that and teach all three scripts (bootstrap, upgrade, diff-upstream) about the new ? prefix convention in file-list. Sample files (?-prefixed) are copied on bootstrap but left alone on upgrade so user modifications are preserved. New samples introduced in a newer framework version are still copied if absent. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
152 lines
3.9 KiB
Bash
Executable File
152 lines
3.9 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
set -eu
|
|
set -o pipefail
|
|
IFS=$'\n\t'
|
|
|
|
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
|
|
new_ref="${1:?Usage: upgrade.sh <new-ref>}"
|
|
|
|
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)
|
|
# Entries prefixed with ? are sample files -- we don't remove those on upgrade.
|
|
old_files=()
|
|
old_samples=()
|
|
while IFS= read -r line; do
|
|
[[ "$line" =~ ^[[:space:]]*# ]] && continue
|
|
[[ -z "$line" ]] && continue
|
|
if [[ "$line" == \?* ]]; then
|
|
old_samples+=("${line#\?}")
|
|
else
|
|
old_files+=("$line")
|
|
fi
|
|
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=()
|
|
new_samples=()
|
|
while IFS= read -r line; do
|
|
[[ "$line" =~ ^[[:space:]]*# ]] && continue
|
|
[[ -z "$line" ]] && continue
|
|
if [[ "$line" == \?* ]]; then
|
|
new_samples+=("${line#\?}")
|
|
else
|
|
new_files+=("$line")
|
|
fi
|
|
done < "$tmpdir/diachron/file-list"
|
|
|
|
# Remove old framework files (not samples -- those belong to the user)
|
|
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
|
|
|
|
# Handle sample files: copy only if the user doesn't already have them
|
|
samples_added=()
|
|
samples_skipped=()
|
|
for f in "${new_samples[@]}"; do
|
|
if [ -e "$DIR/$f" ]; then
|
|
samples_skipped+=("$f")
|
|
else
|
|
# New sample that doesn't exist yet -- copy it in
|
|
(cd "$tmpdir/diachron" && tar cf - "$f") | (cd "$DIR" && tar xf -)
|
|
git -C "$DIR" add "$f"
|
|
samples_added+=("$f")
|
|
fi
|
|
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."
|
|
|
|
if [ ${#samples_added[@]} -gt 0 ]; then
|
|
echo ""
|
|
echo "New sample files added:"
|
|
for f in "${samples_added[@]}"; do
|
|
echo " + $f"
|
|
done
|
|
fi
|
|
|
|
if [ ${#samples_skipped[@]} -gt 0 ]; then
|
|
echo ""
|
|
echo "Sample files skipped (you already have these):"
|
|
for f in "${samples_skipped[@]}"; do
|
|
echo " ~ $f"
|
|
done
|
|
fi
|
|
|
|
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"
|