From 778a7169a622722ec067d0a380981aed67d699b6 Mon Sep 17 00:00:00 2001 From: Greg Anderson Date: Sun, 30 Apr 2023 12:43:34 -0700 Subject: [PATCH] Move register command out of runner and into Robo class. (#1143) * Move register to Robo class * Restore Runner::instantiateCommandClass for backwards compatibility --- src/Robo.php | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/Runner.php | 53 +++++------------------------------- 2 files changed, 79 insertions(+), 47 deletions(-) diff --git a/src/Robo.php b/src/Robo.php index 313c38b0..3e22594a 100644 --- a/src/Robo.php +++ b/src/Robo.php @@ -4,14 +4,18 @@ use Composer\Autoload\ClassLoader; use League\Container\Container; +use League\Container\ContainerAwareInterface; use League\Container\Definition\DefinitionInterface; use Psr\Container\ContainerInterface; +use Robo\Collection\CollectionBuilder; use Robo\Common\ProcessExecutor; +use Robo\Contract\BuilderAwareInterface; use Consolidation\Config\ConfigInterface; use Consolidation\Config\Loader\ConfigProcessor; use Consolidation\Config\Loader\YamlConfigLoader; use Symfony\Component\Console\Input\StringInput; use Symfony\Component\Console\Application as SymfonyApplication; +use Symfony\Component\Console\Command\Command; use Symfony\Component\Process\Process; /** @@ -498,4 +502,73 @@ public static function process(Process $process) { return ProcessExecutor::create(static::getContainer(), $process); } + + /** + * @param \Robo\Application $app + * @param string|object $handler + * + * @return null|object + */ + public static function register($app, $handler) + { + $container = Robo::getContainer(); + $instance = static::instantiate($handler); + if (!$instance) { + return; + } + + // If the instance is a Symfony Command, register it with + // the application + if ($instance instanceof Command) { + $app->add($instance); + return $instance; + } + + // Register commands for all of the public methods in the RoboFile. + $commandFactory = $container->get('commandFactory'); + $commandList = $commandFactory->createCommandsFromClass($instance); + foreach ($commandList as $command) { + $app->add($command); + } + return $instance; + } + + /** + * @param string|object $handler + * + * @return null|object + */ + protected static function instantiate($handler) + { + $container = Robo::getContainer(); + + // Register the RoboFile with the container and then immediately + // fetch it; this ensures that all of the inflectors will run. + // If the command class is already an instantiated object, then + // just use it exactly as it was provided to us. + if (is_string($handler)) { + if (!class_exists($handler)) { + return; + } + $reflectionClass = new \ReflectionClass($handler); + if ($reflectionClass->isAbstract()) { + return; + } + + $commandFileName = "{$handler}Commands"; + Robo::addShared($container, $commandFileName, $handler); + $handler = $container->get($commandFileName); + } + // If the command class is a Builder Aware Interface, then + // ensure that it has a builder. Every command class needs + // its own collection builder, as they have references to each other. + if ($handler instanceof BuilderAwareInterface) { + $builder = CollectionBuilder::create($container, $handler); + $handler->setBuilder($builder); + } + if ($handler instanceof ContainerAwareInterface) { + $handler->setContainer($container); + } + return $handler; + } } diff --git a/src/Runner.php b/src/Runner.php index d8803ebe..c0ab62fb 100644 --- a/src/Runner.php +++ b/src/Runner.php @@ -316,7 +316,7 @@ protected function getRoboFileCommands($output) public function registerCommandClasses($app, $commandClasses) { foreach ((array)$commandClasses as $commandClass) { - $this->registerCommandClass($app, $commandClass); + Robo::register($app, $commandClass); } } @@ -338,62 +338,21 @@ protected function discoverCommandClasses($relativeNamespace) * @param \Robo\Application $app * @param string|BuilderAwareInterface|ContainerAwareInterface $commandClass * + * @deprecated Use Robo::register directly + * * @return null|object */ public function registerCommandClass($app, $commandClass) { - $container = Robo::getContainer(); - $roboCommandFileInstance = $this->instantiateCommandClass($commandClass); - if (!$roboCommandFileInstance) { - return; - } - - // Register commands for all of the public methods in the RoboFile. - $commandFactory = $container->get('commandFactory'); - $commandList = $commandFactory->createCommandsFromClass($roboCommandFileInstance); - foreach ($commandList as $command) { - $app->add($command); - } - return $roboCommandFileInstance; + return Robo::register($app, $commandClass); } /** - * @param string|\Robo\Contract\BuilderAwareInterface|\League\Container\ContainerAwareInterface $commandClass - * - * @return null|object + * @deprecated Use Robo::instantiate directly */ protected function instantiateCommandClass($commandClass) { - $container = Robo::getContainer(); - - // Register the RoboFile with the container and then immediately - // fetch it; this ensures that all of the inflectors will run. - // If the command class is already an instantiated object, then - // just use it exactly as it was provided to us. - if (is_string($commandClass)) { - if (!class_exists($commandClass)) { - return; - } - $reflectionClass = new \ReflectionClass($commandClass); - if ($reflectionClass->isAbstract()) { - return; - } - - $commandFileName = "{$commandClass}Commands"; - Robo::addShared($container, $commandFileName, $commandClass); - $commandClass = $container->get($commandFileName); - } - // If the command class is a Builder Aware Interface, then - // ensure that it has a builder. Every command class needs - // its own collection builder, as they have references to each other. - if ($commandClass instanceof BuilderAwareInterface) { - $builder = CollectionBuilder::create($container, $commandClass); - $commandClass->setBuilder($builder); - } - if ($commandClass instanceof ContainerAwareInterface) { - $commandClass->setContainer($container); - } - return $commandClass; + return Robo::instantiate($commandClass); } public function installRoboHandlers()