8000 Auto-Registration of Commands is now configurable by seiffert · Pull Request #6389 · symfony/symfony · GitHub
[go: up one dir, main page]

Skip to content

Auto-Registration of Commands is now configurable #6389

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 1 commit into from
Closed

Auto-Registration of Commands is now configurable #6389

wants to merge 1 commit into from

Conversation

seiffert
Copy link
Contributor

This PR adds a method to HttpKernel\Bundle that is used to decide whether the commands of the bundle should be registered using Bundle::registerCommands.

This needs to be configurable since there are cases in which commands should not be registered by default. One could just override Bundle::registerCommands to solve this. However, this wouldn't be compatible with LSP.

@fabpot
Copy link
Member
fabpot commented Dec 17, 2012

What's the point? If you register a bundle, why would you want to not register the commands? When does it hurt?

@lsmith77
Copy link
Contributor

@fabpot see the email @seiffert send to the list, the idea is to make it possible for Bundle's to register commands as services instead. those who want to unit test their commands as well as maintain a better overview of their dependencies might prefer them to be services. furthermore it would mean i would no longer need to do hacks like this to conditionally register commands https://github.com/doctrine/DoctrinePHPCRBundle/blob/master/DoctrinePHPCRBundle.php#L48

@lsmith77
Copy link
Contributor

BTW, it appears we should add an interface for the entire command handling as BundleInterface is missing registerCommands().

@seiffert
Copy link
Contributor Author

@fabpot The point is that currently the only "right" way to add commands to an application is to put them into a specific directory (which should be a convention). See console-extra-bundle for an example that registers commands in another way. There, I am using an DI tag to determine which services should be considered console commands.

@henrikbjorn
Copy link
Contributor

👎 it is just as fast to overwrite the registerCommands function as it is with writing the auto register one.

@henrikbjorn
Copy link
Contributor

Also by doing parent::registerCommands you are still running the finder logic that is finding and registrering commands.

@seiffert
Copy link
Contributor Author

@henrikbjorn The problem with overriding registerCommands is that it would break the Bundle's API. (When calling registerCommands, you expect that commands are being registered...)

Where am I calling parent::registerCommands?

@henrikbjorn
Copy link
Contributor

in your bundle you are. It would break the bundle's api? How. It still does the same thing registering commands, it is just not autodiscovering them. Saying that would break the API then every extension of a class would be an API breakage.

@seiffert
Copy link
Contributor Author

The bundle console-extra-bundle does not register own commands. The method SeiffertConsoleExtraBundle::registerCommands() is used to register all commands collected during container compilation. I am calling parent::registerCommands in order to be compatible with the API.

A true extension of a class does not break any API. However, if you take away functionality, a class cannot fullfil promises made by the parent class. (In this case, you are breaking API and should consider re-designing your class)

@henrikbjorn
Copy link
Contributor

Then the describtion of the registerCommand method should be changed. To only saying "Register commands with the Console Application" instead of the finding stuff.

@lsmith77
Copy link
Contributor

BTW I was also pondering if the auto registration shouldn't be disabled via an interface. them again its weird to disable a capability via an interface. alternatively we could offer 2 Bundle base classes one with and without the interface for registerCommand

@se
8000
iffert
Copy link
Contributor Author

@henrikbjorn Yes, that would be a good alternative. The bundle would then be responsible for registering it's commands in all cases and we could move auto-discovery into a separate method like discoverCommands. Based on a switch (like autoRegisterCommands or a boolean flag), registerBundles either calls discoverCommands or it doesn't. Does that sound better to you?

@henrikbjorn
Copy link
Contributor

@lsmith77 that is just adding bloat, change the description and implement an empty registerCommands if you dont want the autodiscovering i think that is the best approach.

@seiffert
Copy link
Contributor Author

@henrikbjorn You would still need some kind of a switch...

@henrikbjorn
Copy link
Contributor

I wouldnt need a switch just dont call parent::registerCommands.

@seiffert
Copy link
Contributor Author

are you refering to this registerCommands implementation?
My PR does not affect that one. I am concerning those bundles that would want to define their commands as services. As you can read in the README.md, those bundles currently have to override Bundle::registerBundles with an empty implementation. <--- which is what I want to avoid.

@stof
Copy link
Member
stof commented Dec 17, 2012

And instead, you want them to override another method (with a non-empty implementation) added only to avoid the overriding... This is a weird reasonning IMO.

@seiffert
Copy link
Contributor Author

No, I want the user to be able to decide whether commands are being auto-discovered or not. I want to give him a way to configure this other than removing functionality by overriding a method with an empty implementation.

I am open for alternatives, but the current "solution" is not a real option for me.

@stof
Copy link
Member
stof commented Dec 17, 2012

Why is it not a real option ? your solution also requires to overwrite a method (and it requires to ship an implementation in the overwritten method when you actually want your bundle to do nothing)

@seiffert
Copy link
Contributor Author

This is not about saving bytes but about extending functionality in a clean way.

Let's say I created a bundle X which overrides Bundle::registerCommands with an empty implementation. This way, no commands are registered for this bundle. Now a friend of mine wants to reuse my bundle X's bundle class. He extends it via class inheritance but wants to use the command auto-discovery feature. How would he do that?

The example might be abstruse, but it illustrates the problem I have with empty implementations.

@lsmith77
Copy link
Contributor

indeed, its just bad design to have to overwrite this method this way. so i agree it would be better to either have a flag or an interface to express that you want or don't want the auto registration feature.

additionally we also need to include registerCommands inside an interface (probably a new one).

@seiffert
Copy link
Contributor Author

Probably @lsmith77's idea with the additional interface is better. If a bundle class implements this interface, it has to provide a registerCommands method. If not, the application won't try to call it.
This way, there won't be any 'disabled' methods.

@lsmith77 What would be a good name/place for such an interface? I see two possible semantics for it: Either, it inherits from BundleInterface (and is named CommandRegisteringBundleInterface) adding just one method OR it is placed somewhere else and contains only registerCommands. By doing this, we could have different classes implementing this CommandRegistratingInterface - one could be a bundle, another one some class of console-extra-bundle,...

@seiffert
Copy link
Contributor Author

OK, after re-reading the code, I suggest adding an interface Symfony\FrameworkBundle\Console\CommandRegistratingInterface (please propose better names). Important is that it's not placed in HttpKernel. HttpKernel really should not have to care about commands at all. What do you think?

@lsmith77
Copy link
Contributor

the name sounds fine to me .. but for backwards compatibility i fear we will have to have the Bundle class implementing this interface. so to make it feasible for people to not have auto registration enabled, we imho need a new class that doesnt implement said interface. now if we are not going to add this feature to core, then you can then provide this class inside your Bundle. however you will then have to copy most of the code from the Bundle class :-/

@ghost ghost mentioned this pull request Feb 5, 2013
@seiffert
Copy link
Contributor Author

Although #8182 looks a little hacky to me, it probably solves the issue for most cases.

@seiffert seiffert closed this Jul 11, 2013
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
< 4946 form class="js-issue-sidebar-form" aria-label="Select projects" data-turbo="false" action="/symfony/symfony/projects/issues/6389" accept-charset="UTF-8" method="post">
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants
0