Skip to content

Commit 4713f31

Browse files
committed
PHPStan
1 parent 327e0cc commit 4713f31

11 files changed

Lines changed: 66 additions & 102 deletions

composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060
},
6161
"require-dev": {
6262
"amphp/amp": "^2.5",
63+
"ekino/phpstan-banned-code": "^3.2",
6364
"friendsofphp/php-cs-fixer": "^3.75",
6465
"phpunit/phpunit": "^11",
6566
"portphp/portphp": "^1.9",

phpstan.neon.dist

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
includes:
2+
- vendor/ekino/phpstan-banned-code/extension.neon
3+
parameters:
4+
level: 5
5+
paths:
6+
- src/

src/Command/ExecuteDataflowCommand.php

Lines changed: 15 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,9 @@
1010
use CodeRhapsodie\DataflowBundle\Repository\JobRepository;
1111
use Psr\Log\LoggerAwareInterface;
1212
use Psr\Log\LoggerAwareTrait;
13+
use Symfony\Component\Console\Attribute\Argument;
1314
use Symfony\Component\Console\Attribute\AsCommand;
14-
use Symfony\Component\Console\Command\Command;
15-
use Symfony\Component\Console\Input\InputArgument;
16-
use Symfony\Component\Console\Input\InputInterface;
17-
use Symfony\Component\Console\Input\InputOption;
18-
use Symfony\Component\Console\Output\OutputInterface;
15+
use Symfony\Component\Console\Attribute\Option;
1916
use Symfony\Component\Console\Style\SymfonyStyle;
2017

2118
/**
@@ -28,33 +25,27 @@
2825
2926
<info>php %command.full_name% App\Dataflow\MyDataflow '{"option1": "value1", "option2": "value2"}'</info>
3027
TXT)]
31-
class ExecuteDataflowCommand extends Command implements LoggerAwareInterface
28+
final class ExecuteDataflowCommand implements LoggerAwareInterface
3229
{
3330
use LoggerAwareTrait;
3431

35-
public function __construct(private DataflowTypeRegistryInterface $registry, private ConnectionFactory $connectionFactory, private JobRepository $jobRepository)
32+
public function __construct(private readonly DataflowTypeRegistryInterface $registry, private readonly ConnectionFactory $connectionFactory, private readonly JobRepository $jobRepository)
3633
{
37-
parent::__construct();
3834
}
3935

40-
protected function configure(): void
41-
{
42-
$this
43-
->addArgument('fqcn', InputArgument::REQUIRED, 'FQCN or alias of the dataflow type')
44-
->addArgument('options', InputArgument::OPTIONAL, 'Options for the dataflow type as a json string', '[]')
45-
->addOption('connection', null, InputOption::VALUE_REQUIRED, 'Define the DBAL connection to use');
46-
}
47-
48-
protected function execute(InputInterface $input, OutputInterface $output): int
49-
{
50-
if ($input->getOption('connection') !== null) {
51-
$this->connectionFactory->setConnectionName($input->getOption('connection'));
36+
public function __invoke(
37+
SymfonyStyle $io,
38+
#[Argument('FQCN or alias of the dataflow type')] string $fqcn,
39+
#[Argument('Options for the dataflow type as a json string')] string $options = '[]',
40+
#[Option('Define the DBAL connection to use')] ?string $connection = null,
41+
): int {
42+
if ($connection !== null) {
43+
$this->connectionFactory->setConnectionName($connection);
5244
}
53-
$fqcnOrAlias = $input->getArgument('fqcn');
54-
$options = json_decode((string) $input->getArgument('options'), true, 512, \JSON_THROW_ON_ERROR);
55-
$io = new SymfonyStyle($input, $output);
5645

57-
$dataflowType = $this->registry->getDataflowType($fqcnOrAlias);
46+
$options = json_decode($options, true, 512, \JSON_THROW_ON_ERROR);
47+
48+
$dataflowType = $this->registry->getDataflowType($fqcn);
5849
if ($dataflowType instanceof AutoUpdateCountInterface) {
5950
$dataflowType->setRepository($this->jobRepository);
6051
}

src/Command/JobShowCommand.php

Lines changed: 16 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,7 @@
88
use CodeRhapsodie\DataflowBundle\Factory\ConnectionFactory;
99
use CodeRhapsodie\DataflowBundle\Gateway\JobGateway;
1010
use Symfony\Component\Console\Attribute\AsCommand;
11-
use Symfony\Component\Console\Command\Command;
12-
use Symfony\Component\Console\Input\InputInterface;
13-
use Symfony\Component\Console\Input\InputOption;
14-
use Symfony\Component\Console\Output\OutputInterface;
11+
use Symfony\Component\Console\Attribute\Option;
1512
use Symfony\Component\Console\Style\SymfonyStyle;
1613

1714
/**
@@ -20,38 +17,31 @@
2017
#[AsCommand('code-rhapsodie:dataflow:job:show', 'Display job details for schedule or specific job', help: <<<'TXT'
2118
The <info>%command.name%</info> display job details for schedule or specific job.
2219
TXT)]
23-
class JobShowCommand extends Command
20+
final readonly class JobShowCommand
2421
{
2522
private const STATUS_MAPPING = [
2623
Job::STATUS_PENDING => 'Pending',
2724
Job::STATUS_RUNNING => 'Running',
2825
Job::STATUS_COMPLETED => 'Completed',
26+
Job::STATUS_QUEUED => 'Queued',
27+
Job::STATUS_CRASHED => 'Crashed',
2928
];
3029

31-
public function __construct(private readonly JobGateway $jobGateway, private readonly ConnectionFactory $connectionFactory)
30+
public function __construct(private JobGateway $jobGateway, private ConnectionFactory $connectionFactory)
3231
{
33-
parent::__construct();
3432
}
3533

36-
protected function configure(): void
37-
{
38-
$this
39-
->addOption('job-id', null, InputOption::VALUE_REQUIRED, 'Id of the job to get details')
40-
->addOption('schedule-id', null, InputOption::VALUE_REQUIRED, 'Id of schedule for last execution details')
41-
->addOption('details', null, InputOption::VALUE_NONE, 'Display full details')
42-
->addOption('connection', null, InputOption::VALUE_REQUIRED, 'Define the DBAL connection to use');
43-
}
44-
45-
protected function execute(InputInterface $input, OutputInterface $output): int
46-
{
47-
if ($input->getOption('connection') !== null) {
48-
$this->connectionFactory->setConnectionName($input->getOption('connection'));
34+
public function __invoke(
35+
SymfonyStyle $io,
36+
#[Option('Id of the job to get details')] ?int $jobId = null,
37+
#[Option('Id of schedule for last execution details')] ?int $scheduleId = null,
38+
#[Option('Display full details')] bool $details = false,
39+
#[Option('Define the DBAL connection to use')] ?string $connection = null,
40+
): int {
41+
if ($connection !== null) {
42+
$this->connectionFactory->setConnectionName($connection);
4943
}
5044

51-
$io = new SymfonyStyle($input, $output);
52-
53-
$jobId = (int) $input->getOption('job-id');
54-
$scheduleId = (int) $input->getOption('schedule-id');
5545
if ($jobId && $scheduleId) {
5646
$io->error('You must use `job-id` OR `schedule-id` option, not the 2 in the same time.');
5747

@@ -85,14 +75,14 @@ protected function execute(InputInterface $input, OutputInterface $output): int
8575
['Errors', \count((array) $job->getExceptions())],
8676
['Status', $this->translateStatus($job->getStatus())],
8777
];
88-
if ($input->getOption('details')) {
78+
if ($details) {
8979
$display[] = ['Type', $job->getDataflowType()];
9080
$display[] = ['Options', json_encode($job->getOptions(), \JSON_THROW_ON_ERROR)];
9181
$io->section('Summary');
9282
}
9383

9484
$io->table(['Field', 'Value'], $display);
95-
if ($input->getOption('details')) {
85+
if ($details) {
9686
$io->section('Exceptions');
9787
$exceptions = array_map(static fn (string $exception) => substr($exception, 0, 900).'', $job->getExceptions());
9888

src/Command/RunPendingDataflowsCommand.php

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,9 @@
88
use CodeRhapsodie\DataflowBundle\Manager\ScheduledDataflowManagerInterface;
99
use CodeRhapsodie\DataflowBundle\Runner\PendingDataflowRunnerInterface;
1010
use Symfony\Component\Console\Attribute\AsCommand;
11-
use Symfony\Component\Console\Command\Command;
11+
use Symfony\Component\Console\Attribute\Option;
1212
use Symfony\Component\Console\Command\LockableTrait;
13-
use Symfony\Component\Console\Input\InputInterface;
14-
use Symfony\Component\Console\Input\InputOption;
15-
use Symfony\Component\Console\Output\OutputInterface;
13+
use Symfony\Component\Console\Style\SymfonyStyle;
1614

1715
/**
1816
* Runs dataflows according to user-defined schedule.
@@ -22,31 +20,26 @@
2220
#[AsCommand('code-rhapsodie:dataflow:run-pending', 'Runs dataflows based on the scheduled defined in the UI.', help: <<<'TXT'
2321
The <info>%command.name%</info> command runs dataflows according to the schedule defined in the UI by the user.
2422
TXT)]
25-
class RunPendingDataflowsCommand extends Command
23+
final class RunPendingDataflowsCommand
2624
{
2725
use LockableTrait;
2826

29-
public function __construct(private ScheduledDataflowManagerInterface $manager, private PendingDataflowRunnerInterface $runner, private ConnectionFactory $connectionFactory)
27+
public function __construct(private readonly ScheduledDataflowManagerInterface $manager, private readonly PendingDataflowRunnerInterface $runner, private readonly ConnectionFactory $connectionFactory)
3028
{
31-
parent::__construct();
3229
}
3330

34-
protected function configure(): void
35-
{
36-
$this
37-
->addOption('connection', null, InputOption::VALUE_REQUIRED, 'Define the DBAL connection to use');
38-
}
39-
40-
protected function execute(InputInterface $input, OutputInterface $output): int
41-
{
31+
public function __invoke(
32+
SymfonyStyle $io,
33+
#[Option('Define the DBAL connection to use')] ?string $connection = null,
34+
): int {
4235
if (!$this->lock()) {
43-
$output->writeln('The command is already running in another process.');
36+
$io->writeln('The command is already running in another process.');
4437

4538
return 0;
4639
}
4740

48-
if ($input->getOption('connection') !== null) {
49-
$this->connectionFactory->setConnectionName($input->getOption('connection'));
41+
if ($connection !== null) {
42+
$this->connectionFactory->setConnectionName($connection);
5043
}
5144

5245
$this->manager->createJobsFromScheduledDataflows();

src/Command/ScheduleListCommand.php

Lines changed: 10 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,7 @@
77
use CodeRhapsodie\DataflowBundle\Factory\ConnectionFactory;
88
use CodeRhapsodie\DataflowBundle\Repository\ScheduledDataflowRepository;
99
use Symfony\Component\Console\Attribute\AsCommand;
10-
use Symfony\Component\Console\Command\Command;
11-
use Symfony\Component\Console\Input\InputInterface;
12-
use Symfony\Component\Console\Input\InputOption;
13-
use Symfony\Component\Console\Output\OutputInterface;
10+
use Symfony\Component\Console\Attribute\Option;
1411
use Symfony\Component\Console\Style\SymfonyStyle;
1512

1613
/**
@@ -19,25 +16,20 @@
1916
#[AsCommand('code-rhapsodie:dataflow:schedule:list', 'List scheduled dataflows', help: <<<'TXT'
2017
The <info>%command.name%</info> lists all scheduled dataflows.
2118
TXT)]
22-
class ScheduleListCommand extends Command
19+
final readonly class ScheduleListCommand
2320
{
24-
public function __construct(private readonly ScheduledDataflowRepository $scheduledDataflowRepository, private readonly ConnectionFactory $connectionFactory)
21+
public function __construct(private ScheduledDataflowRepository $scheduledDataflowRepository, private ConnectionFactory $connectionFactory)
2522
{
26-
parent::__construct();
2723
}
2824

29-
protected function configure(): void
30-
{
31-
$this
32-
->addOption('connection', null, InputOption::VALUE_REQUIRED, 'Define the DBAL connection to use');
33-
}
34-
35-
protected function execute(InputInterface $input, OutputInterface $output): int
36-
{
37-
if ($input->getOption('connection') !== null) {
38-
$this->connectionFactory->setConnectionName($input->getOption('connection'));
25+
public function __invoke(
26+
SymfonyStyle $io,
27+
#[Option('Define the DBAL connection to use')] ?string $connection = null,
28+
): int {
29+
if ($connection !== null) {
30+
$this->connectionFactory->setConnectionName($connection);
3931
}
40-
$io = new SymfonyStyle($input, $output);
32+
4133
$display = [];
4234
$schedules = $this->scheduledDataflowRepository->listAllOrderedByLabel();
4335
foreach ($schedules as $schedule) {

src/Command/SetCrashedCommand.php

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,24 +7,17 @@
77
use CodeRhapsodie\DataflowBundle\Repository\JobRepository;
88
use Symfony\Component\Console\Attribute\AsCommand;
99
use Symfony\Component\Console\Command\Command;
10-
use Symfony\Component\Console\Input\InputInterface;
11-
use Symfony\Component\Console\Output\OutputInterface;
1210

1311
#[AsCommand(name: 'code-rhapsodie:dataflow:job:set-crashed', description: 'Set long running jobs as crashed.', help: <<<'TXT'
1412
How long jobs have to run before they are set as crashed can be configured with the "job_history.crashed_delay" configuration.
1513
TXT)]
16-
class SetCrashedCommand extends Command
14+
final readonly class SetCrashedCommand
1715
{
18-
public function __construct(private readonly JobRepository $jobRepository, private readonly int $crashedDelay)
16+
public function __construct(private JobRepository $jobRepository, private int $crashedDelay)
1917
{
20-
parent::__construct();
2118
}
2219

23-
protected function configure()
24-
{
25-
}
26-
27-
protected function execute(InputInterface $input, OutputInterface $output): int
20+
public function __invoke(): int
2821
{
2922
$this->jobRepository->crashLongRunning($this->crashedDelay);
3023

src/DataflowType/Dataflow/AMPAsyncDataflow.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ class AMPAsyncDataflow implements DataflowInterface, LoggerAwareInterface
2323
{
2424
use LoggerAwareTrait;
2525

26-
/** @var callable[] */
26+
/** @var array<array<callable|int>> */
2727
private array $steps = [];
2828

2929
/** @var WriterInterface[] */

src/DataflowType/Dataflow/Dataflow.php

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,6 @@ class Dataflow implements DataflowInterface, LoggerAwareInterface
2121

2222
private ?\Closure $customExceptionIndex = null;
2323

24-
private ?\DateTimeInterface $dateTime = null;
25-
2624
/**
2725
* @var \Closure[]
2826
*/

src/Entity/Job.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ class Job
6464

6565
public static function createFromScheduledDataflow(ScheduledDataflow $scheduled): self
6666
{
67-
return (new static())
67+
return (new self())
6868
->setStatus(static::STATUS_PENDING)
6969
->setDataflowType($scheduled->getDataflowType())
7070
->setOptions($scheduled->getOptions())
@@ -75,7 +75,7 @@ public static function createFromScheduledDataflow(ScheduledDataflow $scheduled)
7575

7676
public static function createFromArray(array $datas)
7777
{
78-
$lost = array_diff(static::KEYS, array_keys($datas));
78+
$lost = array_diff(self::KEYS, array_keys($datas));
7979
if (\count($lost) > 0) {
8080
throw new \LogicException('The first argument of '.__METHOD__.' must be contains: "'.implode(', ', $lost).'"');
8181
}

0 commit comments

Comments
 (0)