From 94c68861cc504c0a162244acf79db1b0af593b7a Mon Sep 17 00:00:00 2001 From: root Date: Tue, 21 Oct 2025 05:00:27 +0000 Subject: [PATCH] Add --framework-only flag to migrate command and enhance framework-pull MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit šŸ¤– Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- app/RSpade/Commands/Migrate/Maint_Migrate.php | 44 +++-- bin/framework-pull-upstream.sh | 171 +++++++++++++++--- 2 files changed, 178 insertions(+), 37 deletions(-) diff --git a/app/RSpade/Commands/Migrate/Maint_Migrate.php b/app/RSpade/Commands/Migrate/Maint_Migrate.php index f2f383fcd..6b72cadb0 100755 --- a/app/RSpade/Commands/Migrate/Maint_Migrate.php +++ b/app/RSpade/Commands/Migrate/Maint_Migrate.php @@ -33,7 +33,7 @@ use App\RSpade\Core\Database\SqlQueryTransformer; */ class Maint_Migrate extends Command { - protected $signature = 'migrate {--force} {--seed} {--step} {--path=*} {--production : Run in production mode, skipping snapshot requirements}'; + protected $signature = 'migrate {--force} {--seed} {--step} {--path=*} {--production : Run in production mode, skipping snapshot requirements} {--framework-only : Run only framework migrations (system/database/migrations), skip snapshot, but run normalization}'; protected $description = 'Run migrations and maintenance commands'; @@ -54,8 +54,11 @@ class Maint_Migrate extends Command // Check if we're in production mode (either via flag or environment) $is_production = $this->option('production') || app()->environment('production'); - // Only enforce snapshot protection in development mode without --production flag - $require_snapshot = !$is_production; + // Check if we're in framework-only mode + $is_framework_only = $this->option('framework-only'); + + // Only enforce snapshot protection in development mode without --production or --framework-only flag + $require_snapshot = !$is_production && !$is_framework_only; // Check for migration mode if we require snapshot if ($require_snapshot) { @@ -80,9 +83,12 @@ class Maint_Migrate extends Command $this->info(''); } elseif ($is_production) { $this->info('šŸš€ Running in production mode (no snapshot protection)'); + } elseif ($is_framework_only) { + $this->info('šŸ”§ Running framework-only migrations (no snapshot protection)'); } - $this->info('Running migrations' . ($is_production ? ' (production mode)' : ' with maintenance commands') . '...'); + $mode_desc = $is_production ? ' (production mode)' : ($is_framework_only ? ' (framework-only)' : ' with maintenance commands'); + $this->info('Running migrations' . $mode_desc . '...'); // Get all the options $force = $this->option('force'); @@ -104,8 +110,13 @@ class Maint_Migrate extends Command return 1; } + // Determine which migration paths to use for whitelist check + $paths_to_check = $is_framework_only + ? [database_path('migrations')] + : MigrationPaths::get_all_paths(); + // Check migration whitelist - if (!$this->checkMigrationWhitelist()) { + if (!$this->checkMigrationWhitelist($paths_to_check)) { return 1; } @@ -127,7 +138,8 @@ class Maint_Migrate extends Command } // Run normalize_schema BEFORE migrations to fix existing tables - $requiredColumnsArgs = $is_production ? ['--production' => true] : []; + // Pass --production flag to skip snapshot in both production and framework-only modes + $requiredColumnsArgs = ($is_production || $is_framework_only) ? ['--production' => true] : []; $this->info("\nšŸ”§ Pre-migration normalization (fixing existing tables)...\n"); $normalizeExitCode = $this->call('migrate:normalize_schema', $requiredColumnsArgs); @@ -149,8 +161,10 @@ class Maint_Migrate extends Command $migrator = app('migrator'); $migrator->setOutput($bufferedOutput); - // Use all migration paths (framework + user) - $migrationPaths = MigrationPaths::get_all_paths(); + // Use all migration paths (framework + user), or just framework if --framework-only + $migrationPaths = $is_framework_only + ? [database_path('migrations')] + : MigrationPaths::get_all_paths(); // Run migrations one-by-one with normalization after each $this->run_migrations_with_normalization($migrator, $migrationPaths, $step, $requiredColumnsArgs); @@ -231,11 +245,11 @@ class Maint_Migrate extends Command return $normalizeExitCode; } - // Only run regenerate constants if not in production mode + // Run regenerate constants if not in production mode (framework-only still runs it) if (!$is_production) { // Disable query logging for regenerate_constants AppServiceProvider::disable_query_echo(); - + $maintenanceExitCode = $this->runMaintenanceCommand('rsx:constants:regenerate'); if ($maintenanceExitCode !== 0) { $this->error('Regenerate constants maintenance failed'); @@ -245,7 +259,7 @@ class Maint_Migrate extends Command // In production mode, check manifest consistency with database // Disable query logging for consistency check AppServiceProvider::disable_query_echo(); - + $this->info("\n"); $consistency_check_exit = $this->call('rsx:migrate:check_consistency'); if ($consistency_check_exit !== 0) { @@ -294,8 +308,10 @@ class Maint_Migrate extends Command /** * Check if all pending migrations are whitelisted + * + * @param array $paths Array of migration paths to check */ - protected function checkMigrationWhitelist(): bool + protected function checkMigrationWhitelist(array $paths): bool { $whitelistPath = database_path('migrations/.migration_whitelist'); @@ -310,9 +326,9 @@ class Maint_Migrate extends Command $whitelist = json_decode(file_get_contents($whitelistPath), true); $whitelistedMigrations = array_keys($whitelist['migrations'] ?? []); - // Get all migration files from all paths + // Get all migration files from specified paths $migrationFiles = []; - foreach (MigrationPaths::get_all_paths() as $path) { + foreach ($paths as $path) { if (is_dir($path)) { foreach (glob($path . '/*.php') as $file) { $migrationFiles[] = basename($file); diff --git a/bin/framework-pull-upstream.sh b/bin/framework-pull-upstream.sh index 5416d8c23..0147ef455 100755 --- a/bin/framework-pull-upstream.sh +++ b/bin/framework-pull-upstream.sh @@ -8,12 +8,21 @@ set -e # Parse arguments NO_REBUILD=false +SHOW_DIFF=false +STASH_CHANGES=false for arg in "$@"; do if [ "$arg" = "--no-rebuild" ]; then NO_REBUILD=true + elif [ "$arg" = "--diff" ]; then + SHOW_DIFF=true + elif [ "$arg" = "--stash" ]; then + STASH_CHANGES=true fi done +# Configure git to ignore file mode changes +git config core.fileMode false + # Determine project mode: Check for .rspade-dev-environment or rsx/.git IS_PROJECT_MODE=false if [ -f ".rspade-dev-environment" ] || [ -d "rsx/.git" ]; then @@ -148,6 +157,15 @@ if [ "$CURRENT_HEAD" = "$UPSTREAM_HEAD" ]; then exit 0 fi +# Handle --diff option: show diff and exit +if [ "$SHOW_DIFF" = true ]; then + echo "" + echo "=== Git Diff: Local Changes vs Upstream ===" + echo "" + git diff HEAD "$UPSTREAM_BRANCH" + 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 @@ -175,7 +193,23 @@ if [ "$IS_PROJECT_MODE" = true ]; then echo "" echo "OPTIONS:" echo "" - echo " 1ļøāƒ£ DISCARD FRAMEWORK CHANGES (recommended)" + echo " 1. VIEW DIFFERENCES" + echo " See what changed between your local files and upstream:" + echo "" + echo " php artisan rsx:framework:pull --diff" + echo "" + echo " 2. STASH CHANGES AND UPDATE (recommended)" + 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" + 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. DISCARD FRAMEWORK CHANGES" echo " If these were accidental edits, reset them:" echo "" echo " git checkout HEAD -- [file paths]" @@ -183,25 +217,14 @@ if [ "$IS_PROJECT_MODE" = true ]; then 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 " 4. 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 " 5. FORK THE FRAMEWORK" echo " If you need to preserve framework modifications permanently:" echo "" echo " php artisan rsx:man framework_fork" @@ -223,7 +246,7 @@ if [ "$IS_PROJECT_MODE" = true ]; then 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 "You MUST NOT automatically use --stash without explicit permission." echo "" echo "════════════════════════════════════════════════════════════════════════════════" exit 1 @@ -232,7 +255,7 @@ if [ "$IS_PROJECT_MODE" = true ]; then 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')" + STASH_MESSAGE="Auto-stashed by framework update with --stash 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" @@ -250,6 +273,84 @@ if [ "$IS_PROJECT_MODE" = true ]; then fi fi +# In framework mode, check for uncommitted changes +if [ "$IS_PROJECT_MODE" = false ]; then + # Get uncommitted changes (modified, staged, deleted) + UNCOMMITTED_CHANGES=$(git diff --name-only 2>&1) + STAGED_CHANGES=$(git diff --cached --name-only 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 changes detected" + echo "════════════════════════════════════════════════════════════════════════════════" + echo "" + echo "You are in FRAMEWORK MODE where this repository is the framework itself." + echo "The following 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. VIEW DIFFERENCES" + echo " See what changed between your local files and upstream:" + echo "" + echo " php artisan rsx:framework:pull --diff" + echo "" + echo " 2. STASH CHANGES AND UPDATE (recommended)" + 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" + 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. DISCARD CHANGES" + echo " If these were accidental edits, reset them:" + echo "" + echo " git reset --hard HEAD" + echo "" + echo " 4. COMMIT THEN UPDATE" + 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 "════════════════════════════════════════════════════════════════════════════════" + exit 1 + else + # Stash changes with descriptive message + echo "" + echo "āš ļø Stashing uncommitted changes..." + echo "" + STASH_MESSAGE="Auto-stashed by framework update with --stash on $(date '+%Y-%m-%d %H:%M:%S')" + + if ! git stash push -u -m "$STASH_MESSAGE" 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" @@ -325,10 +426,24 @@ else 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" + echo "To resolve:" + echo "" + echo " 1. VIEW DIFFERENCES" + echo " php artisan rsx:framework:pull --diff" + echo "" + echo " 2. STASH CHANGES AND UPDATE (recommended)" + echo " php artisan rsx:framework:pull --stash" + echo "" + echo " 3. DISCARD MODIFICATIONS" + echo " git reset --hard $UPSTREAM_BRANCH" + echo "" + echo " 4. COMMIT THEN UPDATE" + echo " git add -A" + echo " git commit -m \"Framework modifications\"" + echo " php artisan rsx:framework:pull" + echo "" + echo " 5. CHECK STATUS" + echo " php artisan rsx:framework:status" exit 1 fi } @@ -368,7 +483,7 @@ else echo "" # Step 1: Clean caches - echo "Step 1/3: Cleaning caches..." + echo "Step 1/4: Cleaning caches..." if ! php artisan rsx:clean; then echo "ERROR: Cache clean failed" exit 1 @@ -377,7 +492,7 @@ else echo "" # Step 2: Rebuild manifest - echo "Step 2/3: Rebuilding manifest..." + echo "Step 2/4: Rebuilding manifest..." if ! php artisan rsx:manifest:build; then echo "ERROR: Manifest rebuild failed" echo " Run manually: php artisan rsx:manifest:build" @@ -387,7 +502,7 @@ else echo "" # Step 3: Compile bundles - echo "Step 3/3: Compiling all bundles..." + echo "Step 3/4: Compiling all bundles..." if ! php artisan rsx:bundle:compile; then echo "ERROR: Bundle compilation failed" echo " Check errors above and fix bundle issues" @@ -395,6 +510,16 @@ else fi echo " āœ“ All bundles compiled" echo "" + + # Step 4: Run framework migrations + echo "Step 4/4: Running framework migrations..." + if ! php artisan migrate --framework-only --force; then + echo "ERROR: Framework migrations failed" + echo " Check errors above and fix migration issues" + exit 1 + fi + echo " āœ“ Framework migrations completed" + echo "" fi # Set read-only attribute on CLAUDE.dist.md after successful update