symfony-docs icon indicating copy to clipboard operation
symfony-docs copied to clipboard

[Console] Add support for invokable commands and input attributes

Open chalasr opened this issue 11 months ago • 24 comments

Q A
Feature PR symfony/symfony#59340
PR author(s) @yceruto
Merged in 7.3

We created this issue to not forget to document this new feature. We would really appreciate if you can help us with this task. If you are not sure how to do it, please ask us and we will help you.

To fix this issue, please create a PR against the 7.3 branch in the symfony-docs repository.

Thank you! :smiley:

chalasr avatar Jan 10 '25 12:01 chalasr

needs to be taken into account when tackling this:

  • symfony/symfony#59474

chalasr avatar Jan 11 '25 00:01 chalasr

Also

  • https://github.com/symfony/symfony/pull/59493
  • https://github.com/symfony/symfony/pull/59473

chalasr avatar Jan 20 '25 11:01 chalasr

Also https://github.com/symfony/symfony/pull/59565

yceruto avatar Jan 25 '25 21:01 yceruto

Until the documentation is written, is there an example of a trivial command using input attributes? Thx.

tacman avatar Feb 13 '25 11:02 tacman

@tacman You can find one in the code PR: https://github.com/symfony/symfony/pull/59340

chalasr avatar Feb 13 '25 12:02 chalasr

Here's a working example:

symfony new --version=next --webapp test-console7.3 && cd test-console7.3 
bin/console make:command lucky:number  

cat > src/Command/LuckyNumberCommand.php <<'END'
<?php

namespace App\Command;

use Symfony\Component\Console\Attribute\Argument;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Attribute\Option;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Style\SymfonyStyle;

#[AsCommand(name: 'lucky:number')]
class LuckyNumberCommand extends Command
{
    public function __construct(
    )
    {
        parent::__construct();
    }

    public function __invoke(SymfonyStyle $io,
                             #[Argument] string $name,
                             #[Option] bool $formal=true): void
    {
        $io->title(sprintf('%s %s!', $formal ? 'Hello' : 'Hey', ucfirst($name)));
        $io->success(sprintf('Today\'s Lucky Number: %d', rand(0, 400)));
    }
}
END
bin/console lucky:number bob

tacman avatar Feb 13 '25 12:02 tacman

I've started looking into this and have a question: should we replace the old signature everywhere or just add a new section for the new one?

yceruto avatar Mar 04 '25 18:03 yceruto

I would just add a new one

OskarStark avatar Mar 04 '25 20:03 OskarStark

I think the new attribute approach will be the new standard right ? (readonly and final classes, no inheritance, same DX than for controllers)

Newcomers to symfony shouldn't see it first ? (to see how powerfull is it)

alamirault avatar Mar 18 '25 22:03 alamirault

I’d go with @alamirault’s view on this, but let’s wait a bit to hear other opinions.

yceruto avatar Mar 19 '25 11:03 yceruto

It is not feature complete now compared to the old way, so I would still propose the old version first.

@chalasr what do you think?

OskarStark avatar Mar 19 '25 11:03 OskarStark

As a newcomer, I'd prefer to start learning from simple examples and basic features (which is exactly what the new version offers), then once I'm comfortable, I can extend the Command class and explore advanced features like interact when I'm ready for more complexity.

I think this is a great opportunity to enhance the doc around commands and adopt an incremental learning approach.

yceruto avatar Mar 19 '25 12:03 yceruto

The invokable approach improves a lot both DX and implementations’ design so I’d make it first-class citizen in docs. Of course regular commands and their specifics should keep being documented as it’s what people are using today and possibly for long.

chalasr avatar Mar 19 '25 15:03 chalasr

Love this feature, amazing work @yceruto 👏

@chalasr thanks for sharing your slides, that got me into this :)

FYI, I'm working on @rectorphp rule, so people can use the day Symfony 7.3 is out: https://github.com/rectorphp/rector-symfony/pull/707

It's WIP, so any documentation PR would be helpful to understand the new concept 🙏

TomasVotruba avatar Mar 21 '25 10:03 TomasVotruba

Also https://github.com/symfony/symfony-docs/issues/20838

yceruto avatar Mar 29 '25 13:03 yceruto

My vote would be to update ALL code examples to use the new and modern way of creating commands. I'd also add a secondary section in the main /console page showing how to define commands and add argument/options (and get their values in code) using the previous base class and methods.

javiereguiluz avatar Apr 16 '25 14:04 javiereguiluz

I think I agree with Yonel and Javier.

xabbuh avatar Apr 17 '25 06:04 xabbuh

I think we have a consensus, so I will do my best to propose the doc improvements before the release!

yceruto avatar Apr 17 '25 12:04 yceruto

I guess that this needs attention too: https://symfony.com/doc/7.3/console.html#testing-commands

garak avatar Apr 26 '25 10:04 garak

@garak Good point! However, nothing changes when it comes to E2E testing for console commands (which is exactly what the code in the link you shared covers: https://symfony.com/doc/7.3/console.html#testing-commands).

Note that for all cases, an invokable command will be wrapped into a Command instance (via setCode() method), so this line won't resolve the invokable command service but its Command instance instead:

$command = $application->find('app:hello');

yceruto avatar Apr 28 '25 14:04 yceruto

Let's start with something https://github.com/symfony/symfony-docs/pull/20932 help wanted

yceruto avatar May 01 '25 15:05 yceruto

Maybe to take into account: https://github.com/symfony/symfony/pull/60389

chalasr avatar May 09 '25 14:05 chalasr

symfony/symfony#59602 also

chalasr avatar May 09 '25 14:05 chalasr

See https://github.com/symfony/symfony/pull/60767 for 7.4

chalasr avatar Jun 13 '25 12:06 chalasr