symfony-yoandev-console
Installation
SKILL.md
Console commands
Tier: core when writing a command — and within it, dry-run by default and the lock are not optional on a destructive or scheduled command. Everything else is a command like any other.
A command is a translation layer, exactly like a controller. It parses input, calls one service, formats output. That is the whole job.
The reason is not tidiness. A rule that lives inside __invoke() can only be exercised by
booting a console, building an input and reading text back out of a buffer; the same rule
in a service is tested by calling a method and asserting on the return value. Every
business decision left in a command is a decision you will only ever test through a string.
#[AsCommand(name: 'app:shelf:purge', description: 'Remove abandoned shelves')]
public function purge(
SymfonyStyle $io,
#[Option(description: 'Actually delete, instead of reporting')] bool $force = false,
): int {
$report = $this->shelfPurger->purge(dryRun: !$force); // the only call