Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork9.7k
[Console] Add LazyCommandTrait to help writing lazy commands#39726
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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
Uh oh!
There was an error while loading.Please reload this page.
Conversation
6ccd276 todd1dd63Comparero0NL commentedJan 5, 2021 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
|
nicolas-grekas commentedJan 5, 2021 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
that'd work only for one item in the list of things that need to be configurable... |
dd1dd63 toac0a8c3Comparero0NL commentedJan 5, 2021
well, do we need anything else? Discouraging constructor injection for this feels like the wrong trade off. |
nicolas-grekas commentedJan 5, 2021 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
There is no tradeoff here. Constructor injection is not the only way to inject deps. |
derrabus commentedJan 6, 2021
The main design flaw of the component is that we have to instantiate the command to get its definition. And I feel like we're wrapping the the command into yet another layer of workarounds here. 😕 |
nicolas-grekas commentedJan 6, 2021 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
There are only two alternatives here:
The current design is not flawed to me. It provides just the right amount of DX + maintainability. Providing laziness is the very purpose of |
nicolas-grekas commentedJan 6, 2021
If this is accepted, I think |
ro0NL commentedJan 6, 2021 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
regardless of LazyCommandTrait as a feature (works for me), should we split name+description from the definition? in favor of static props currently extensibility is already broken given aliases are shown in it's a WTF actually :P |
nicolas-grekas commentedJan 6, 2021
What do you mean? I just had a look at the code and the name looks extensible to me. |
derrabus commentedJan 6, 2021
|
nicolas-grekas commentedJan 6, 2021
That wasn't obvious to me, but now I think that what you mean is that the Could be... I like the current proposal because it gives a simple way to wire commands (no need for the constructor boilerplate, which provides nothing useful). |
nicolas-grekas commentedJan 6, 2021
Can you elaborate? I don't understand what you mean here... |
ro0NL commentedJan 6, 2021 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
@nicolas-grekas given sf/console@v5.2.1 i have class FooBarCommandextends Command{// protected static $defaultName = 'foo:bar';protectedfunctionconfigure() {$this ->setName('foo:abc') ->setAliases(['foo:def']) ; }protectedfunctionexecute(InputInterface$input,OutputInterface$output):int {return Command::SUCCESS; }} list shows both foo:abc and foo:def work at this point next uncomment now list shows but only foo:bar works, whereas i expected the previous output as well. If you remove setName, but keep $defaultName the alias Hence i think if we extract |
derrabus commentedJan 6, 2021
If we look at how an HTTP request is matched to a controller, we find a router in between that knows everything we need to know to decide which controller exactly we need to instantiate (or pull from the container). The controller instance does not know which paths it is attached to. It can be a dump callable if we want. I think, we can build something similar to match a CLI call to a command. The command itself is only pulled from the container if we really intend to execute it. |
nicolas-grekas commentedJan 6, 2021
Oh, OK. That doesn't mean that extensibility is broken. It means it doesn't work the way you thought it works... You can change the name e.g by using a DI tag attribute. The reason is of course that we built for laziness when reading names.
That could work. We could even extend the format of $defaultName to allow listing aliases in the same string, eg For the description, I guess we should do the same: a DI attribute + a default static prop. Up for a PR? |
ro0NL commentedJan 6, 2021 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
i like the we have also
does it mean I also like the command_routing.yaml proposal, to define everything in one go. But it separates some concerns of which im not sure it scales well. Eg. for CLI, vendors are allowed to mount commands currently. |
nicolas-grekas commentedJan 6, 2021 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
On the other hand, a command must declare it's arguments, because that's its signature. I think having this signature declared in the same place as the implementation is critical. A design based around a command router would be radically different. Enough to warrant experimenting the idea in a separate package,if someone is interested in it. |
nicolas-grekas commentedJan 6, 2021
nope, as that would damage reusability ( |
ro0NL commentedJan 6, 2021
fair enough
i figured at this point im indeed wondering if LazyCommandTrait would be sufficient. |
nicolas-grekas commentedJan 6, 2021
|
ro0NL commentedJan 6, 2021 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
i think that + $defaultDescription will do for a lazy in the long run i think we should prefer signature (opt+args) are bound to implementation, so making it immutable as of then only seems reasonable. |
ro0NL commentedJan 6, 2021 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
and if It still unpacks all deps at once, whereas using ServiceSubscriberInterface directly allows invoking them on demand. |
chalasr commentedJan 7, 2021
I'd prefer not having to teach such an alternative |
nicolas-grekas commentedJan 7, 2021
So am I. Thanks for the discussion. PR welcome if anyone is up to giving this a try! |
nicolas-grekas commentedJan 15, 2021
See#39851 for a follow-up PR. |
In#33804,@helhum is wondering about a way to get the description of a command without instantiating its dependencies.
We already have a solution to this: implement
ServiceSubscriberInterface.In this PR, I'd like to propose adding a new
LazyCommandTraitto help implementServiceSubscriberInterface. This trait would allow writing commands like controllers: list services as arguments to get them when the command runs.Here is a dummy command that works with this trait (see how RequestStack is passed):
WDYT?