Add sorting option to DebugCommand for recurring messages

This commit is contained in:
yoye
2026-01-20 15:17:57 +01:00
parent 72e9293f89
commit 892e932f75
3 changed files with 89 additions and 4 deletions

View File

@@ -1,6 +1,11 @@
CHANGELOG
=========
8.1
---
* Add `--sort` option to `debug:command` to order recurring messages by next run date
7.3
---

View File

@@ -45,6 +45,7 @@ final class DebugCommand extends Command
->addArgument('schedule', InputArgument::OPTIONAL | InputArgument::IS_ARRAY, \sprintf('The schedule name (one of "%s")', implode('", "', $this->scheduleNames)), null, $this->scheduleNames)
->addOption('date', null, InputOption::VALUE_REQUIRED, 'The date to use for the next run date', 'now')
->addOption('all', null, InputOption::VALUE_NONE, 'Display all recurring messages, including the terminated ones')
->addOption('sort', null, InputOption::VALUE_NONE, 'Sort recurring messages by next run date')
->setHelp(<<<'EOF'
The <info>%command.name%</info> lists schedules and their recurring messages:
@@ -93,9 +94,16 @@ final class DebugCommand extends Command
continue;
}
$recurringMessages = array_filter(array_map(self::renderRecurringMessage(...), $messages, array_fill(0, \count($messages), $date), array_fill(0, \count($messages), $input->getOption('all'))));
if ($input->getOption('sort')) {
usort($recurringMessages, static fn (array $a, array $b): int => $a[2] <=> $b[2]);
}
$io->table(
['Trigger', 'Provider', 'Next Run'],
array_filter(array_map(self::renderRecurringMessage(...), $messages, array_fill(0, \count($messages), $date), array_fill(0, \count($messages), $input->getOption('all')))),
array_map(static fn (array $row): array => [$row[0], $row[1], $row[2]?->format('r') ?? '-'], $recurringMessages),
);
}
@@ -103,14 +111,14 @@ final class DebugCommand extends Command
}
/**
* @return array{0:string,1:string,2:string}|null
* @return array{0:string,1:string,2:\DateTimeImmutable|null}|null
*/
private static function renderRecurringMessage(RecurringMessage $recurringMessage, \DateTimeImmutable $date, bool $all): ?array
{
$trigger = $recurringMessage->getTrigger();
$next = $trigger->getNextRunDate($date)?->format('r') ?? '-';
if ('-' === $next && !$all) {
$next = $trigger->getNextRunDate($date);
if (null === $next && !$all) {
return null;
}

View File

@@ -11,6 +11,7 @@
namespace Symfony\Component\Scheduler\Tests\Command;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Console\Tester\CommandTester;
use Symfony\Component\Scheduler\Command\DebugCommand;
@@ -150,4 +151,75 @@ class DebugCommandTest extends TestCase
" ------------------------------- ---------- --------------------------------- \n".
"\n/", $tester->getDisplay(true));
}
#[DataProvider('provideSorting')]
public function testExecuteWithScheduleAndSortOption(bool $sorted, string $expected)
{
$schedule = new Schedule();
$schedule
->add(RecurringMessage::every('3 minutes', new \stdClass()))
->add(RecurringMessage::every('1 minute', new \stdClass()))
->add(RecurringMessage::every('2 minutes', new \stdClass()))
;
$schedules = $this->createMock(ServiceProviderInterface::class);
$schedules
->expects($this->once())
->method('getProvidedServices')
->willReturn(['schedule_name' => $schedule])
;
$schedules
->expects($this->once())
->method('get')
->willReturn($schedule)
;
$command = new DebugCommand($schedules);
$tester = new CommandTester($command);
$tester->execute(['--sort' => $sorted], ['decorated' => false]);
$this->assertMatchesRegularExpression($expected, $tester->getDisplay(true));
}
public static function provideSorting(): iterable
{
yield 'Not sorted results' => [
false,
"/\n".
"Scheduler\n".
"=========\n".
"\n".
"schedule_name\n".
"-------------\n".
"\n".
" ----------------- ---------- --------------------------------- \n".
" Trigger Provider Next Run \n".
" ----------------- ---------- --------------------------------- \n".
" every 3 minutes stdClass \w{3}, \d{1,2} \w{3} \d{4} \d{2}:\d{2}:\d{2} (\+|-)\d{4} \n".
" every 1 minute stdClass \w{3}, \d{1,2} \w{3} \d{4} \d{2}:\d{2}:\d{2} (\+|-)\d{4} \n".
" every 2 minutes stdClass \w{3}, \d{1,2} \w{3} \d{4} \d{2}:\d{2}:\d{2} (\+|-)\d{4} \n".
" ----------------- ---------- --------------------------------- \n".
"\n/",
];
yield 'Sorted results' => [
true,
"/\n".
"Scheduler\n".
"=========\n".
"\n".
"schedule_name\n".
"-------------\n".
"\n".
" ----------------- ---------- --------------------------------- \n".
" Trigger Provider Next Run \n".
" ----------------- ---------- --------------------------------- \n".
" every 1 minute stdClass \w{3}, \d{1,2} \w{3} \d{4} \d{2}:\d{2}:\d{2} (\+|-)\d{4} \n".
" every 2 minutes stdClass \w{3}, \d{1,2} \w{3} \d{4} \d{2}:\d{2}:\d{2} (\+|-)\d{4} \n".
" every 3 minutes stdClass \w{3}, \d{1,2} \w{3} \d{4} \d{2}:\d{2}:\d{2} (\+|-)\d{4} \n".
" ----------------- ---------- --------------------------------- \n".
"\n/",
];
}
}