From 0aca5a9bb2f8fc9ee3d22ca854bc84d3f9524036 Mon Sep 17 00:00:00 2001 From: Paras Malhotra Date: Sun, 18 Oct 2020 04:46:39 +0530 Subject: [PATCH 1/2] [9.x] Add support for lazy loading commands --- src/Illuminate/Console/Application.php | 27 ++++++- .../Console/ContainerCommandLoader.php | 72 +++++++++++++++++++ src/Illuminate/Foundation/Console/Kernel.php | 6 +- .../Foundation/Console/stubs/console.stub | 7 ++ 4 files changed, 109 insertions(+), 3 deletions(-) create mode 100644 src/Illuminate/Console/ContainerCommandLoader.php diff --git a/src/Illuminate/Console/Application.php b/src/Illuminate/Console/Application.php index 7066c8485425..e496dcd49977 100755 --- a/src/Illuminate/Console/Application.php +++ b/src/Illuminate/Console/Application.php @@ -46,6 +46,13 @@ class Application extends SymfonyApplication implements ApplicationContract */ protected static $bootstrappers = []; + /** + * A map of command names to classes. + * + * @var array + */ + protected $commandMap = []; + /** * The Event Dispatcher. * @@ -254,10 +261,16 @@ protected function addToParent(SymfonyCommand $command) * Add a command, resolving through the application. * * @param string $command - * @return \Symfony\Component\Console\Command\Command + * @return \Symfony\Component\Console\Command\Command|null */ public function resolve($command) { + if (class_exists($command) && ($commandName = $command::getDefaultName())) { + $this->commandMap[$commandName] = $command; + + return null; + } + return $this->add($this->laravel->make($command)); } @@ -278,6 +291,18 @@ public function resolveCommands($commands) return $this; } + /** + * Set the Container Command Loader + * + * @return $this + */ + public function setContainerCommandLoader() + { + $this->setCommandLoader(new ContainerCommandLoader($this->laravel, $this->commandMap)); + + return $this; + } + /** * Get the default input definition for the application. * diff --git a/src/Illuminate/Console/ContainerCommandLoader.php b/src/Illuminate/Console/ContainerCommandLoader.php new file mode 100644 index 000000000000..3826d7482edb --- /dev/null +++ b/src/Illuminate/Console/ContainerCommandLoader.php @@ -0,0 +1,72 @@ +container = $container; + $this->commandMap = $commandMap; + } + + /** + * Loads a command. + * + * @param string $name + * @return \Symfony\Component\Console\Command\Command + * + * @throws \Symfony\Component\Console\Exception\CommandNotFoundException + */ + public function get(string $name) + { + if (!$this->has($name)) { + throw new CommandNotFoundException(sprintf('Command "%s" does not exist.', $name)); + } + + return $this->container->get($this->commandMap[$name]); + } + + /** + * Checks if a command exists. + * + * @param string $name + * @return bool + */ + public function has(string $name) + { + return $name && isset($this->commandMap[$name]); + } + + /** + * Get the command names. + * + * @return string[] + */ + public function getNames() + { + return array_keys($this->commandMap); + } +} \ No newline at end of file diff --git a/src/Illuminate/Foundation/Console/Kernel.php b/src/Illuminate/Foundation/Console/Kernel.php index e6b0798490e7..0f9534c06c66 100644 --- a/src/Illuminate/Foundation/Console/Kernel.php +++ b/src/Illuminate/Foundation/Console/Kernel.php @@ -327,8 +327,10 @@ public function bootstrap() protected function getArtisan() { if (is_null($this->artisan)) { - return $this->artisan = (new Artisan($this->app, $this->events, $this->app->version())) - ->resolveCommands($this->commands); + $this->artisan = (new Artisan($this->app, $this->events, $this->app->version())) + ->resolveCommands($this->commands); + + return $this->artisan->setContainerCommandLoader(); } return $this->artisan; diff --git a/src/Illuminate/Foundation/Console/stubs/console.stub b/src/Illuminate/Foundation/Console/stubs/console.stub index 0f751a3c75fd..98b48662cdef 100644 --- a/src/Illuminate/Foundation/Console/stubs/console.stub +++ b/src/Illuminate/Foundation/Console/stubs/console.stub @@ -13,6 +13,13 @@ class {{ class }} extends Command */ protected $signature = '{{ command }}'; + /** + * The default command name for lazy loading. + * + * @var string|null + */ + protected static $defaultName = '{{ command }}'; + /** * The console command description. * From 958d02b6c6a0921e783c8bd46d95fe67ce2853a7 Mon Sep 17 00:00:00 2001 From: Paras Malhotra Date: Sun, 18 Oct 2020 05:02:10 +0530 Subject: [PATCH 2/2] fix styleci --- src/Illuminate/Console/Application.php | 2 +- src/Illuminate/Console/ContainerCommandLoader.php | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Illuminate/Console/Application.php b/src/Illuminate/Console/Application.php index e496dcd49977..4f6944369a6e 100755 --- a/src/Illuminate/Console/Application.php +++ b/src/Illuminate/Console/Application.php @@ -292,7 +292,7 @@ public function resolveCommands($commands) } /** - * Set the Container Command Loader + * Set the Container Command Loader. * * @return $this */ diff --git a/src/Illuminate/Console/ContainerCommandLoader.php b/src/Illuminate/Console/ContainerCommandLoader.php index 3826d7482edb..443409dc015c 100644 --- a/src/Illuminate/Console/ContainerCommandLoader.php +++ b/src/Illuminate/Console/ContainerCommandLoader.php @@ -17,7 +17,7 @@ class ContainerCommandLoader implements CommandLoaderInterface /** * A map of command names to classes. - * + * * @var array */ protected $commandMap; @@ -42,7 +42,7 @@ public function __construct(ContainerInterface $container, array $commandMap) */ public function get(string $name) { - if (!$this->has($name)) { + if (! $this->has($name)) { throw new CommandNotFoundException(sprintf('Command "%s" does not exist.', $name)); } @@ -62,11 +62,11 @@ public function has(string $name) /** * Get the command names. - * + * * @return string[] */ public function getNames() { return array_keys($this->commandMap); } -} \ No newline at end of file +}