-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[Console] Add command resolver (proof of concept) #16438
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@@ -87,6 +93,8 @@ public function __construct($name = 'UNKNOWN', $version = 'UNKNOWN') | |||
$this->helperSet = $this->getDefaultHelperSet(); | |||
$this->definition = $this->getDefaultInputDefinition(); | |||
|
|||
$this->commands = !empty($commandResolver) ? $commandResolver : new CommandResolver(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use a null
comparison instead
@@ -87,6 +93,8 @@ public function __construct($name = 'UNKNOWN', $version = 'UNKNOWN') | |||
$this->helperSet = $this->getDefaultHelperSet(); | |||
$this->definition = $this->getDefaultInputDefinition(); | |||
|
|||
$this->commandResolver = ($commandResolver !== null) ? $commandResolver : new CommandResolver(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it should be null !== $commandResolver ?
and parentheses is useless here
*/ | ||
class CommandResolverTest extends \PHPUnit_Framework_TestCase | ||
{ | ||
public function testLazyCommandResolver() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wrong indent in whole file. Use 4 spaces not 2.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry for that. I will fix it.
@stof Hello. Can you help me? I can`t pass all tests of this PR at CI services (In local environment all tests are green). |
Very nice PR! Tests for Console are passing well. It fails on Symfony/Bridge/ProxyManager package, not sure why. |
@TomasVotruba yep and I don`t know how to resolve this. Is there any way to rerun this tests? |
with a rebase 😉 |
Hi 2 all. It is easier to create new pull request and implement the same logic. |
{ | ||
$this->name = $name; | ||
$this->version = $version; | ||
$this->defaultCommand = 'list'; | ||
$this->helperSet = $this->getDefaultHelperSet(); | ||
$this->definition = $this->getDefaultInputDefinition(); | ||
|
||
$this->commandResolver = $commandResolver !== null ? $commandResolver : new CommandResolver(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we use $this->commandResolver = $commandResolver ?: new CommandResolver()
This PR was merged into the 3.4 branch. Discussion ---------- [Console] Add support for command lazy-loading | Q | A | ------------- | --- | Branch? | 3.4 | Bug fix? | no | New feature? | yes | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | #12063 #16438 #13946 #21781 | License | MIT | Doc PR | todo This PR adds command lazy-loading support to the console, based on PSR-11 and DI tags. (#12063 (comment)) Commands registered as services which set the `command` attribute on their `console.command` tag are now instantiated when calling `Application::get()` instead of all instantiated at `run()`. __Usage__ ```yaml app.command.heavy: tags: - { name: console.command, command: app:heavy } ``` This way private command services can be inlined (no public aliases, remain really private). With console+PSR11 implem only: ```php $application = new Application(); $container = new ServiceLocator(['heavy' => function () { return new Heavy(); }]); $application->setCommandLoader(new ContainerCommandLoader($container, ['app:heavy' => 'heavy']); ``` Implementation is widely inspired from Twig runtime loaders (without the definition/runtime separation which is not needed here). Commits ------- 7f97519 Add support for command lazy-loading
This PR was merged into the 3.4 branch. Discussion ---------- [Console] Add support for command lazy-loading | Q | A | ------------- | --- | Branch? | 3.4 | Bug fix? | no | New feature? | yes | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | symfony/symfony#12063 symfony/symfony#16438 symfony/symfony#13946 #21781 | License | MIT | Doc PR | todo This PR adds command lazy-loading support to the console, based on PSR-11 and DI tags. (symfony/symfony#12063 (comment)) Commands registered as services which set the `command` attribute on their `console.command` tag are now instantiated when calling `Application::get()` instead of all instantiated at `run()`. __Usage__ ```yaml app.command.heavy: tags: - { name: console.command, command: app:heavy } ``` This way private command services can be inlined (no public aliases, remain really private). With console+PSR11 implem only: ```php $application = new Application(); $container = new ServiceLocator(['heavy' => function () { return new Heavy(); }]); $application->setCommandLoader(new ContainerCommandLoader($container, ['app:heavy' => 'heavy']); ``` Implementation is widely inspired from Twig runtime loaders (without the definition/runtime separation which is not needed here). Commits ------- 7f97519 Add support for command lazy-loading
Hello. This is simple proof of concept for command resolver.
Why?
On huge projects we should always initialize all commands, even if they are not used.
Some users want lazy-loading of commands. And there are a lot of ways how to do that. Store cache in files, db, initialize commands by unique id etc..
How?
This PR introduce new interface
CommandResolverInterface
. Any user can implement logic and inject it to the application. With this interface developer can create commands by requestBC ?
This interface is softly injected to this application. All tests pass. By default
CommandResolver
is simple holder for commands.Current state
There are one problem: when we add
Command
to application, application add this command only if it is available. This logic is not covered inCommandResolverInterface
. We put all responsibility to developer which Commands are available to application.If it will be interesting to the team I can polish it (fix code style, possible change names of interface, write documentation etc.)