Standardize settings file naming and relocate documentation files Fix code quality violations from rsx:check Reorganize user_management directory into logical subdirectories Move Quill Bundle to core and align with Tom Select pattern Simplify Site Settings page to focus on core site information Complete Phase 5: Multi-tenant authentication with login flow and site selection Add route query parameter rule and synchronize filename validation logic Fix critical bug in UpdateNpmCommand causing missing JavaScript stubs Implement filename convention rule and resolve VS Code auto-rename conflict Implement js-sanitizer RPC server to eliminate 900+ Node.js process spawns Implement RPC server architecture for JavaScript parsing WIP: Add RPC server infrastructure for JS parsing (partial implementation) Update jqhtml terminology from destroy to stop, fix datagrid DOM preservation Add JQHTML-CLASS-01 rule and fix redundant class names Improve code quality rules and resolve violations Remove legacy fatal error format in favor of unified 'fatal' error type Filter internal keys from window.rsxapp output Update button styling and comprehensive form/modal documentation Add conditional fly-in animation for modals Fix non-deterministic bundle compilation 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
166 lines
6.1 KiB
PHP
Executable File
166 lines
6.1 KiB
PHP
Executable File
<?php
|
|
/**
|
|
* CODING CONVENTION:
|
|
* This file follows the coding convention where variable_names and function_names
|
|
* use snake_case (underscore_wherever_possible).
|
|
*/
|
|
|
|
namespace App\RSpade\Commands\Rsx;
|
|
|
|
use App\Console\Commands\FrameworkDeveloperCommand;
|
|
use App\RSpade\Core\Manifest\Manifest;
|
|
|
|
class Manifest_Build_Command extends FrameworkDeveloperCommand
|
|
{
|
|
/**
|
|
* The name and signature of the console command.
|
|
*
|
|
* @var string
|
|
*/
|
|
protected $signature = 'rsx:manifest:build
|
|
{--force : Execute rsx:clean then rsx:manifest:build via PHP exec}
|
|
{--clean : Clear all caches before building (forces complete rebuild)}
|
|
{--build-debug : Enable verbose build output (shows file-by-file processing)}';
|
|
|
|
/**
|
|
* The console command description.
|
|
*
|
|
* @var string
|
|
*/
|
|
protected $description = 'Build or rebuild the RSX manifest (incremental by default, use --clean for full rebuild)';
|
|
|
|
/**
|
|
* Create a new command instance
|
|
*/
|
|
public function __construct()
|
|
{
|
|
parent::__construct();
|
|
|
|
// Check if --build-debug flag is present in command line args
|
|
// Define BUILD_DEBUG_MODE early so it's set before service providers boot
|
|
if (in_array('--build-debug', $_SERVER['argv'] ?? [])) {
|
|
define('BUILD_DEBUG_MODE', true);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Execute the console command.
|
|
*
|
|
* @return int
|
|
*/
|
|
public function handle()
|
|
{
|
|
// Prevent being called via $this->call() - must use passthru for fresh process
|
|
$this->prevent_call_from_another_command();
|
|
|
|
// Handle --force flag: complete clean and rebuild via exec
|
|
if ($this->option('force')) {
|
|
// Execute rsx:clean
|
|
passthru('php artisan rsx:clean');
|
|
|
|
// Execute rsx:manifest:build without --force to avoid recursion
|
|
passthru('php artisan rsx:manifest:build');
|
|
|
|
// Immediately exit
|
|
die();
|
|
}
|
|
|
|
// Check if in production mode with existing manifest
|
|
if (config('app.env') === 'production') {
|
|
$manifest_file = base_path('storage/rsx-build/manifest_data.php');
|
|
|
|
if (file_exists($manifest_file)) {
|
|
$file_age = time() - filemtime($manifest_file);
|
|
|
|
// If manifest exists and is older than 5 seconds, block rebuild
|
|
if ($file_age > 5) {
|
|
$this->error('Production manifest rebuild blocked');
|
|
$this->line('');
|
|
$this->line('The manifest file exists in production and is ' . round($file_age / 60, 1) . ' minutes old.');
|
|
$this->line('Rebuilding the manifest in production is not permitted without explicit confirmation.');
|
|
$this->line('');
|
|
$this->line('Use --force flag to override this protection and rebuild anyway.');
|
|
return 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
$start_time = microtime(true);
|
|
|
|
// Reset debug options
|
|
Manifest::$_debug_options = [];
|
|
|
|
// Handle --clean flag: clear caches first
|
|
if ($this->option('clean')) {
|
|
$this->info('🧹 Clearing caches before build...');
|
|
// Clear RSX caches (but not persistent directory)
|
|
passthru('php artisan rsx:clean');
|
|
Manifest::clear();
|
|
}
|
|
|
|
$this->info('Building RSX manifest...');
|
|
|
|
// Default behavior: incremental build (don't clear unless --clean was used)
|
|
// Manifest::init() handles everything - loading cache and doing incremental updates
|
|
Manifest::init();
|
|
$stats = Manifest::get_stats();
|
|
|
|
$elapsed = round((microtime(true) - $start_time) * 1000, 2);
|
|
|
|
$this->info('Manifest built successfully!');
|
|
$this->line('');
|
|
$this->line('Summary:');
|
|
$this->line(' Build Hash: ' . Manifest::get_build_key());
|
|
$this->line(' Total Files: ' . $stats['total_files']);
|
|
$this->line(' PHP Classes: ' . $stats['php']);
|
|
$this->line(' JS Classes: ' . $stats['js']);
|
|
$this->line(' Blade Views: ' . $stats['blade']);
|
|
$this->line(' Build Time: ' . $elapsed . 'ms');
|
|
|
|
// Reset debug options
|
|
Manifest::$_debug_options = [];
|
|
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* Prevent this command from being called via $this->call() from another command
|
|
*
|
|
* This command MUST run in a fresh process to ensure in-memory caches are cleared.
|
|
* Use passthru() instead of $this->call() when calling from other commands.
|
|
*
|
|
* @return void
|
|
*/
|
|
protected function prevent_call_from_another_command()
|
|
{
|
|
$trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 20);
|
|
|
|
foreach ($trace as $frame) {
|
|
// Check if we're being called from Artisan::call() or Command::call()
|
|
if (isset($frame['class']) && isset($frame['function'])) {
|
|
$class = $frame['class'];
|
|
$function = $frame['function'];
|
|
|
|
// Detect $this->call() from another command
|
|
if ($function === 'call' && str_contains($class, 'Command')) {
|
|
$this->error('');
|
|
$this->error('❌ FATAL ERROR: rsx:manifest:build cannot be called via $this->call()');
|
|
$this->error('');
|
|
$this->error('This command MUST run in a fresh process to properly clear in-memory caches.');
|
|
$this->error('');
|
|
$this->error('FIX: Use passthru() instead of $this->call():');
|
|
$this->error('');
|
|
$this->line(' // ❌ WRONG - runs in same process, caches remain in memory');
|
|
$this->line(' $this->call(\'rsx:manifest:build\');');
|
|
$this->error('');
|
|
$this->line(' // ✅ CORRECT - fresh process, all caches cleared');
|
|
$this->line(' passthru(\'php artisan rsx:manifest:build\');');
|
|
$this->error('');
|
|
|
|
exit(1);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|