From 0aca5a9bb2f8fc9ee3d22ca854bc84d3f9524036 Mon Sep 17 00:00:00 2001 From: Paras Malhotra Date: Sun, 18 Oct 2020 04:46:39 +0530 Subject: [PATCH 1/4] [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/4] 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 +} From 8b34191467d41d3d9c0d14db842440707f8a4c5f Mon Sep 17 00:00:00 2001 From: Taylor Otwell Date: Wed, 21 Oct 2020 08:17:28 -0500 Subject: [PATCH 3/4] formatting --- src/Illuminate/Console/Application.php | 16 ++++++++-------- .../Console/ContainerCommandLoader.php | 9 ++++++--- src/Illuminate/Foundation/Console/Kernel.php | 5 ++--- 3 files changed, 16 insertions(+), 14 deletions(-) diff --git a/src/Illuminate/Console/Application.php b/src/Illuminate/Console/Application.php index 4f6944369a6e..db1f9ac403aa 100755 --- a/src/Illuminate/Console/Application.php +++ b/src/Illuminate/Console/Application.php @@ -32,6 +32,13 @@ class Application extends SymfonyApplication implements ApplicationContract */ protected $laravel; + /** + * The event dispatcher instance. + * + * @var \Illuminate\Contracts\Events\Dispatcher + */ + protected $events; + /** * The output from the previous command. * @@ -53,13 +60,6 @@ class Application extends SymfonyApplication implements ApplicationContract */ protected $commandMap = []; - /** - * The Event Dispatcher. - * - * @var \Illuminate\Contracts\Events\Dispatcher - */ - protected $events; - /** * Create a new Artisan console application. * @@ -292,7 +292,7 @@ public function resolveCommands($commands) } /** - * Set the Container Command Loader. + * Set the container command loader for lazy resolution. * * @return $this */ diff --git a/src/Illuminate/Console/ContainerCommandLoader.php b/src/Illuminate/Console/ContainerCommandLoader.php index 443409dc015c..3ac26fe345da 100644 --- a/src/Illuminate/Console/ContainerCommandLoader.php +++ b/src/Illuminate/Console/ContainerCommandLoader.php @@ -23,8 +23,11 @@ class ContainerCommandLoader implements CommandLoaderInterface protected $commandMap; /** - * @param \Psr\Container\ContainerInterface $container + * Create a new command loader instance. + * + * @param \Psr\Container\ContainerInterface $container * @param array $commandMap + * @return void */ public function __construct(ContainerInterface $container, array $commandMap) { @@ -33,7 +36,7 @@ public function __construct(ContainerInterface $container, array $commandMap) } /** - * Loads a command. + * Resolve a command from the container. * * @param string $name * @return \Symfony\Component\Console\Command\Command @@ -50,7 +53,7 @@ public function get(string $name) } /** - * Checks if a command exists. + * Determines if a command exists. * * @param string $name * @return bool diff --git a/src/Illuminate/Foundation/Console/Kernel.php b/src/Illuminate/Foundation/Console/Kernel.php index 0f9534c06c66..729d6edaa1ee 100644 --- a/src/Illuminate/Foundation/Console/Kernel.php +++ b/src/Illuminate/Foundation/Console/Kernel.php @@ -328,9 +328,8 @@ protected function getArtisan() { if (is_null($this->artisan)) { $this->artisan = (new Artisan($this->app, $this->events, $this->app->version())) - ->resolveCommands($this->commands); - - return $this->artisan->setContainerCommandLoader(); + ->resolveCommands($this->commands) + ->setContainerCommandLoader(); } return $this->artisan; From 29e17b983f43751a2118bba9343904ac1219ba1f Mon Sep 17 00:00:00 2001 From: Taylor Otwell Date: Wed, 21 Oct 2020 08:37:33 -0500 Subject: [PATCH 4/4] formatting --- src/Illuminate/Foundation/Console/stubs/console.stub | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Illuminate/Foundation/Console/stubs/console.stub b/src/Illuminate/Foundation/Console/stubs/console.stub index 98b48662cdef..90fd300842c0 100644 --- a/src/Illuminate/Foundation/Console/stubs/console.stub +++ b/src/Illuminate/Foundation/Console/stubs/console.stub @@ -14,7 +14,9 @@ class {{ class }} extends Command protected $signature = '{{ command }}'; /** - * The default command name for lazy loading. + * The name of the console command. + * + * This name is used to identify the command during lazy loading. * * @var string|null */