Files
rspade_system/app/RSpade/Commands/Rsx/Mode_Set_Command.php
root 2489997e42 Move mode detection from Rsx_Mode to Rsx class
Simplify ajax batching to be mode-based instead of configurable

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-14 22:33:49 +00:00

242 lines
7.5 KiB
PHP
Executable File

<?php
namespace App\RSpade\Commands\Rsx;
use Illuminate\Console\Command;
use App\RSpade\Core\Rsx;
/**
* Set the application mode (development, debug, or production)
*
* Changes the RSX_MODE in .env, clears caches, and rebuilds as appropriate.
*/
class Mode_Set_Command extends Command
{
protected $signature = 'rsx:mode:set
{mode : Mode to set (dev|development|debug|prod|production)}';
protected $description = 'Set the application mode (development, debug, or production)';
public function handle(): int
{
$mode = $this->argument('mode');
// Normalize mode aliases
$normalized = match (strtolower($mode)) {
'dev', 'development' => Rsx::MODE_DEVELOPMENT,
'debug' => Rsx::MODE_DEBUG,
'prod', 'production' => Rsx::MODE_PRODUCTION,
default => null,
};
if ($normalized === null) {
$this->error("Invalid mode: {$mode}");
$this->line('');
$this->line('Valid modes:');
$this->line(' dev, development - Auto-rebuild, full debugging');
$this->line(' debug - Production optimizations with sourcemaps');
$this->line(' prod, production - Full optimization');
return 1;
}
// Check current mode (for display purposes only - always rebuild)
$current_mode = $this->_get_current_env_mode();
if ($current_mode === $normalized) {
$this->info("Rebuilding {$normalized} mode...");
} else {
$this->info("Switching to {$normalized} mode...");
}
$this->newLine();
// Step 1: Update .env file
$this->line(' [1/3] Updating .env...');
$this->_update_env_mode($normalized);
// Clear the cached mode so subsequent calls see the new value
Rsx::clear_mode_cache();
// Step 2: Clear all caches
$this->line(' [2/3] Clearing caches...');
// Clear Laravel caches by deleting files directly (avoids triggering Manifest::init)
$this->_clear_laravel_caches();
// Clear RSX caches directly (avoids triggering Manifest::init via artisan boot)
$this->_clear_rsx_caches();
// Step 3: Build appropriate assets
$this->line(' [3/3] Building assets...');
if ($normalized === Rsx::MODE_DEVELOPMENT) {
// In development, pre-warm the bundle cache
// Explicitly pass RSX_MODE to ensure subprocess uses correct mode
passthru("RSX_MODE={$normalized} php artisan rsx:bundle:compile", $exit_code);
if ($exit_code !== 0) {
$this->warn('Bundle compilation had warnings, but continuing...');
}
} else {
// In debug/production, run the production build
// RSX_FORCE_BUILD allows manifest rebuild even in production mode
// Explicitly pass RSX_MODE to ensure subprocess uses correct mode
passthru("RSX_MODE={$normalized} RSX_FORCE_BUILD=1 php artisan rsx:prod:build", $exit_code);
if ($exit_code !== 0) {
$this->error('Production build failed');
return 1;
}
}
$this->newLine();
$this->info("[OK] Switched to {$normalized} mode");
return 0;
}
/**
* Get current RSX_MODE from .env file (not from env() which may be cached)
*/
private function _get_current_env_mode(): string
{
$env_path = base_path('.env');
if (!file_exists($env_path)) {
return Rsx::MODE_DEVELOPMENT;
}
$contents = file_get_contents($env_path);
if (preg_match('/^RSX_MODE=(.*)$/m', $contents, $matches)) {
return trim($matches[1]);
}
return Rsx::MODE_DEVELOPMENT;
}
/**
* Update RSX_MODE in .env file
*/
private function _update_env_mode(string $mode): void
{
$env_path = base_path('.env');
if (!file_exists($env_path)) {
// Create .env with just RSX_MODE
file_put_contents($env_path, "RSX_MODE={$mode}\n");
return;
}
$contents = file_get_contents($env_path);
if (preg_match('/^RSX_MODE=.*$/m', $contents)) {
// Replace existing RSX_MODE
$contents = preg_replace('/^RSX_MODE=.*$/m', "RSX_MODE={$mode}", $contents);
} else {
// Add RSX_MODE after APP_DEBUG or APP_URL if they exist, otherwise at end
if (preg_match('/^APP_DEBUG=.*$/m', $contents)) {
$contents = preg_replace(
'/^(APP_DEBUG=.*)$/m',
"$1\nRSX_MODE={$mode}",
$contents,
1
);
} elseif (preg_match('/^APP_URL=.*$/m', $contents)) {
$contents = preg_replace(
'/^(APP_URL=.*)$/m',
"$1\nRSX_MODE={$mode}",
$contents,
1
);
} else {
// Append to end
$contents = rtrim($contents) . "\nRSX_MODE={$mode}\n";
}
}
file_put_contents($env_path, $contents);
}
/**
* Clear Laravel caches by deleting files directly
* (Avoids running artisan commands which trigger Manifest::init)
*/
private function _clear_laravel_caches(): void
{
$bootstrap_cache = base_path('bootstrap/cache');
// Config cache
$config_cache = "{$bootstrap_cache}/config.php";
if (file_exists($config_cache)) {
unlink($config_cache);
}
// Route cache
$route_cache = "{$bootstrap_cache}/routes-v7.php";
if (file_exists($route_cache)) {
unlink($route_cache);
}
// Services cache
$services_cache = "{$bootstrap_cache}/services.php";
if (file_exists($services_cache)) {
unlink($services_cache);
}
// Packages cache
$packages_cache = "{$bootstrap_cache}/packages.php";
if (file_exists($packages_cache)) {
unlink($packages_cache);
}
// Compiled views
$views_path = storage_path('framework/views');
if (is_dir($views_path)) {
$files = glob("{$views_path}/*.php");
foreach ($files as $file) {
unlink($file);
}
}
}
/**
* Clear RSX caches by deleting directories directly
* (Avoids running artisan commands which trigger Manifest::init)
*/
private function _clear_rsx_caches(): void
{
// Clear rsx-build directory
$build_path = storage_path('rsx-build');
if (is_dir($build_path)) {
$this->_clear_directory_contents($build_path);
}
// Clear rsx-tmp directory
$tmp_path = storage_path('rsx-tmp');
if (is_dir($tmp_path)) {
$this->_clear_directory_contents($tmp_path);
}
}
/**
* Recursively clear directory contents
*/
private function _clear_directory_contents(string $path): void
{
if (!is_dir($path)) {
return;
}
$files = new \RecursiveIteratorIterator(
new \RecursiveDirectoryIterator($path, \RecursiveDirectoryIterator::SKIP_DOTS),
\RecursiveIteratorIterator::CHILD_FIRST
);
foreach ($files as $file) {
if ($file->isDir()) {
rmdir($file->getRealPath());
} else {
unlink($file->getRealPath());
}
}
}
}