option('path'); // Resolve relative path from base_path parent (since we're in /system) if (str_starts_with($export_path, './')) { $export_path = dirname(base_path()) . '/' . substr($export_path, 2); } elseif (!str_starts_with($export_path, '/')) { $export_path = dirname(base_path()) . '/' . $export_path; } $this->info('Exporting application for deployment...'); $this->line(" Destination: {$export_path}"); $this->newLine(); // Step 1: Run production build (unless --skip-build) if (!$this->option('skip-build')) { $this->line('[1/3] Running production build...'); passthru('php artisan rsx:prod:build', $exit_code); if ($exit_code !== 0) { $this->error('Production build failed'); return 1; } $this->newLine(); } else { $this->line('[1/3] Skipping production build (--skip-build)'); } // Step 2: Prepare export directory $this->line('[2/3] Preparing export directory...'); // Clear existing export if it exists if (is_dir($export_path)) { $this->line(' Clearing existing export...'); $this->_clear_directory($export_path); } // Create export directory if (!mkdir($export_path, 0755, true) && !is_dir($export_path)) { $this->error("Failed to create export directory: {$export_path}"); return 1; } // Step 3: Copy files $this->line('[3/3] Copying files...'); $base = dirname(base_path()); // Parent of /system $copied_files = 0; $copied_dirs = 0; // Directories to copy $dirs_to_copy = [ 'system' => 'system', 'rsx' => 'rsx', 'node_modules' => 'node_modules', 'vendor' => 'vendor', ]; // Also include rsx-build from storage $storage_rsx_build = base_path('storage/rsx-build'); if (is_dir($storage_rsx_build)) { $dirs_to_copy['system/storage/rsx-build'] = 'system/storage/rsx-build'; } foreach ($dirs_to_copy as $src_rel => $dest_rel) { $src = "{$base}/{$src_rel}"; $dest = "{$export_path}/{$dest_rel}"; if (!is_dir($src)) { $this->warn(" Skipping {$src_rel} (not found)"); continue; } $this->line(" Copying {$src_rel}/..."); $count = $this->_copy_directory($src, $dest, $src_rel); $copied_files += $count; $copied_dirs++; } // Copy *.json files from root $json_files = glob("{$base}/*.json"); foreach ($json_files as $json_file) { $filename = basename($json_file); copy($json_file, "{$export_path}/{$filename}"); $copied_files++; } if (!empty($json_files)) { $this->line(' Copying *.json files...'); } // Create .gitignore for export directory file_put_contents( "{$export_path}/.gitignore", "# This export should not be committed to version control\n*\n" ); $this->newLine(); $this->info("[OK] Export complete"); $this->line(" {$copied_dirs} directories, {$copied_files} files"); $this->line(" Location: {$export_path}"); $this->newLine(); $this->line('Next steps:'); $this->line(' 1. Copy the export directory to your production server'); $this->line(' 2. Configure .env on the production server'); $this->line(' 3. Point your web server to the deployment'); return 0; } /** * Copy a directory recursively, excluding certain paths */ private function _copy_directory(string $src, string $dest, string $rel_path): int { // Paths to exclude (relative to source) $exclude_patterns = [ '.env', '.env.example', 'storage/app', 'storage/logs', 'storage/framework/cache', 'storage/framework/sessions', 'storage/framework/views', 'storage/rsx-tmp', 'rsx-export', '.git', '.idea', '.vscode', 'tests', ]; // For system directory, exclude additional paths if ($rel_path === 'system') { $exclude_patterns[] = 'storage/rsx-tmp'; } if (!is_dir($dest)) { mkdir($dest, 0755, true); } $copied = 0; $iterator = new RecursiveIteratorIterator( new RecursiveDirectoryIterator($src, RecursiveDirectoryIterator::SKIP_DOTS), RecursiveIteratorIterator::SELF_FIRST ); foreach ($iterator as $item) { $sub_path = $iterator->getSubPathname(); // Check exclusions $skip = false; foreach ($exclude_patterns as $pattern) { if (str_starts_with($sub_path, $pattern) || str_contains($sub_path, "/{$pattern}")) { $skip = true; break; } } if ($skip) { continue; } $dest_path = "{$dest}/{$sub_path}"; if ($item->isDir()) { if (!is_dir($dest_path)) { mkdir($dest_path, 0755, true); } } else { // Ensure parent directory exists $parent = dirname($dest_path); if (!is_dir($parent)) { mkdir($parent, 0755, true); } copy($item->getPathname(), $dest_path); $copied++; } } return $copied; } /** * Clear a directory recursively */ private function _clear_directory(string $path): void { if (!is_dir($path)) { return; } $iterator = new RecursiveIteratorIterator( new RecursiveDirectoryIterator($path, RecursiveDirectoryIterator::SKIP_DOTS), RecursiveIteratorIterator::CHILD_FIRST ); foreach ($iterator as $item) { if ($item->isDir()) { rmdir($item->getPathname()); } else { unlink($item->getPathname()); } } rmdir($path); } }