diff --git a/src/Illuminate/Console/Application.php b/src/Illuminate/Console/Application.php index 7066c8485425..4f6944369a6e 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..443409dc015c --- /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); + } +} 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. *