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>
242 lines
7.5 KiB
PHP
Executable File
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());
|
|
}
|
|
}
|
|
}
|
|
}
|