Skip to content

Commit

Permalink
Merge branch 'lazy_load_commands'
Browse files Browse the repository at this point in the history
  • Loading branch information
taylorotwell committed Oct 21, 2020
2 parents 6a493fd + 29e17b9 commit d70fd4f
Show file tree
Hide file tree
Showing 4 changed files with 116 additions and 6 deletions.
33 changes: 29 additions & 4 deletions src/Illuminate/Console/Application.php
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*
Expand All @@ -47,11 +54,11 @@ class Application extends SymfonyApplication implements ApplicationContract
protected static $bootstrappers = [];

/**
* The Event Dispatcher.
* A map of command names to classes.
*
* @var \Illuminate\Contracts\Events\Dispatcher
* @var array
*/
protected $events;
protected $commandMap = [];

/**
* Create a new Artisan console application.
Expand Down Expand Up @@ -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));
}

Expand All @@ -278,6 +291,18 @@ public function resolveCommands($commands)
return $this;
}

/**
* Set the container command loader for lazy resolution.
*
* @return $this
*/
public function setContainerCommandLoader()
{
$this->setCommandLoader(new ContainerCommandLoader($this->laravel, $this->commandMap));

return $this;
}

/**
* Get the default input definition for the application.
*
Expand Down
75 changes: 75 additions & 0 deletions src/Illuminate/Console/ContainerCommandLoader.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<?php

namespace Illuminate\Console;

use Psr\Container\ContainerInterface;
use Symfony\Component\Console\CommandLoader\CommandLoaderInterface;
use Symfony\Component\Console\Exception\CommandNotFoundException;

class ContainerCommandLoader implements CommandLoaderInterface
{
/**
* The container instance.
*
* @var \Psr\Container\ContainerInterface
*/
protected $container;

/**
* A map of command names to classes.
*
* @var array
*/
protected $commandMap;

/**
* Create a new command loader instance.
*
* @param \Psr\Container\ContainerInterface $container
* @param array $commandMap
* @return void
*/
public function __construct(ContainerInterface $container, array $commandMap)
{
$this->container = $container;
$this->commandMap = $commandMap;
}

/**
* Resolve a command from the container.
*
* @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]);
}

/**
* Determines 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);
}
}
5 changes: 3 additions & 2 deletions src/Illuminate/Foundation/Console/Kernel.php
Original file line number Diff line number Diff line change
Expand Up @@ -327,8 +327,9 @@ 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)
->setContainerCommandLoader();
}

return $this->artisan;
Expand Down
9 changes: 9 additions & 0 deletions src/Illuminate/Foundation/Console/stubs/console.stub
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,15 @@ class {{ class }} extends Command
*/
protected $signature = '{{ command }}';

/**
* The name of the console command.
*
* This name is used to identify the command during lazy loading.
*
* @var string|null
*/
protected static $defaultName = '{{ command }}';

/**
* The console command description.
*
Expand Down

0 comments on commit d70fd4f

Please sign in to comment.