Skip to content

[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

Closed
wants to merge 12 commits into from
Closed

[Console] Add command resolver (proof of concept) #16438

wants to merge 12 commits into from

Conversation

funivan
Copy link

@funivan funivan commented Nov 3, 2015

Q A
Bug fix? no
New feature? yes
BC breaks? no
Deprecations? no
Tests pass? yes
Fixed tickets #12063
License MIT
Doc PR NA

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 request

BC ?

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 in CommandResolverInterface. 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.)

@@ -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();
Copy link
Member

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();
Copy link
Contributor

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()
Copy link
Contributor

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.

Copy link
Author

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.

@funivan
Copy link
Author

funivan commented Nov 12, 2015

@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).
Some times it failure in AppVeyor sometimes in travis, but always in different places. And even more, sometimes failures are not relevant to my commits. Thank you.
What should I do to make this PR green?

@xabbuh xabbuh added the Console label Nov 12, 2015
@TomasVotruba
Copy link
Contributor

Very nice PR!

Tests for Console are passing well. It fails on Symfony/Bridge/ProxyManager package, not sure why.
Maybe rerun might help.

@funivan
Copy link
Author

funivan commented Mar 3, 2016

@TomasVotruba yep and I don`t know how to resolve this. Is there any way to rerun this tests?

@DavidBadura
Copy link
Contributor

with a rebase 😉

@javiereguiluz javiereguiluz changed the title [CONSOLE] Add command resolver (proof of concept) [Console] Add command resolver (proof of concept) Mar 3, 2016
@funivan
Copy link
Author

funivan commented Jul 22, 2016

Hi 2 all. It is easier to create new pull request and implement the same logic.
If this feature is interesting to the community and to the core team I can implement the same algorithm of the command resolver.

{
$this->name = $name;
$this->version = $version;
$this->defaultCommand = 'list';
$this->helperSet = $this->getDefaultHelperSet();
$this->definition = $this->getDefaultInputDefinition();

$this->commandResolver = $commandResolver !== null ? $commandResolver : new CommandResolver();
Copy link
Member

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()

@nicolas-grekas
Copy link
Member

Closing in favor of #22734 which is going to be accepted and provide most of what this tries to achieve.
Thanks for working on this @funivan.

@funivan funivan deleted the console-command-resolv branch July 11, 2017 17:53
nicolas-grekas added a commit that referenced this pull request Jul 12, 2017
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
symfony-splitter pushed a commit to symfony/security-bundle that referenced this pull request Jul 12, 2017
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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.