Application.php 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Symfony\Bundle\FrameworkBundle\Console;
  11. use Symfony\Component\Console\Application as BaseApplication;
  12. use Symfony\Component\Console\Command\Command;
  13. use Symfony\Component\Console\Command\ListCommand;
  14. use Symfony\Component\Console\Input\InputInterface;
  15. use Symfony\Component\Console\Input\InputOption;
  16. use Symfony\Component\Console\Output\ConsoleOutputInterface;
  17. use Symfony\Component\Console\Output\OutputInterface;
  18. use Symfony\Component\Console\Style\SymfonyStyle;
  19. use Symfony\Component\DependencyInjection\ContainerAwareInterface;
  20. use Symfony\Component\HttpKernel\Bundle\Bundle;
  21. use Symfony\Component\HttpKernel\Kernel;
  22. use Symfony\Component\HttpKernel\KernelInterface;
  23. /**
  24. * @author Fabien Potencier <fabien@symfony.com>
  25. */
  26. class Application extends BaseApplication
  27. {
  28. private $kernel;
  29. private $commandsRegistered = false;
  30. private $registrationErrors = [];
  31. public function __construct(KernelInterface $kernel)
  32. {
  33. $this->kernel = $kernel;
  34. parent::__construct('Symfony', Kernel::VERSION);
  35. $inputDefinition = $this->getDefinition();
  36. $inputDefinition->addOption(new InputOption('--env', '-e', InputOption::VALUE_REQUIRED, 'The Environment name.', $kernel->getEnvironment()));
  37. $inputDefinition->addOption(new InputOption('--no-debug', null, InputOption::VALUE_NONE, 'Switch off debug mode.'));
  38. }
  39. /**
  40. * Gets the Kernel associated with this Console.
  41. *
  42. * @return KernelInterface A KernelInterface instance
  43. */
  44. public function getKernel()
  45. {
  46. return $this->kernel;
  47. }
  48. /**
  49. * {@inheritdoc}
  50. */
  51. public function reset()
  52. {
  53. if ($this->kernel->getContainer()->has('services_resetter')) {
  54. $this->kernel->getContainer()->get('services_resetter')->reset();
  55. }
  56. }
  57. /**
  58. * Runs the current application.
  59. *
  60. * @return int 0 if everything went fine, or an error code
  61. */
  62. public function doRun(InputInterface $input, OutputInterface $output)
  63. {
  64. $this->registerCommands();
  65. if ($this->registrationErrors) {
  66. $this->renderRegistrationErrors($input, $output);
  67. }
  68. $this->setDispatcher($this->kernel->getContainer()->get('event_dispatcher'));
  69. return parent::doRun($input, $output);
  70. }
  71. /**
  72. * {@inheritdoc}
  73. */
  74. protected function doRunCommand(Command $command, InputInterface $input, OutputInterface $output)
  75. {
  76. if (!$command instanceof ListCommand) {
  77. if ($this->registrationErrors) {
  78. $this->renderRegistrationErrors($input, $output);
  79. $this->registrationErrors = [];
  80. }
  81. return parent::doRunCommand($command, $input, $output);
  82. }
  83. $returnCode = parent::doRunCommand($command, $input, $output);
  84. if ($this->registrationErrors) {
  85. $this->renderRegistrationErrors($input, $output);
  86. $this->registrationErrors = [];
  87. }
  88. return $returnCode;
  89. }
  90. /**
  91. * {@inheritdoc}
  92. */
  93. public function find($name)
  94. {
  95. $this->registerCommands();
  96. return parent::find($name);
  97. }
  98. /**
  99. * {@inheritdoc}
  100. */
  101. public function get($name)
  102. {
  103. $this->registerCommands();
  104. $command = parent::get($name);
  105. if ($command instanceof ContainerAwareInterface) {
  106. $command->setContainer($this->kernel->getContainer());
  107. }
  108. return $command;
  109. }
  110. /**
  111. * {@inheritdoc}
  112. */
  113. public function all($namespace = null)
  114. {
  115. $this->registerCommands();
  116. return parent::all($namespace);
  117. }
  118. /**
  119. * {@inheritdoc}
  120. */
  121. public function getLongVersion()
  122. {
  123. return parent::getLongVersion().sprintf(' (env: <comment>%s</>, debug: <comment>%s</>)', $this->kernel->getEnvironment(), $this->kernel->isDebug() ? 'true' : 'false');
  124. }
  125. public function add(Command $command)
  126. {
  127. $this->registerCommands();
  128. return parent::add($command);
  129. }
  130. protected function registerCommands()
  131. {
  132. if ($this->commandsRegistered) {
  133. return;
  134. }
  135. $this->commandsRegistered = true;
  136. $this->kernel->boot();
  137. $container = $this->kernel->getContainer();
  138. foreach ($this->kernel->getBundles() as $bundle) {
  139. if ($bundle instanceof Bundle) {
  140. try {
  141. $bundle->registerCommands($this);
  142. } catch (\Throwable $e) {
  143. $this->registrationErrors[] = $e;
  144. }
  145. }
  146. }
  147. if ($container->has('console.command_loader')) {
  148. $this->setCommandLoader($container->get('console.command_loader'));
  149. }
  150. if ($container->hasParameter('console.command.ids')) {
  151. $lazyCommandIds = $container->hasParameter('console.lazy_command.ids') ? $container->getParameter('console.lazy_command.ids') : [];
  152. foreach ($container->getParameter('console.command.ids') as $id) {
  153. if (!isset($lazyCommandIds[$id])) {
  154. try {
  155. $this->add($container->get($id));
  156. } catch (\Throwable $e) {
  157. $this->registrationErrors[] = $e;
  158. }
  159. }
  160. }
  161. }
  162. }
  163. private function renderRegistrationErrors(InputInterface $input, OutputInterface $output)
  164. {
  165. if ($output instanceof ConsoleOutputInterface) {
  166. $output = $output->getErrorOutput();
  167. }
  168. (new SymfonyStyle($input, $output))->warning('Some commands could not be registered:');
  169. foreach ($this->registrationErrors as $error) {
  170. $this->doRenderThrowable($error, $output);
  171. }
  172. }
  173. }