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); } }