Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 7e90c79

Browse files
committed
[Console] Add support for command lazy-loading
1 parent 27852a0 commit 7e90c79

File tree

13 files changed

+379
-45
lines changed

13 files changed

+379
-45
lines changed

src/Symfony/Bundle/FrameworkBundle/Console/Application.php

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -67,15 +67,7 @@ public function doRun(InputInterface $input, OutputInterface $output)
6767
{
6868
$this->kernel->boot();
6969

70-
$container = $this->kernel->getContainer();
71-
72-
foreach ($this->all() as $command) {
73-
if ($command instanceof ContainerAwareInterface) {
74-
$command->setContainer($container);
75-
}
76-
}
77-
78-
$this->setDispatcher($container->get('event_dispatcher'));
70+
$this->setDispatcher($this->kernel->getContainer()->get('event_dispatcher'));
7971

8072
return parent::doRun($input, $output);
8173
}
@@ -97,7 +89,13 @@ public function get($name)
9789
{
9890
$this->registerCommands();
9991

100-
return parent::get($name);
92+
$command = parent::get($name);
93+
94+
if ($command instanceof ContainerAwareInterface) {
95+
$command->setContainer($this->kernel->getContainer());
96+
}
97+
98+
return $command;
10199
}
102100

103101
/**
@@ -130,15 +128,22 @@ protected function registerCommands()
130128

131129
$container = $this->kernel->getContainer();
132130

131+
if ($container->has('console.command_loader')) {
132+
$this->setCommandLoader($container->get('console.command_loader'));
133+
}
134+
133135
foreach ($this->kernel->getBundles() as $bundle) {
134136
if ($bundle instanceof Bundle) {
135137
$bundle->registerCommands($this);
136138
}
137139
}
138140

141+
// @deprecated since version 3.4, to be removed in 4.0
139142
if ($container->hasParameter('console.command.ids')) {
140143
foreach ($container->getParameter('console.command.ids') as $id) {
141-
$this->add($container->get($id));
144+
if (false !== $id) {
145+
$this->add($container->get($id));
146+
}
142147
}
143148
}
144149
}

src/Symfony/Bundle/FrameworkBundle/composer.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
"fig/link-util": "^1.0",
3737
"symfony/asset": "~3.3|~4.0.0",
3838
"symfony/browser-kit": "~2.8|~3.0|~4.0.0",
39-
"symfony/console": "~3.3|~4.0.0",
39+
"symfony/console": "~3.4|~4.0.0",
4040
"symfony/css-selector": "~2.8|~3.0|~4.0.0",
4141
"symfony/dom-crawler": "~2.8|~3.0|~4.0.0",
4242
"symfony/polyfill-intl-icu": "~1.0",
@@ -64,7 +64,7 @@
6464
"phpdocumentor/type-resolver": "<0.2.0",
6565
"phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0",
6666
"symfony/asset": "<3.3",
67-
"symfony/console": "<3.3",
67+
"symfony/console": "<3.4",
6868
"symfony/form": "<3.3",
6969
"symfony/property-info": "<3.3",
7070
"symfony/serializer": "<3.3",

src/Symfony/Bundle/SecurityBundle/Resources/config/console.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
<service id="security.console.user_password_encoder_command" class="Symfony\Bundle\SecurityBundle\Command\UserPasswordEncoderCommand">
1111
<argument type="service" id="security.encoder_factory"/>
1212
<argument type="collection" /> <!-- encoders' user classes -->
13-
<tag name="console.command" />
13+
<tag name="console.command" command="security:encode-password" />
1414
</service>
1515
</services>
1616
</container>

src/Symfony/Bundle/WebServerBundle/Resources/config/webserver.xml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,21 +10,21 @@
1010
<service id="web_server.command.server_run" class="Symfony\Bundle\WebServerBundle\Command\ServerRunCommand">
1111
<argument>%kernel.root_dir%/../web</argument>
1212
<argument>%kernel.environment%</argument>
13-
<tag name="console.command" />
13+
<tag name="console.command" command="server:run" />
1414
</service>
1515

1616
<service id="web_server.command.server_start" class="Symfony\Bundle\WebServerBundle\Command\ServerStartCommand">
1717
<argument>%kernel.root_dir%/../web</argument>
1818
<argument>%kernel.environment%</argument>
19-
<tag name="console.command" />
19+
<tag name="console.command" command="server:start" />
2020
</service>
2121

2222
<service id="web_server.command.server_stop" class="Symfony\Bundle\WebServerBundle\Command\ServerStopCommand">
23-
<tag name="console.command" />
23+
<tag name="console.command" command="server:stop" />
2424
</service>
2525

2626
<service id="web_server.command.server_status" class="Symfony\Bundle\WebServerBundle\Command\ServerStatusCommand">
27-
<tag name="console.command" />
27+
<tag name="console.command" command="server:status" />
2828
</service>
2929
</services>
3030
</container>

src/Symfony/Component/Console/Application.php

Lines changed: 47 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace Symfony\Component\Console;
1313

14+
use Symfony\Component\Console\CommandLoader\CommandLoaderInterface;
1415
use Symfony\Component\Console\Exception\ExceptionInterface;
1516
use Symfony\Component\Console\Formatter\OutputFormatter;
1617
use Symfony\Component\Console\Helper\DebugFormatterHelper;
@@ -64,6 +65,7 @@ class Application
6465
private $runningCommand;
6566
private $name;
6667
private $version;
68+
private $commandLoader;
6769
private $catchExceptions = true;
6870
private $autoExit = true;
6971
private $definition;
@@ -96,6 +98,11 @@ public function setDispatcher(EventDispatcherInterface $dispatcher)
9698
$this->dispatcher = $dispatcher;
9799
}
98100

101+
public function setCommandLoader(CommandLoaderInterface $commandLoader)
102+
{
103+
$this->commandLoader = $commandLoader;
104+
}
105+
99106
/**
100107
* Runs the current application.
101108
*
@@ -431,6 +438,10 @@ public function add(Command $command)
431438
throw new LogicException(sprintf('Command class "%s" is not correctly initialized. You probably forgot to call the parent constructor.', get_class($command)));
432439
}
433440

441+
if (!$command->getName()) {
442+
throw new LogicException(sprintf('The command defined in "%s" cannot have an empty name.', get_class($command)));
443+
}
444+
434445
$this->commands[$command->getName()] = $command;
435446

436447
foreach ($command->getAliases() as $alias) {
@@ -451,12 +462,16 @@ public function add(Command $command)
451462
*/
452463
public function get($name)
453464
{
454-
if (!isset($this->commands[$name])) {
465+
if (isset($this->commands[$name])) {
466+
$command = $this->commands[$name];
467+
} elseif ($this->commandLoader && $this->commandLoader->has($name)) {
468+
$command = $this->commandLoader->get($name);
469+
$command->setName($name);
470+
$this->add($command);
471+
} else {
455472
throw new CommandNotFoundException(sprintf('The command "%s" does not exist.', $name));
456473
}
457474

458-
$command = $this->commands[$name];
459-
460475
if ($this->wantHelps) {
461476
$this->wantHelps = false;
462477

@@ -478,7 +493,7 @@ public function get($name)
478493
*/
479494
public function has($name)
480495
{
481-
return isset($this->commands[$name]);
496+
return isset($this->commands[$name]) || ($this->commandLoader && $this->commandLoader->has($name));
482497
}
483498

484499
/**
@@ -555,7 +570,7 @@ public function findNamespace($namespace)
555570
*/
556571
public function find($name)
557572
{
558-
$allCommands = array_keys($this->commands);
573+
$allCommands = $this->commandLoader ? array_merge($this->commandLoader->getNames(), array_keys($this->commands)) : array_keys($this->commands);
559574
$expr = preg_replace_callback('{([^:]+|)}', function ($matches) { return preg_quote($matches[1]).'[^:]*'; }, $name);
560575
$commands = preg_grep('{^'.$expr.'}', $allCommands);
561576

@@ -581,12 +596,12 @@ public function find($name)
581596

582597
// filter out aliases for commands which are already on the list
583598
if (count($commands) > 1) {
584-
$commandList = $this->commands;
585-
$commands = array_filter($commands, function ($nameOrAlias) use ($commandList, $commands) {
586-
$commandName = $commandList[$nameOrAlias]->getName();
599+
$commandList = $this->commandLoader ? array_merge(array_flip($this->commandLoader->getNames()), $this->commands) : $this->commands;
600+
$commands = array_unique(array_filter($commands, function ($nameOrAlias) use ($commandList, $commands) {
601+
$commandName = $commandList[$nameOrAlias] instanceof Command ? $commandList[$nameOrAlias]->getName() : $nameOrAlias;
587602

588603
return $commandName === $nameOrAlias || !in_array($commandName, $commands);
589-
});
604+
}));
590605
}
591606

592607
$exact = in_array($name, $commands, true);
@@ -598,6 +613,9 @@ public function find($name)
598613
$maxLen = max(Helper::strlen($abbrev), $maxLen);
599614
}
600615
$abbrevs = array_map(function ($cmd) use ($commandList, $usableWidth, $maxLen) {
616+
if (!$commandList[$cmd] instanceof Command) {
617+
return $cmd;
618+
}
601619
$abbrev = str_pad($cmd, $maxLen, ' ').' '.$commandList[$cmd]->getDescription();
602620

603621
return Helper::strlen($abbrev) > $usableWidth ? Helper::substr($abbrev, 0, $usableWidth - 3).'...' : $abbrev;
@@ -622,7 +640,18 @@ public function find($name)
622640
public function all($namespace = null)
623641
{
624642
if (null === $namespace) {
625-
return $this->commands;
643+
if (!$this->commandLoader) {
644+
return $this->commands;
645+
}
646+
647+
$commands = $this->commands;
648+
foreach ($this->commandLoader->getNames() as $name) {
649+
if (!isset($commands[$name])) {
650+
$commands[$name] = $this->commandLoader->get($name);
651+
}
652+
}
653+
654+
return $commands;
626655
}
627656

628657
$commands = array();
@@ -632,6 +661,14 @@ public function all($namespace = null)
632661
}
633662
}
634663

664+
if ($this->commandLoader) {
665+
foreach ($this->commandLoader->getNames() as $name) {
666+
if (!isset($commands[$name]) && $namespace === $this->extractNamespace($name, substr_count($namespace, ':') + 1)) {
667+
$commands[$name] = $this->commandLoader->get($name);
668+
}
669+
}
670+
}
671+
635672
return $commands;
636673
}
637674

src/Symfony/Component/Console/Command/Command.php

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,6 @@ public function __construct($name = null)
6161
}
6262

6363
$this->configure();
64-
65-
if (!$this->name) {
66-
throw new LogicException(sprintf('The command defined in "%s" cannot have an empty name.', get_class($this)));
67-
}
6864
}
6965

7066
/**
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?php
2+
3+
namespace Symfony\Component\Console\CommandLoader;
4+
5+
use Symfony\Component\Console\Command\Command;
6+
use Symfony\Component\Console\Exception\CommandNotFoundException;
7+
8+
/**
9+
* @author Robin Chalas <[email protected]>
10+
*/
11+
interface CommandLoaderInterface
12+
{
13+
/**
14+
* Loads a command.
15+
*
16+
* @param string $namee
17+
*
18+
* @return Command
19+
*
20+
* @throws CommandNotFoundException
21+
*/
22+
public function get($name);
23+
24+
/**
25+
* Checks if a command exists.
26+
*
27+
* @param string $name
28+
*
29+
* @return bool
30+
*/
31+
public function has($name);
32+
33+
/**
34+
* @return iterable All registered commands mapped by names
35+
*/
36+
public function all();
37+
38+
/**
39+
* @return string[] All registered command names
40+
*/
41+
public function getNames();
42+
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
<?php
2+
3+
namespace Symfony\Component\Console\CommandLoader;
4+
5+
use Psr\Container\ContainerInterface;
6+
use Symfony\Component\Console\Exception\CommandNotFoundException;
7+
8+
/**
9+
* Loads commands from a PSR-11 container.
10+
*
11+
* @author Robin Chalas <[email protected]>
12+
*/
13+
class ContainerCommandLoader implements CommandLoaderInterface
14+
{
15+
private $container;
16+
private $commandNames;
17+
18+
public function __construct(ContainerInterface $container, array $commandNames)
19+
{
20+
$this->container = $container;
21+
$this->commandNames = $commandNames;
22+
}
23+
24+
/**
25+
* {@inheritdoc}
26+
*/
27+
public function get($name)
28+
{
29+
if (!$this->has($name)) {
30+
throw new CommandNotFoundException(sprintf('Command "%s" does not exist.', $name));
31+
}
32+
33+
return $this->container->get($name);
34+
}
35+
36+
/**
37+
* {@inheritdoc}
38+
*/
39+
public function has($name)
40+
{
41+
return in_array($name, $this->commandNames, true);
42+
}
43+
44+
/**
45+
* {@inheritdoc}
46+
*/
47+
public function all()
48+
{
49+
foreach ($this->commandNames as $name) {
50+
yield $name => $this->container->get($name);
51+
}
52+
}
53+
54+
/**
55+
* {@inheritdoc}
56+
*/
57+
public function getNames()
58+
{
59+
return $this->commandNames;
60+
}
61+
}

0 commit comments

Comments
 (0)