-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[Console] Improve AsCommand
DX for simple arguments and options
#57225
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
AsCommand
DX for simple arguments and options
AsCommand
DX for simple arguments and optionsAsCommand
DX for simple arguments and options
kind of reminds me #49522, wdyt? |
I didn't see issue. Interesting suggestion, that way modes looks like constraints or can be implicitly extracted from type hint. However, it's required to rewrite how command system works, right ? |
i do not know really 🤷🏻♂️, I was just commenting an issue of mine were I've seen that the console component will leverage new langage feature, so quite similar to this I think it is worth a discuss/question to know the go to of modernizing such "low level", and massively used component :) |
Thanks for the PR, happy to see traction on this topic.
Indeed, although still up to be discussed, input options/arguments value resolvers and autowiring are something that the work in progress mentioned in the linked issue covers.
Correct yes, that WIP has a broader scope and is a lot more involving than what you propose in this PR as it also includes getting rid of the fact commands must extend the base |
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 like this but I'm wondering about "suggestedValues" - should we find a way to allow binding it to a method of the command class?
*/ | ||
public function __construct( | ||
public string $name, | ||
public ?string $description = null, | ||
array $aliases = [], | ||
bool $hidden = false, | ||
public array|InputDefinition $inputDefinition = [], |
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 find the $inputDefinition name a bit long but I don't have a better idea at the moment
I'm closing this in favor of #59340 as it goes one step further which is desired. |
… attributes (yceruto) This PR was merged into the 7.3 branch. Discussion ---------- [Console] Add support for invokable commands and input attributes | Q | A | ------------- | --- | Branch? | 7.3 | Bug fix? | no | New feature? | yes | Deprecations? | yes | Issues | - | License | MIT Alternative to: #57225 This PR focuses on enhancing the DX for creating and defining console commands. Key improvements include: * No Need to Extend the Command Class: When using an invokable class marked with `#[AsCommand]`, extending the `Command` class is no longer required. * Automatic Argument and Option Inference: Command arguments and options are now inferred directly from the parameters of the `__invoke()` method, thanks to the new `#[Argument]` and `#[Option]` attributes. * Flexible `__invoke()` Signature: The `__invoke()` method now has a flexible signature, allowing you to define only the helpers you need. ### Before ```php #[AsCommand(name: 'lucky:number')] class LuckyNumberCommand extends Command { public function __construct(private LuckyNumberGenerator $generator) { parent::__construct(); } protected function configure(): void { $this->addArgument('name', InputArgument::REQUIRED); $this->addOption('formal', null, InputOption::VALUE_NONE | InputOption::VALUE_NEGATABLE); } public function execute(InputInterface $input, OutputInterface $output): int { $io = new SymfonyStyle($input, $output); $formal = (bool) $input->getOption('formal'); $name = $input->getArgument('name'); $io->title(sprintf('%s %s!', $formal ? 'Hello' : 'Hey', ucfirst($name))); $io->success(sprintf('Today\'s Lucky Number: %d', $this->generator->random())); return 0; } } ``` ### After ```php #[AsCommand(name: 'lucky:number')] class LuckyNumberCommand { public function __construct(private LuckyNumberGenerator $generator) { } public function __invoke(SymfonyStyle $io, #[Argument] string $name, #[Option] bool $formal): void { $io->title(sprintf('%s %s!', $formal ? 'Hello' : 'Hey', ucfirst($name))); $io->success(sprintf('Today\'s Lucky Number: %d', $this->generator->random())); } } ``` However, you can still extend the `Command` class when necessary to use advanced methods, such as the `interact()` method and others. Happy New Year! 🎉 Commits ------- cf6c3aa Add support for invokable commands and input attributes
I really like to use
AsCommand
attribute to configure command name and description.For most of my commands I only have one or two arguments/options.
Instead implementing
configure
method, what do you think to allow argument/inputs declarations inside the attribute ?(IMO, I can be more focus on execute method because command configuration it's done at one place)
Before this PR
After this PR
(You can, of course, continue to use
configure
method )