From 0e9f4588ec59399a1ab0f2ef01e8ab3ba188303f Mon Sep 17 00:00:00 2001 From: Sem Schilder Date: Mon, 17 Jun 2024 14:22:15 +0200 Subject: [PATCH] [Messenger] Add `--format` option to the `messenger:stats` command --- src/Symfony/Component/Messenger/CHANGELOG.md | 5 ++ .../Messenger/Command/StatsCommand.php | 56 ++++++++++++++++++- .../Tests/Command/StatsCommandTest.php | 44 +++++++++++++++ 3 files changed, 103 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/Messenger/CHANGELOG.md b/src/Symfony/Component/Messenger/CHANGELOG.md index fc81f735410d5..d8f4705562eec 100644 --- a/src/Symfony/Component/Messenger/CHANGELOG.md +++ b/src/Symfony/Component/Messenger/CHANGELOG.md @@ -1,6 +1,11 @@ CHANGELOG ========= +7.2 +--- + + * Add `--format` option to the `messenger:stats` command + 7.1 --- diff --git a/src/Symfony/Component/Messenger/Command/StatsCommand.php b/src/Symfony/Component/Messenger/Command/StatsCommand.php index 6f3afc961389d..9a6a62c334b28 100644 --- a/src/Symfony/Component/Messenger/Command/StatsCommand.php +++ b/src/Symfony/Component/Messenger/Command/StatsCommand.php @@ -16,9 +16,11 @@ use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\ConsoleOutputInterface; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Style\SymfonyStyle; +use Symfony\Component\Messenger\Exception\InvalidArgumentException; use Symfony\Component\Messenger\Transport\Receiver\MessageCountAwareInterface; /** @@ -36,8 +38,10 @@ public function __construct( protected function configure(): void { + $outputFormats = implode(', ', $this->getAvailableFormatOptions()); $this ->addArgument('transport_names', InputArgument::IS_ARRAY | InputArgument::OPTIONAL, 'List of transports\' names') + ->addOption('format', '', InputOption::VALUE_REQUIRED, 'The output format, e.g.: '.$outputFormats, 'text', $this->getAvailableFormatOptions()) ->setHelp(<<%command.name% command counts the messages for all the transports: @@ -46,6 +50,11 @@ protected function configure(): void Or specific transports only: php %command.full_name% + +The --format option specifies the format of command output, +these are "{$outputFormats}". + + php %command.full_name% --format=json EOF ) ; @@ -55,6 +64,11 @@ protected function execute(InputInterface $input, OutputInterface $output): int { $io = new SymfonyStyle($input, $output instanceof ConsoleOutputInterface ? $output->getErrorOutput() : $output); + $format = $input->getOption('format'); + if (!\in_array($format, $this->getAvailableFormatOptions(), true)) { + throw new InvalidArgumentException('Invalid output format.'); + } + $transportNames = $this->transportNames; if ($input->getArgument('transport_names')) { $transportNames = $input->getArgument('transport_names'); @@ -64,7 +78,9 @@ protected function execute(InputInterface $input, OutputInterface $output): int $uncountableTransports = []; foreach ($transportNames as $transportName) { if (!$this->transportLocator->has($transportName)) { - $io->warning(\sprintf('The "%s" transport does not exist.', $transportName)); + if ($this->formatSupportsWarnings($format)) { + $io->warning(\sprintf('The "%s" transport does not exist.', $transportName)); + } continue; } @@ -77,12 +93,48 @@ protected function execute(InputInterface $input, OutputInterface $output): int $outputTable[] = [$transportName, $transport->getMessageCount()]; } + match ($format) { + 'text' => $this->outputText($io, $outputTable, $uncountableTransports), + 'json' => $this->outputJson($io, $outputTable, $uncountableTransports), + }; + + return 0; + } + + private function outputText(SymfonyStyle $io, array $outputTable, array $uncountableTransports): void + { $io->table(['Transport', 'Count'], $outputTable); if ($uncountableTransports) { $io->note(\sprintf('Unable to get message count for the following transports: "%s".', implode('", "', $uncountableTransports))); } + } - return 0; + private function outputJson(SymfonyStyle $io, array $outputTable, array $uncountableTransports): void + { + $output = ['transports' => []]; + foreach ($outputTable as [$transportName, $count]) { + $output['transports'][$transportName] = ['count' => $count]; + } + + if ($uncountableTransports) { + $output['uncountable_transports'] = $uncountableTransports; + } + + $io->writeln(json_encode($output, \JSON_PRETTY_PRINT)); + } + + private function formatSupportsWarnings(string $format): bool + { + return match ($format) { + 'text' => true, + 'json' => false, + }; + } + + /** @return string[] */ + private function getAvailableFormatOptions(): array + { + return ['text', 'json']; } } diff --git a/src/Symfony/Component/Messenger/Tests/Command/StatsCommandTest.php b/src/Symfony/Component/Messenger/Tests/Command/StatsCommandTest.php index 9eb8268930609..0179c54eb34d7 100644 --- a/src/Symfony/Component/Messenger/Tests/Command/StatsCommandTest.php +++ b/src/Symfony/Component/Messenger/Tests/Command/StatsCommandTest.php @@ -69,6 +69,23 @@ public function testWithoutArgument() $this->assertStringContainsString('! [NOTE] Unable to get message count for the following transports: "simple".', $display); } + public function testWithoutArgumentJsonFormat() + { + $tester = new CommandTester($this->command); + $tester->execute(['--format' => 'json']); + $display = $tester->getDisplay(); + + $this->assertJsonStringEqualsJsonString('{ + "transports": { + "message_countable": {"count": 6}, + "another_message_countable": {"count": 6} + }, + "uncountable_transports": [ + "simple" + ] +}', $display); + } + public function testWithOneExistingMessageCountableTransport() { $tester = new CommandTester($this->command); @@ -81,6 +98,19 @@ public function testWithOneExistingMessageCountableTransport() $this->assertStringNotContainsString(' ! [NOTE] Unable to get message count for the following transports: "simple".', $display); } + public function testWithOneExistingMessageCountableTransportJsonFormat() + { + $tester = new CommandTester($this->command); + $tester->execute(['transport_names' => ['message_countable'], '--format' => 'json']); + $display = $tester->getDisplay(); + + $this->assertJsonStringEqualsJsonString('{ + "transports": { + "message_countable": {"count": 6} + } +}', $display); + } + public function testWithMultipleExistingMessageCountableTransport() { $tester = new CommandTester($this->command); @@ -93,6 +123,20 @@ public function testWithMultipleExistingMessageCountableTransport() $this->assertStringNotContainsString('! [NOTE] Unable to get message count for the following transports: "simple".', $display); } + public function testWithMultipleExistingMessageCountableTransportJsonFormat() + { + $tester = new CommandTester($this->command); + $tester->execute(['transport_names' => ['message_countable', 'another_message_countable'], '--format' => 'json']); + $display = $tester->getDisplay(); + + $this->assertJsonStringEqualsJsonString('{ + "transports": { + "message_countable": {"count": 6}, + "another_message_countable": {"count": 6} + } +}', $display); + } + public function testWithNotMessageCountableTransport() { $tester = new CommandTester($this->command);