Fix bin/publish: use correct .env path for rspade_system Fix bin/publish script: prevent grep exit code 1 from terminating script 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
384 lines
14 KiB
Bash
Executable File
384 lines
14 KiB
Bash
Executable File
#!/bin/bash
|
||
|
||
# RSpade Framework Update Script
|
||
# Pulls updates from rspade_upstream remote while preserving ./rsx in project mode
|
||
# This script runs BEFORE Laravel loads to update framework code independently
|
||
|
||
set -e
|
||
|
||
# Parse arguments
|
||
NO_REBUILD=false
|
||
for arg in "$@"; do
|
||
if [ "$arg" = "--no-rebuild" ]; then
|
||
NO_REBUILD=true
|
||
fi
|
||
done
|
||
|
||
# Determine project mode: Check for .rspade-dev-environment or rsx/.git
|
||
IS_PROJECT_MODE=false
|
||
if [ -f ".rspade-dev-environment" ] || [ -d "rsx/.git" ]; then
|
||
IS_PROJECT_MODE=true
|
||
fi
|
||
|
||
# In project mode, rsx/.git MUST exist
|
||
if [ "$IS_PROJECT_MODE" = true ] && [ ! -d "rsx/.git" ]; then
|
||
echo "ERROR: ./rsx is not a git repository."
|
||
echo ""
|
||
echo "The development environment appears corrupted."
|
||
echo "Expected ./rsx to be an independent git repository."
|
||
exit 1
|
||
fi
|
||
|
||
# Check if framework is forked
|
||
if [ -f ".rspade-forked-framework" ]; then
|
||
echo "ERROR: Framework is in forked mode."
|
||
echo ""
|
||
echo "You have taken full ownership of the RSpade framework codebase."
|
||
echo "Automatic updates are disabled to prevent overwriting your changes."
|
||
echo ""
|
||
echo "To manually update from upstream:"
|
||
echo " 1. git fetch rspade_upstream"
|
||
echo " 2. git diff rspade_upstream/rspade_selfupdate"
|
||
echo " 3. Manually merge desired changes"
|
||
echo " 4. Test thoroughly"
|
||
echo ""
|
||
echo "For detailed procedures: php artisan rsx:man framework_fork"
|
||
exit 1
|
||
fi
|
||
|
||
# Check .env for IS_FRAMEWORK_DEVELOPER=true
|
||
if [ -f ".env" ]; then
|
||
if grep -q "^IS_FRAMEWORK_DEVELOPER=true" .env; then
|
||
echo "ERROR: This command is disabled for framework developers."
|
||
echo ""
|
||
echo "This command is for application developers to pull framework updates."
|
||
echo "Framework developers should use standard git commands to manage the monorepo."
|
||
echo ""
|
||
echo "To use this command, set IS_FRAMEWORK_DEVELOPER=false in .env"
|
||
exit 1
|
||
fi
|
||
fi
|
||
|
||
# Check APP_ENV for production
|
||
if [ -f ".env" ]; then
|
||
if grep -q "^APP_ENV=production" .env; then
|
||
echo "ERROR: Framework updates are disabled in production mode."
|
||
echo ""
|
||
echo "Framework updates should be incorporated into and tested in a"
|
||
echo "development environment before deploying to production."
|
||
echo ""
|
||
echo "Update in development, test thoroughly, then deploy to production."
|
||
exit 1
|
||
fi
|
||
fi
|
||
|
||
# Verify rspade_upstream remote exists
|
||
if ! git remote get-url rspade_upstream >/dev/null 2>&1; then
|
||
echo "ERROR: Remote \"rspade_upstream\" not configured."
|
||
echo ""
|
||
echo "Configure the upstream remote:"
|
||
echo " git remote add rspade_upstream <upstream-url>"
|
||
exit 1
|
||
fi
|
||
|
||
echo ""
|
||
echo "=== Pull RSpade Framework Updates ==="
|
||
echo ""
|
||
|
||
# Detect current branch and set upstream branch
|
||
CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD 2>&1)
|
||
UPSTREAM_BRANCH="rspade_upstream/${CURRENT_BRANCH}"
|
||
|
||
# Verify upstream branch exists
|
||
if ! git rev-parse "$UPSTREAM_BRANCH" >/dev/null 2>&1; then
|
||
echo "ERROR: Upstream branch $UPSTREAM_BRANCH not found"
|
||
echo ""
|
||
echo "Current branch: $CURRENT_BRANCH"
|
||
echo "Expected upstream: $UPSTREAM_BRANCH"
|
||
echo ""
|
||
echo "Available upstream branches:"
|
||
git branch -r | grep rspade_upstream/ | sed 's/^/ /'
|
||
exit 1
|
||
fi
|
||
|
||
if [ "$IS_PROJECT_MODE" = true ]; then
|
||
echo "Mode: Project (./rsx will be preserved)"
|
||
else
|
||
echo "Mode: Framework development (./rsx will be updated)"
|
||
fi
|
||
echo "Branch: $CURRENT_BRANCH → $UPSTREAM_BRANCH"
|
||
echo ""
|
||
|
||
# Fetch updates
|
||
echo "Fetching updates from rspade_upstream..."
|
||
if ! git fetch rspade_upstream 2>&1; then
|
||
echo "ERROR: Failed to fetch updates"
|
||
exit 1
|
||
fi
|
||
echo " ✓ Updates fetched"
|
||
|
||
# Check if already up-to-date
|
||
CURRENT_HEAD=$(git rev-parse HEAD 2>&1)
|
||
UPSTREAM_HEAD=$(git rev-parse "$UPSTREAM_BRANCH" 2>&1)
|
||
|
||
if [ "$CURRENT_HEAD" = "$UPSTREAM_HEAD" ]; then
|
||
echo ""
|
||
echo "✓ Already up to date"
|
||
echo ""
|
||
exit 0
|
||
fi
|
||
|
||
# In project mode, check for uncommitted changes outside ./rsx
|
||
if [ "$IS_PROJECT_MODE" = true ]; then
|
||
# Get uncommitted changes (modified, staged, deleted) excluding ./rsx
|
||
UNCOMMITTED_CHANGES=$(git diff --name-only -- . ":(exclude)rsx" 2>&1)
|
||
STAGED_CHANGES=$(git diff --cached --name-only -- . ":(exclude)rsx" 2>&1)
|
||
|
||
# Combine and deduplicate (|| true prevents grep exit code 1 from killing script)
|
||
ALL_CHANGES=$(echo -e "${UNCOMMITTED_CHANGES}\n${STAGED_CHANGES}" | sort -u | grep -v "^$" || true)
|
||
|
||
if [ -n "$ALL_CHANGES" ]; then
|
||
if [ "$STASH_CHANGES" = false ]; then
|
||
echo ""
|
||
echo "════════════════════════════════════════════════════════════════════════════════"
|
||
echo "❌ ERROR: Uncommitted framework changes detected"
|
||
echo "════════════════════════════════════════════════════════════════════════════════"
|
||
echo ""
|
||
echo "You are in PROJECT MODE where ./rsx is your application repository."
|
||
echo "Framework files outside ./rsx should NEVER be modified in project mode."
|
||
echo ""
|
||
echo "The following framework files have uncommitted changes:"
|
||
echo ""
|
||
echo "$ALL_CHANGES" | sed 's/^/ /'
|
||
echo ""
|
||
echo "These changes must be resolved before updating the framework."
|
||
echo ""
|
||
echo "OPTIONS:"
|
||
echo ""
|
||
echo " 1️⃣ DISCARD FRAMEWORK CHANGES (recommended)"
|
||
echo " If these were accidental edits, reset them:"
|
||
echo ""
|
||
echo " git checkout HEAD -- [file paths]"
|
||
echo ""
|
||
echo " Or reset all framework changes:"
|
||
echo " git checkout HEAD -- . ':!rsx'"
|
||
echo ""
|
||
echo " 2️⃣ STASH CHANGES AND UPDATE"
|
||
echo " Your changes will be stashed automatically, then the framework"
|
||
echo " will be updated. You can review or restore the stashed changes after:"
|
||
echo ""
|
||
echo " php artisan rsx:framework:pull --stash-changes"
|
||
echo ""
|
||
echo " After update, review your stashed changes:"
|
||
echo " git stash list"
|
||
echo " git stash show"
|
||
echo " git stash pop (to restore)"
|
||
echo ""
|
||
echo " 3️⃣ COMMIT THEN UPDATE (framework developers only)"
|
||
echo " If you're intentionally modifying the framework:"
|
||
echo ""
|
||
echo " git add -A"
|
||
echo " git commit -m \"Framework modifications\""
|
||
echo " php artisan rsx:framework:pull"
|
||
echo ""
|
||
echo " 4️⃣ FORK THE FRAMEWORK"
|
||
echo " If you need to preserve framework modifications permanently:"
|
||
echo ""
|
||
echo " php artisan rsx:man framework_fork"
|
||
echo ""
|
||
echo " This documents taking full control of the framework codebase."
|
||
echo ""
|
||
echo "════════════════════════════════════════════════════════════════════════════════"
|
||
echo "Note to LLM agents:"
|
||
echo "════════════════════════════════════════════════════════════════════════════════"
|
||
echo ""
|
||
echo "You have attempted to update the framework with uncommitted changes present."
|
||
echo ""
|
||
echo "REQUIRED ACTIONS:"
|
||
echo ""
|
||
echo " 1. Show the developer the full list of uncommitted files above"
|
||
echo " 2. Run 'git diff' to show what changed in those files"
|
||
echo " 3. Ask the developer explicitly: 'These framework files were modified."
|
||
echo " Do you want me to discard these changes and update the framework,"
|
||
echo " or stash them and proceed with the update?'"
|
||
echo ""
|
||
echo "You MUST NOT proceed until the developer has made a decision."
|
||
echo "You MUST NOT automatically use --stash-changes without explicit permission."
|
||
echo ""
|
||
echo "════════════════════════════════════════════════════════════════════════════════"
|
||
exit 1
|
||
else
|
||
# Stash changes with descriptive message
|
||
echo ""
|
||
echo "⚠️ Stashing uncommitted framework changes..."
|
||
echo ""
|
||
STASH_MESSAGE="Auto-stashed by framework update with --stash-changes on $(date '+%Y-%m-%d %H:%M:%S')"
|
||
|
||
if ! git stash push -u -m "$STASH_MESSAGE" -- . ":(exclude)rsx" 2>&1; then
|
||
echo "ERROR: Failed to stash changes"
|
||
exit 1
|
||
fi
|
||
|
||
echo " ✓ Changes stashed"
|
||
echo ""
|
||
echo "Your changes have been saved. After update completes, you can review them:"
|
||
echo " git stash list"
|
||
echo " git stash show"
|
||
echo " git stash pop (to restore changes)"
|
||
echo ""
|
||
fi
|
||
fi
|
||
fi
|
||
|
||
# Extract and display changelog
|
||
echo ""
|
||
echo "⚠ RSpade framework has upstream changes"
|
||
echo ""
|
||
|
||
# Get commit subjects, filter out Claude Code attribution and blank lines
|
||
CHANGELOG=$(git log --pretty=format:"%s" HEAD.."$UPSTREAM_BRANCH" 2>&1 | \
|
||
grep -v "Claude Code" | \
|
||
grep -v "Co-Authored-By:" | \
|
||
grep -v "^$" | \
|
||
sed 's/^/ • /')
|
||
|
||
if [ -n "$CHANGELOG" ]; then
|
||
echo "Changelog:"
|
||
echo ""
|
||
echo "$CHANGELOG"
|
||
echo ""
|
||
fi
|
||
|
||
# Show file diff stats (exclude ./rsx if in project mode)
|
||
if [ "$IS_PROJECT_MODE" = true ]; then
|
||
DIFF_STATS=$(git diff --stat HEAD.."$UPSTREAM_BRANCH" -- . ":(exclude)rsx" 2>&1)
|
||
else
|
||
DIFF_STATS=$(git diff --stat HEAD.."$UPSTREAM_BRANCH" 2>&1)
|
||
fi
|
||
|
||
if [ -n "$DIFF_STATS" ]; then
|
||
echo "Files that will be updated:"
|
||
echo ""
|
||
echo "$DIFF_STATS" | sed 's/^/ /'
|
||
echo ""
|
||
fi
|
||
|
||
# Apply updates based on mode
|
||
echo "Applying framework updates..."
|
||
|
||
if [ "$IS_PROJECT_MODE" = true ]; then
|
||
# Project mode: merge with --no-ff (preserves ./rsx via .gitattributes)
|
||
if ! git merge --no-ff "$UPSTREAM_BRANCH" 2>&1; then
|
||
echo "ERROR: Framework update failed."
|
||
echo ""
|
||
|
||
# Show current git state
|
||
GIT_STATUS=$(git status --short 2>&1)
|
||
if [ -n "$GIT_STATUS" ]; then
|
||
echo "Current git state:"
|
||
echo ""
|
||
echo "$GIT_STATUS" | sed 's/^/ /'
|
||
echo ""
|
||
fi
|
||
|
||
echo "Check status: php artisan rsx:framework:status"
|
||
exit 1
|
||
fi
|
||
echo " ✓ Framework updated (./rsx preserved by .gitattributes)"
|
||
else
|
||
# Framework mode: fast-forward only (updates everything including ./rsx)
|
||
MERGE_OUTPUT=$(git merge --ff-only "$UPSTREAM_BRANCH" 2>&1) || {
|
||
if echo "$MERGE_OUTPUT" | grep -q "up to date\|up-to-date"; then
|
||
echo " ✓ Already up to date"
|
||
else
|
||
echo "ERROR: Framework update failed."
|
||
echo ""
|
||
echo "ERROR: Cannot fast-forward: you have local modifications"
|
||
echo ""
|
||
|
||
# Show modified files
|
||
GIT_STATUS=$(git status --short 2>&1)
|
||
if [ -n "$GIT_STATUS" ]; then
|
||
echo "Modified files blocking update:"
|
||
echo ""
|
||
echo "$GIT_STATUS" | sed 's/^/ /'
|
||
echo ""
|
||
fi
|
||
|
||
echo "To resolve, either:"
|
||
echo " 1. Commit your changes and try again"
|
||
echo " 2. Discard modifications: git reset --hard $UPSTREAM_BRANCH"
|
||
echo " 3. Check status: php artisan rsx:framework:status"
|
||
exit 1
|
||
fi
|
||
}
|
||
echo " ✓ Framework updated"
|
||
fi
|
||
|
||
echo ""
|
||
echo "✓ Framework updated successfully"
|
||
echo ""
|
||
|
||
if [ "$IS_PROJECT_MODE" = true ]; then
|
||
echo "Your application code in ./rsx was preserved."
|
||
echo ""
|
||
fi
|
||
|
||
# Rebuild caches after framework update
|
||
if [ "$NO_REBUILD" = true ]; then
|
||
echo "⚠️ Cleaning caches only (--no-rebuild specified)"
|
||
echo ""
|
||
|
||
if ! php artisan rsx:clean; then
|
||
echo "ERROR: Cache clean failed"
|
||
exit 1
|
||
fi
|
||
echo " ✓ Caches cleaned"
|
||
echo ""
|
||
|
||
echo "⚠ Manifest and bundles NOT rebuilt - you must run manually:"
|
||
echo " php artisan rsx:manifest:build"
|
||
echo " php artisan rsx:bundle:compile"
|
||
echo ""
|
||
else
|
||
echo "⚠️ Regenerating framework caches"
|
||
echo ""
|
||
echo " This rebuild is only required because the framework itself was updated."
|
||
echo " Never run these commands manually unless there are catastrophic errors."
|
||
echo ""
|
||
|
||
# Step 1: Clean caches
|
||
echo "Step 1/3: Cleaning caches..."
|
||
if ! php artisan rsx:clean; then
|
||
echo "ERROR: Cache clean failed"
|
||
exit 1
|
||
fi
|
||
echo " ✓ Caches cleaned"
|
||
echo ""
|
||
|
||
# Step 2: Rebuild manifest
|
||
echo "Step 2/3: Rebuilding manifest..."
|
||
if ! php artisan rsx:manifest:build; then
|
||
echo "ERROR: Manifest rebuild failed"
|
||
echo " Run manually: php artisan rsx:manifest:build"
|
||
exit 1
|
||
fi
|
||
echo " ✓ Manifest rebuilt"
|
||
echo ""
|
||
|
||
# Step 3: Compile bundles
|
||
echo "Step 3/3: Compiling all bundles..."
|
||
if ! php artisan rsx:bundle:compile; then
|
||
echo "ERROR: Bundle compilation failed"
|
||
echo " Check errors above and fix bundle issues"
|
||
exit 1
|
||
fi
|
||
echo " ✓ All bundles compiled"
|
||
echo ""
|
||
fi
|
||
|
||
echo "✅ Framework update complete"
|
||
echo ""
|
||
|
||
exit 0
|