#!/usr/bin/env php kernel()->boot(); // Get the container $container = $app->container(); // Create Symfony Console Application $console = new ConsoleApplication('Ktrix Console', Kernel::VERSION); // Collect all command classes $commandClasses = []; // Collect commands from modules /** @var ModuleManager $moduleManager */ $moduleManager = $container->get(ModuleManager::class); foreach ($moduleManager->list() as $module) { $moduleInstance = $module->instance(); // Skip if module instance is not available if ($moduleInstance === null) { continue; } // Check if module implements console command provider if ($moduleInstance instanceof ModuleConsoleInterface) { try { $commands = $moduleInstance->registerCI(); foreach ($commands as $commandClass) { if (!class_exists($commandClass)) { fwrite(STDERR, "Warning: Command class not found: {$commandClass}\n"); continue; } $commandClasses[] = $commandClass; } } catch (\Throwable $e) { fwrite(STDERR, "Warning: Failed to load commands from module {$module->handle()}: {$e->getMessage()}\n"); } } } // Register commands using lazy loading foreach ($commandClasses as $commandClass) { try { // Use reflection to read #[AsCommand] attribute without instantiation $reflection = new \ReflectionClass($commandClass); $attributes = $reflection->getAttributes(\Symfony\Component\Console\Attribute\AsCommand::class); if (empty($attributes)) { fwrite(STDERR, "Warning: Command {$commandClass} missing #[AsCommand] attribute\n"); continue; } // Get attribute instance /** @var \Symfony\Component\Console\Attribute\AsCommand $commandAttr */ $commandAttr = $attributes[0]->newInstance(); // Create lazy command wrapper that defers instantiation $lazyCommand = new LazyCommand( $commandAttr->name, [], $commandAttr->description ?? '', $commandAttr->hidden ?? false, fn() => $container->get($commandClass) // Only instantiate when executed ); $console->add($lazyCommand); } catch (\Throwable $e) { fwrite(STDERR, "Warning: Failed to register command {$commandClass}: {$e->getMessage()}\n"); } } // Run the console application $exitCode = $console->run(); exit($exitCode); } catch (\Throwable $e) { fwrite(STDERR, "Fatal error: " . $e->getMessage() . "\n"); if (isset($app) && $app->debug()) { fwrite(STDERR, $e->getTraceAsString() . "\n"); } exit(1); }