From 5947dcdc8626a40c7ef2a805147c1863d0f1adb0 Mon Sep 17 00:00:00 2001 From: Michael Wolf Date: Mon, 9 Feb 2026 06:58:09 -0500 Subject: [PATCH] Add ? prefix for sample files in file-list; fix bootstrap/upgrade 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 --- bootstrap.sh | 4 ++-- diachron/AGENTS.md | 15 ++++++++++++++ diff-upstream.sh | 4 ++-- file-list | 21 +++++++++++-------- upgrade.sh | 50 ++++++++++++++++++++++++++++++++++++++++++---- 5 files changed, 78 insertions(+), 16 deletions(-) diff --git a/bootstrap.sh b/bootstrap.sh index f3aaba6..0465664 100755 --- a/bootstrap.sh +++ b/bootstrap.sh @@ -42,8 +42,8 @@ echo working dir: $PWD # exit 0 -tar cvf - $(cat "$PWD/file-list" | grep -v '^#') | (cd "$here" && tar xf -) +tar cvf - $(cat "$PWD/file-list" | grep -v '^#' | sed 's/^?//') | (cd "$here" && tar xf -) -echo "$ref" > .diachron-version +echo "$ref" > "$here/.diachron-version" echo "Now, run the command ./sync.sh" diff --git a/diachron/AGENTS.md b/diachron/AGENTS.md index 4c24893..4b65b1f 100644 --- a/diachron/AGENTS.md +++ b/diachron/AGENTS.md @@ -187,6 +187,21 @@ framework. When you create or delete a file that is part of the project (not a scratch file or generated output), you must update `file-list` to match. Keep it sorted alphabetically. +Entries can have a `?` prefix (e.g. `?backend/app.ts`). These are +**sample files** -- starter code that `bootstrap.sh` copies into a new +project but that `upgrade.sh` will not overwrite. Once the user has the +file, it belongs to them. On upgrade, new sample files that don't exist +yet in the project are copied in; existing ones are left untouched. + +Unprefixed entries are **framework-owned** and are always replaced on +upgrade. When adding a new file to `file-list`, decide which category +it belongs to: + +- Framework-owned (no prefix): infrastructure scripts, framework + library code, build tooling, config that must stay in sync. +- Sample (`?` prefix): application starter code the user is expected + to edit (routes, handlers, services, types, package.json, etc.). + ## Things to avoid - Do not introduce `.env` files or `dotenv` without checking with the diff --git a/diff-upstream.sh b/diff-upstream.sh index c07169f..489bd1c 100755 --- a/diff-upstream.sh +++ b/diff-upstream.sh @@ -50,12 +50,12 @@ if ! git -C "$cached_repo" rev-parse --verify "$ref^{commit}" >/dev/null 2>&1; t exit 1 fi -# Read file-list +# Read file-list (strip ? prefix from sample entries) files=() while IFS= read -r line; do [[ "$line" =~ ^[[:space:]]*# ]] && continue [[ -z "$line" ]] && continue - files+=("$line") + files+=("${line#\?}") done < "$DIR/file-list" # Check out upstream into a temp directory diff --git a/file-list b/file-list index 123d1a9..77a4eb2 100644 --- a/file-list +++ b/file-list @@ -1,27 +1,32 @@ # please keep this file sorted alphabetically +# +# Files prefixed with ? are sample/starter files. bootstrap.sh copies them +# into a new project, but upgrade.sh will not overwrite them if the user has +# already modified or replaced them. Unprefixed files are framework-owned +# and are always replaced on upgrade. .gitignore .go-version DIACHRON.md backend/.gitignore backend/.npmrc -backend/app.ts +?backend/app.ts backend/build.sh backend/check-deps.ts backend/check.sh backend/diachron backend/generated -backend/group.ts -backend/handlers.spec.ts -backend/handlers.ts -backend/package.json +?backend/group.ts +?backend/handlers.spec.ts +?backend/handlers.ts +?backend/package.json backend/pnpm-workspace.yaml -backend/routes.ts +?backend/routes.ts backend/run.sh -backend/services.ts +?backend/services.ts backend/show-config.sh backend/tsconfig.json -backend/types.ts +?backend/types.ts backend/watch.sh bootstrap.sh cmd diff --git a/upgrade.sh b/upgrade.sh index eb483cc..799b2f4 100755 --- a/upgrade.sh +++ b/upgrade.sh @@ -62,11 +62,17 @@ 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 - old_files+=("$line") + if [[ "$line" == \?* ]]; then + old_samples+=("${line#\?}") + else + old_files+=("$line") + fi done < "$DIR/file-list" # Clone and checkout new version into a temp directory @@ -76,25 +82,44 @@ 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 - new_files+=("$line") + if [[ "$line" == \?* ]]; then + new_samples+=("${line#\?}") + else + new_files+=("$line") + fi done < "$tmpdir/diachron/file-list" -# Remove old framework files +# 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 cvf - "${new_files[@]}") | (cd "$DIR" && tar xf -) +(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" @@ -102,6 +127,23 @@ 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"