Add 100+ automated unit tests from .expect file specifications Add session system test Add rsx:constants:regenerate command test Add rsx:logrotate command test Add rsx:clean command test Add rsx:manifest:stats command test Add model enum system test Add model mass assignment prevention test Add rsx:check command test Add migrate:status command test 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
109 lines
3.3 KiB
PHP
109 lines
3.3 KiB
PHP
<?php
|
|
|
|
namespace App\RSpade\Commands\Rsx;
|
|
|
|
use Illuminate\Console\Command;
|
|
use Illuminate\Support\Str;
|
|
use App\RSpade\Core\CodeTemplates\StubProcessor;
|
|
|
|
class Module_Create_Command extends Command
|
|
{
|
|
/**
|
|
* The name and signature of the console command.
|
|
*
|
|
* @var string
|
|
*/
|
|
protected $signature = 'rsx:app:module:create
|
|
{name : Module name (lowercase with underscores)}';
|
|
|
|
/**
|
|
* The console command description.
|
|
*
|
|
* @var string
|
|
*/
|
|
protected $description = 'Create a new module (top-level section with shared layout). Example: frontend, admin';
|
|
|
|
/**
|
|
* Execute the console command.
|
|
*
|
|
* @return int
|
|
*/
|
|
public function handle()
|
|
{
|
|
$module_name = $this->argument('name');
|
|
|
|
// Validate module name (lowercase and underscores only)
|
|
if (!preg_match('/^[a-z_]+$/', $module_name)) {
|
|
$this->error('Module name must contain only lowercase letters and underscores.');
|
|
return 1;
|
|
}
|
|
|
|
// Check if module already exists
|
|
$module_path = base_path("rsx/app/{$module_name}");
|
|
if (is_dir($module_path)) {
|
|
$this->error("Module '{$module_name}' already exists at: rsx/app/{$module_name}");
|
|
return 1;
|
|
}
|
|
|
|
// Create module directory
|
|
if (!mkdir($module_path, 0755, true)) {
|
|
$this->error("Failed to create module directory: {$module_path}");
|
|
return 1;
|
|
}
|
|
|
|
$this->info("Created module directory: rsx/app/{$module_name}");
|
|
|
|
// Generate replacements
|
|
$replacements = StubProcessor::generate_replacements($module_name);
|
|
|
|
try {
|
|
// Create bundle file
|
|
$bundle_content = StubProcessor::process('bundle', $replacements);
|
|
$bundle_path = "{$module_path}/{$module_name}_bundle.php";
|
|
file_put_contents($bundle_path, $bundle_content);
|
|
$this->info("Created bundle: {$module_name}_bundle.php");
|
|
|
|
// Create layout file
|
|
$layout_content = StubProcessor::process('module_layout', $replacements);
|
|
$layout_path = "{$module_path}/{$module_name}_layout.blade.php";
|
|
file_put_contents($layout_path, $layout_content);
|
|
$this->info("Created layout: {$module_name}_layout.blade.php");
|
|
|
|
// Create default index feature
|
|
$this->call('rsx:app:module:feature:create', [
|
|
'module' => $module_name,
|
|
'feature' => 'index'
|
|
]);
|
|
|
|
} catch (\Exception $e) {
|
|
$this->error("Failed to create module: " . $e->getMessage());
|
|
// Clean up on failure
|
|
if (is_dir($module_path)) {
|
|
$this->cleanup_directory($module_path);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
$this->info("✅ Module '{$module_name}' created successfully!");
|
|
$this->info("Route: /{$module_name}");
|
|
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* Clean up directory on failure
|
|
*/
|
|
protected function cleanup_directory($dir)
|
|
{
|
|
if (!is_dir($dir)) {
|
|
return;
|
|
}
|
|
|
|
$files = array_diff(scandir($dir), ['.', '..']);
|
|
foreach ($files as $file) {
|
|
$path = $dir . '/' . $file;
|
|
is_dir($path) ? $this->cleanup_directory($path) : unlink($path);
|
|
}
|
|
rmdir($dir);
|
|
}
|
|
} |