-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[2.2] [FrameworkBundle] Add events to console commands #3889
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
if (true === $input->hasParameterOption(array('--shell', '-s'))) { | ||
$shell = new Shell($this); | ||
$shell->setProcessIsolation($input->hasParameterOption(array('--process-isolation'))); | ||
$shell->run(); | ||
|
||
return 0; | ||
$statusCode = 0; |
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.
the code when using the shell should not be changed. Events should be dispatched by the commands launched inside the shell, not before and after running the shell itself
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.
Alright, I was unsure about that point. Fixed.
I am bit confused here. I await some helping pointers from any core dev. |
$dispatcher = $this->kernel->getContainer()->get('event_dispatcher'); | ||
$dispatcher->dispatch('console.init'); | ||
|
||
$statusCode = parent::doRun($input, $output); |
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.
this variable would better be named $exitCode
i havent tested this branch, but in concept it seems good to me. please also add a test case. see |
@lsmith77 no need to add a test for the compiler pass as it should be removed (it duplicates things already possible with the existing pass for event listeners as it is exactly the same with a different tag) |
which "existing pass for event listeners" are you talking about? |
are you saying that |
@lsmith77 there is nothing to refactor. Simply register a listener with |
ah i see now .. since he is using its maybe a bit iffy to call it |
Thanks for your feedback, I'll try to work on this PR in the next few days. |
I applied the suggestions above.
|
* | ||
* @author Francesco Levorato <[email protected]> | ||
*/ | ||
class ConsoleInitEvent extends KernelEvent |
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.
you should not extend KernelEvent as KernelEvent has the request and the request type which are totally irrelevant here
I probably did a bit of a mess with my last push. Do you have any more suggestions/comments to add? |
/** | ||
* The input received by the command. | ||
* | ||
* @var Symfony\Component\Console\Input\InputInterface |
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.
you should use the short class name (the other solution would be the FQCN, i.e. with the leadaing \
but Sf2 uses the short classname everywhere). The current code will break the autocompletion is some IDE (PhpStorm would consider it as Symfony\Bundle\FrameworkBundle\Console\Event\Symfony\Component\Console\Input\InputInterface
for instance)
Dirty hack idea (because I enjoy that sport): before dispatching register a new autoloader that will create any class that does not exist with: eval(<<<CODE
class $class
{
public function __call($name, $args)
{
}
}
CODE
); That way services can be created and then called even if they don't exist anymore. It would mask any classname mistake though, so it should only be registered when the cache:clear command is called IMO. |
@Seldaek running any command in the prod environment with an outdated cache would also break things |
I have given some thought but I still don't have any solution. When executed with --no-debug, the console application will use the currently cached kernel and container. If a listener/subscriber class gets removed (e.g.: in a deploy) the console application breaks with a fatal error, as it tries to load the event dispatcher from the cached container which in turn contains references to the not-existing-any-more class. In general all usages of the console application will break, but in particular it won't be possible to use it to clear the cache. I can think of 3 approaches: Here is a list of some proposals:
I don't like any of these proposals, but if I really I had to choose, my order of choice would be A3, A1, A2. |
The cache:clear command cannot be responsible to check the instantiation of the dispatcher as the dispatcher is sued before calling the command. |
@stof I assume you are commenting on A4. Yes, the code for rm -rf would need to be in the Application not in the CacheClearCommand itself. |
IMO the only command that matters for the issue of "listener classes It's the same with the routing, annotations and whatever else is in the It is a predicate of the framework that if you change the code, you |
One other (very crazy) idea could be: A5: also cache (aka copy) the event listeners/subscribers classes and all their dependencies and configure the autoloader accordingly. Even if it's probably more hassle than it's worth, It would make some sense as a cache works only as long as all the classes it depends on still exist. The extreme result of this path is we end up caching the whole application, but if we apply this only in the case of cache:clear dependencies, it might be not as bad. Going back to a more traditional thinking, A3 (implement a new dispatcher) might be the cleanest/easiest solution to offer console events and at the same provide useful output should something break during cache:clear. Please share your opinions and suggestions so I can get this PR moving again! |
How about a flag on the command, just like the |
@flevour : I've continued your PR with this commit : bamarni/symfony@3072ee3 Are you fine with this implementation? I've not tested it yet but it should give you an idea about what I meant. Unfortunately I can't submit a PR against your fork as github doesn't show it to me in the available symfony forks list. Maybe you can cherry-pick it? |
@flevour : did you had time to look at my commit? It should fix the issue, I guess now it only misses some small tweaks and unit tests. If you don't have time to devote on this, I'd be happy to help you to sort this out by opening another PR, but of course I'll squash the commits with your name so that you keep the authorship for this feature! |
@fabpot what about this? It's also needed for symfony/swiftmailer-bundle#23 |
Closing in favor of #6124 |
This adds an init and terminate event for commands. They are dispatched from ContainerAwareCommand. The cache:clear command can't implement this (cf. symfony#3889 on Github).
This PR was merged into the master branch. Discussion ---------- Console dispatcher | Q | A | ------------- | --- | Bug fix? | no | New feature? | yes | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | #3889, #6124 | License | MIT | Doc PR | symfony/symfony-docs#2352 refs #1884, #1929 This is an alternative implementation for adding events to console applications. This implementation has the following features: * Available for anyone using the Console component and it is not tied to FrameworkBundle (this is important as one thing we are trying to solve is email sending from a command, and frameworks like Silex using the Console component needs a solution too); * Non-intrusive as the current code has not been changed (except for renaming an internal variable that was wrongly named -- so that's not strictly needed for this PR) * The new DispatchableApplication class also works without a dispatcher, falling back to the regular behavior. That makes easy to create applications that can benefit from a dispatcher when available, but can still work otherwise. * Besides the *before* and *after* events, there is also an *exception* event that is dispatched whenever an exception is thrown. * Each event is quite powerful and can manipulate the input, the output, but also the command to be executed. Commits ------- 4f9a55a refactored the implementation of how a console application can handle events 4edf29d added helperSet to console event objects f224102 Added events for CLI commands
Bug fix: no
Feature addition: yes
Backwards compatibility break: no
Symfony2 tests pass:
Fixes the following tickets: #1929
Todo: