diff --git a/src/Command/ListTaskCommand.php b/src/Command/ListTaskCommand.php index dc5e221..ecf1097 100644 --- a/src/Command/ListTaskCommand.php +++ b/src/Command/ListTaskCommand.php @@ -7,37 +7,33 @@ use App\Entity\Task; use App\Repository\TaskRepository; use Symfony\Component\Console\Attribute\AsCommand; +use Symfony\Component\Console\Attribute\Option; use Symfony\Component\Console\Command\Command; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Input\InputOption; -use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Style\SymfonyStyle; /** * @author Tobias Nyholm */ -#[AsCommand(name: 'app:task:list')] -final class ListTaskCommand extends Command +#[AsCommand( + name: 'app:task:list', + description: 'List scheduled tasks', +)] +final class ListTaskCommand { public function __construct( private readonly TaskRepository $repository, ) { - parent::__construct(); } - protected function configure(): void - { - $this->addOption('number', null, InputOption::VALUE_REQUIRED, 'The issue number we are interested in', null); - } - - protected function execute(InputInterface $input, OutputInterface $output): int - { - /** @var mixed|null $number */ - $number = $input->getOption('number'); + public function __invoke( + SymfonyStyle $io, + #[Option(description: 'The issue number we are interested in')] + ?int $number = null, + ): int { if (null === $number) { $criteria = []; } else { - $criteria = ['number' => (int) $number]; + $criteria = ['number' => $number]; } $limit = 100; @@ -53,7 +49,6 @@ protected function execute(InputInterface $input, OutputInterface $output): int ]; } - $io = new SymfonyStyle($input, $output); $io->table(['Repo', 'Number', 'Action', 'Verify After'], $rows); $io->write(sprintf('Total of %d items in the table. ', $taskCount = count($tasks))); if ($limit === $taskCount) { diff --git a/src/Command/PingStaleIssuesCommand.php b/src/Command/PingStaleIssuesCommand.php index 397ed21..89affa7 100644 --- a/src/Command/PingStaleIssuesCommand.php +++ b/src/Command/PingStaleIssuesCommand.php @@ -11,11 +11,10 @@ use App\Service\RepositoryProvider; use App\Service\StaleIssueCommentGenerator; use App\Service\TaskScheduler; +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\Input\InputArgument; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; /** @@ -23,8 +22,11 @@ * * @author Tobias Nyholm */ -#[AsCommand(name: 'app:issue:ping-stale')] -final class PingStaleIssuesCommand extends Command +#[AsCommand( + name: 'app:issue:ping-stale', + description: 'Ping stale issues and schedule them for closing', +)] +final class PingStaleIssuesCommand { public const string MESSAGE_TWO_AFTER = '+2weeks'; public const string MESSAGE_THREE_AND_CLOSE_AFTER = '+2weeks'; @@ -36,35 +38,30 @@ public function __construct( private readonly StaleIssueCommentGenerator $commentGenerator, private readonly LabelApi $labelApi, ) { - parent::__construct(); } - protected function configure(): void - { - $this->addArgument('repository', InputArgument::REQUIRED, 'The full name to the repository, eg symfony/symfony-docs'); - $this->addOption('not-updated-for', null, InputOption::VALUE_REQUIRED, 'A string representing a time period to for how long the issue has been stalled.', '12months'); - $this->addOption('dry-run', null, InputOption::VALUE_NONE, 'Do a test search without making any comments or changes'); - } - - protected function execute(InputInterface $input, OutputInterface $output): int - { - /** @var string $repositoryName */ - $repositoryName = $input->getArgument('repository'); - $repository = $this->repositoryProvider->getRepository($repositoryName); - if (null === $repository) { + public function __invoke( + OutputInterface $output, + #[Argument(description: 'The full name to the repository, eg symfony/symfony-docs')] + string $repository, + #[Option(description: 'A string representing a time period to for how long the issue has been stalled.')] + string $notUpdatedFor = '12months', + #[Option(description: 'Do a test search without making any comments or changes')] + bool $dryRun = false, + ): int { + $repo = $this->repositoryProvider->getRepository($repository); + if (null === $repo) { $output->writeln('Repository not configured'); return Command::FAILURE; } - /** @var string $timeString */ - $timeString = $input->getOption('not-updated-for'); - $notUpdatedAfter = new \DateTimeImmutable('-'.ltrim($timeString, '-')); - $issues = $this->issueApi->findStaleIssues($repository, $notUpdatedAfter); + $notUpdatedAfter = new \DateTimeImmutable('-'.ltrim($notUpdatedFor, '-')); + $issues = $this->issueApi->findStaleIssues($repo, $notUpdatedAfter); - if ($input->getOption('dry-run')) { + if ($dryRun) { foreach ($issues as $issue) { - $output->writeln(sprintf('Marking issue #%s as "Stalled". Link https://github.com/%s/issues/%s', $issue['number'], $repository->getFullName(), $issue['number'])); + $output->writeln(sprintf('Marking issue #%s as "Stalled". Link https://github.com/%s/issues/%s', $issue['number'], $repo->getFullName(), $issue['number'])); } return Command::SUCCESS; @@ -75,11 +72,11 @@ protected function execute(InputInterface $input, OutputInterface $output): int * @var array{number: int, name: string, labels: array} $issue */ $comment = $this->commentGenerator->getComment($this->extractType($issue)); - $this->issueApi->commentOnIssue($repository, $issue['number'], $comment); - $this->labelApi->addIssueLabel($issue['number'], 'Stalled', $repository); + $this->issueApi->commentOnIssue($repo, $issue['number'], $comment); + $this->labelApi->addIssueLabel($issue['number'], 'Stalled', $repo); // add a scheduled task to process this issue again after 2 weeks - $this->scheduler->runLater($repository, $issue['number'], Task::ACTION_INFORM_CLOSE_STALE, new \DateTimeImmutable(self::MESSAGE_TWO_AFTER)); + $this->scheduler->runLater($repo, $issue['number'], Task::ACTION_INFORM_CLOSE_STALE, new \DateTimeImmutable(self::MESSAGE_TWO_AFTER)); } return Command::SUCCESS; diff --git a/src/Command/RunTaskCommand.php b/src/Command/RunTaskCommand.php index f98b0e1..c6e5317 100644 --- a/src/Command/RunTaskCommand.php +++ b/src/Command/RunTaskCommand.php @@ -8,30 +8,28 @@ use App\Service\TaskRunner; use Psr\Log\LoggerInterface; use Symfony\Component\Console\Attribute\AsCommand; +use Symfony\Component\Console\Attribute\Option; use Symfony\Component\Console\Command\Command; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; -#[AsCommand(name: 'app:task:run')] -final class RunTaskCommand extends Command +#[AsCommand( + name: 'app:task:run', + description: 'Run scheduled tasks', +)] +final class RunTaskCommand { public function __construct( private readonly TaskRepository $repository, private readonly TaskRunner $taskRunner, private readonly LoggerInterface $logger, ) { - parent::__construct(); } - protected function configure(): void - { - $this->addOption('limit', 'l', InputOption::VALUE_REQUIRED, 'Limit the number of tasks to run', '10'); - } - - protected function execute(InputInterface $input, OutputInterface $output): int - { - $limit = (int) $input->getOption('limit'); + public function __invoke( + OutputInterface $output, + #[Option(name: 'limit', shortcut: 'l', description: 'Limit the number of tasks to run')] + int $limit = 10, + ): int { foreach ($this->repository->getTasksToVerify($limit) as $task) { try { $this->taskRunner->run($task);