From 7abf2415c6e39d07af52550fa5a1240a7292a7f2 Mon Sep 17 00:00:00 2001 From: michalsn Date: Thu, 6 Mar 2025 16:14:16 +0100 Subject: [PATCH 1/2] chore: rector php 8.1 --- psalm.xml | 1 + rector.php | 72 +++++++++++++++++++++++++++-- src/FrequenciesTrait.php | 14 +++--- src/RunResolver.php | 27 +++-------- src/Task.php | 20 +++----- src/TaskRunner.php | 4 +- tests/mock/MockTest.php | 2 +- tests/unit/CronExpressionTest.php | 8 +++- tests/unit/FrequenciesTraitTest.php | 2 +- tests/unit/SchedulerTest.php | 2 +- tests/unit/TaskTest.php | 5 -- 11 files changed, 101 insertions(+), 56 deletions(-) diff --git a/psalm.xml b/psalm.xml index 976c974..86ab980 100644 --- a/psalm.xml +++ b/psalm.xml @@ -10,6 +10,7 @@ cacheDirectory="build/psalm/" findUnusedBaselineEntry="false" findUnusedCode="false" + ensureOverrideAttribute="false" > diff --git a/rector.php b/rector.php index 0e31556..e824476 100644 --- a/rector.php +++ b/rector.php @@ -11,21 +11,28 @@ * the LICENSE file that was distributed with this source code. */ +use Rector\Caching\ValueObject\Storage\FileCacheStorage; use Rector\CodeQuality\Rector\BooleanAnd\SimplifyEmptyArrayCheckRector; +use Rector\CodeQuality\Rector\Class_\CompleteDynamicPropertiesRector; +use Rector\CodeQuality\Rector\Empty_\SimplifyEmptyCheckOnEmptyArrayRector; use Rector\CodeQuality\Rector\Expression\InlineIfToExplicitIfRector; use Rector\CodeQuality\Rector\Foreach_\UnusedForeachValueToArrayKeysRector; use Rector\CodeQuality\Rector\FuncCall\ChangeArrayPushToArrayAssignRector; use Rector\CodeQuality\Rector\FuncCall\SimplifyRegexPatternRector; use Rector\CodeQuality\Rector\FuncCall\SimplifyStrposLowerRector; +use Rector\CodeQuality\Rector\FuncCall\SingleInArrayToCompareRector; use Rector\CodeQuality\Rector\FunctionLike\SimplifyUselessVariableRector; use Rector\CodeQuality\Rector\If_\CombineIfRector; +use Rector\CodeQuality\Rector\If_\ExplicitBoolCompareRector; use Rector\CodeQuality\Rector\If_\ShortenElseIfRector; use Rector\CodeQuality\Rector\If_\SimplifyIfElseToTernaryRector; use Rector\CodeQuality\Rector\If_\SimplifyIfReturnBoolRector; +use Rector\CodeQuality\Rector\Ternary\TernaryEmptyArrayArrayDimFetchToCoalesceRector; use Rector\CodeQuality\Rector\Ternary\UnnecessaryTernaryExpressionRector; use Rector\CodingStyle\Rector\ClassMethod\FuncGetArgsToVariadicParamRector; use Rector\CodingStyle\Rector\ClassMethod\MakeInheritedMethodVisibilitySameAsParentRector; use Rector\CodingStyle\Rector\FuncCall\CountArrayToEmptyArrayComparisonRector; +use Rector\CodingStyle\Rector\FuncCall\VersionCompareFuncCallToConstantRector; use Rector\Config\RectorConfig; use Rector\DeadCode\Rector\ClassMethod\RemoveUnusedPromotedPropertyRector; use Rector\EarlyReturn\Rector\Foreach_\ChangeNestedForeachIfsToEarlyContinueRector; @@ -34,14 +41,34 @@ use Rector\EarlyReturn\Rector\Return_\PreparedValueToEarlyReturnRector; use Rector\Php55\Rector\String_\StringClassNameToClassConstantRector; use Rector\Php73\Rector\FuncCall\StringifyStrNeedlesRector; +use Rector\PHPUnit\AnnotationsToAttributes\Rector\Class_\AnnotationWithValueToAttributeRector; +use Rector\PHPUnit\CodeQuality\Rector\Class_\YieldDataProviderRector; use Rector\PHPUnit\Set\PHPUnitSetList; +use Rector\Privatization\Rector\Property\PrivatizeFinalClassPropertyRector; use Rector\Set\ValueObject\LevelSetList; use Rector\Set\ValueObject\SetList; +use Rector\Strict\Rector\Empty_\DisallowedEmptyRuleFixerRector; +use Rector\Strict\Rector\If_\BooleanInIfConditionRuleFixerRector; +use Rector\TypeDeclaration\Rector\Empty_\EmptyOnNullableObjectToInstanceOfRector; +use Rector\TypeDeclaration\Rector\Property\TypedPropertyFromAssignsRector; use Rector\ValueObject\PhpVersion; return static function (RectorConfig $rectorConfig): void { - $rectorConfig->sets([SetList::DEAD_CODE, LevelSetList::UP_TO_PHP_74, PHPUnitSetList::PHPUNIT_80]); + $rectorConfig->sets([ + SetList::DEAD_CODE, + LevelSetList::UP_TO_PHP_81, + PHPUnitSetList::PHPUNIT_CODE_QUALITY, + PHPUnitSetList::PHPUNIT_100, + ]); + $rectorConfig->parallel(); + + // Github action cache + $rectorConfig->cacheClass(FileCacheStorage::class); + if (is_dir('/tmp')) { + $rectorConfig->cacheDirectory('/tmp/rector'); + } + // The paths to refactor (can also be supplied with CLI arguments) $rectorConfig->paths([ __DIR__ . '/src/', @@ -63,23 +90,41 @@ } // Set the target version for refactoring - $rectorConfig->phpVersion(PhpVersion::PHP_74); + $rectorConfig->phpVersion(PhpVersion::PHP_81); // Auto-import fully qualified class names $rectorConfig->importNames(); // Are there files or rules you need to skip? $rectorConfig->skip([ - __DIR__ . '/src/Views', + __DIR__ . '/app/Views', StringifyStrNeedlesRector::class, + YieldDataProviderRector::class, // Note: requires php 8 RemoveUnusedPromotedPropertyRector::class, + AnnotationWithValueToAttributeRector::class, // May load view files directly when detecting classes StringClassNameToClassConstantRector::class, + + // Because of the BaseCommand + TypedPropertyFromAssignsRector::class => [ + __DIR__ . '/src/Commands/Disable.php', + __DIR__ . '/src/Commands/Enable.php', + __DIR__ . '/src/Commands/Lister.php', + __DIR__ . '/src/Commands/Publish.php', + __DIR__ . '/src/Commands/Run.php', + __DIR__ . '/src/Commands/TaskCommand.php', + __DIR__ . '/tests/_support/Commands/TasksExample.php', + __DIR__ . '/tests/unit/TaskRunnerTest.php', + ], ]); + + // auto import fully qualified class names + $rectorConfig->importNames(); + $rectorConfig->rule(SimplifyUselessVariableRector::class); $rectorConfig->rule(RemoveAlwaysElseRector::class); $rectorConfig->rule(CountArrayToEmptyArrayComparisonRector::class); @@ -99,4 +144,25 @@ $rectorConfig->rule(FuncGetArgsToVariadicParamRector::class); $rectorConfig->rule(MakeInheritedMethodVisibilitySameAsParentRector::class); $rectorConfig->rule(SimplifyEmptyArrayCheckRector::class); + $rectorConfig->rule(SimplifyEmptyCheckOnEmptyArrayRector::class); + $rectorConfig->rule(TernaryEmptyArrayArrayDimFetchToCoalesceRector::class); + $rectorConfig->rule(EmptyOnNullableObjectToInstanceOfRector::class); + $rectorConfig->rule(DisallowedEmptyRuleFixerRector::class); + $rectorConfig + ->ruleWithConfiguration(TypedPropertyFromAssignsRector::class, [ + /** + * The INLINE_PUBLIC value is default to false to avoid BC break, + * if you use for libraries and want to preserve BC break, you don't + * need to configure it, as it included in LevelSetList::UP_TO_PHP_74 + * Set to true for projects that allow BC break + */ + TypedPropertyFromAssignsRector::INLINE_PUBLIC => true, + ]); + $rectorConfig->rule(StringClassNameToClassConstantRector::class); + $rectorConfig->rule(PrivatizeFinalClassPropertyRector::class); + $rectorConfig->rule(CompleteDynamicPropertiesRector::class); + $rectorConfig->rule(BooleanInIfConditionRuleFixerRector::class); + $rectorConfig->rule(SingleInArrayToCompareRector::class); + $rectorConfig->rule(VersionCompareFuncCallToConstantRector::class); + $rectorConfig->rule(ExplicitBoolCompareRector::class); }; diff --git a/src/FrequenciesTrait.php b/src/FrequenciesTrait.php index ce35030..7c8243d 100644 --- a/src/FrequenciesTrait.php +++ b/src/FrequenciesTrait.php @@ -71,7 +71,7 @@ public function daily(?string $time = null) { $min = $hour = 0; - if (! empty($time)) { + if ($time !== null && $time !== '' && $time !== '0') { [$min, $hour] = $this->parseTime($time); } @@ -323,7 +323,7 @@ public function monthly(?string $time = null) { $min = $hour = 0; - if (! empty($time)) { + if ($time !== null && $time !== '' && $time !== '0') { [$min, $hour] = $this->parseTime($time); } @@ -403,7 +403,7 @@ public function quarterly(?string $time = null) { $min = $hour = 0; - if (! empty($time)) { + if ($time !== null && $time !== '' && $time !== '0') { [$min, $hour] = $this->parseTime($time); } @@ -425,7 +425,7 @@ public function yearly(?string $time = null) { $min = $hour = 0; - if (! empty($time)) { + if ($time !== null && $time !== '' && $time !== '0') { [$min, $hour] = $this->parseTime($time); } @@ -446,7 +446,7 @@ public function weekdays(?string $time = null) { $min = $hour = 0; - if (! empty($time)) { + if ($time !== null && $time !== '' && $time !== '0') { [$min, $hour] = $this->parseTime($time); } @@ -466,7 +466,7 @@ public function weekends(?string $time = null) { $min = $hour = 0; - if (! empty($time)) { + if ($time !== null && $time !== '' && $time !== '0') { [$min, $hour] = $this->parseTime($time); } @@ -486,7 +486,7 @@ protected function setDayOfWeek(int $day, ?string $time = null) { $min = $hour = '*'; - if (! empty($time)) { + if ($time !== null && $time !== '' && $time !== '0') { [$min, $hour] = $this->parseTime($time); } diff --git a/src/RunResolver.php b/src/RunResolver.php index 316131a..e9d24f5 100644 --- a/src/RunResolver.php +++ b/src/RunResolver.php @@ -121,26 +121,13 @@ public function nextRun(string $expression, Time $next): Time */ protected function increment(Time $next, string $position): Time { - switch ($position) { - case 'minute': - $next = $next->addMinutes(1); - break; - - case 'hour': - $next = $next->addHours(1); - break; - - case 'monthDay': - case 'weekDay': - $next = $next->addDays(1); - break; - - case 'month': - $next = $next->addMonths(1); - break; - } - - return $next; + return match ($position) { + 'minute' => $next->addMinutes(1), + 'hour' => $next->addHours(1), + 'monthDay', 'weekDay' => $next->addDays(1), + 'month' => $next->addMonths(1), + default => $next, + }; } /** diff --git a/src/Task.php b/src/Task.php index 3c1b266..6ccd61f 100644 --- a/src/Task.php +++ b/src/Task.php @@ -55,13 +55,6 @@ class Task */ protected string $type; - /** - * The actual content that should be run. - * - * @var mixed - */ - protected $action; - /** * If not empty, lists the allowed environments * this can run in. @@ -74,18 +67,17 @@ class Task protected string $name; /** - * @param mixed $action + * @param $action mixed The actual content that should be run. * * @throws TasksException */ - public function __construct(string $type, $action) + public function __construct(string $type, protected mixed $action) { if (! in_array($type, $this->types, true)) { throw TasksException::forInvalidTaskType($type); } - $this->type = $type; - $this->action = $action; + $this->type = $type; } /** @@ -144,12 +136,12 @@ public function shouldRun(?string $testTime = null): bool $cron = service('cronExpression'); // Allow times to be set during testing - if (! empty($testTime)) { + if ($testTime !== null && $testTime !== '' && $testTime !== '0') { $cron->testTime($testTime); } // Are we restricting to environments? - if (! empty($this->environments) && ! $this->runsInEnvironment($_SERVER['CI_ENVIRONMENT'])) { + if ($this->environments !== [] && ! $this->runsInEnvironment($_SERVER['CI_ENVIRONMENT'])) { return false; } @@ -201,7 +193,7 @@ public function lastRun() protected function runsInEnvironment(string $environment): bool { // If nothing is specified then it should run - if (empty($this->environments)) { + if ($this->environments === []) { return true; } diff --git a/src/TaskRunner.php b/src/TaskRunner.php index 62956b7..c41a0d2 100644 --- a/src/TaskRunner.php +++ b/src/TaskRunner.php @@ -52,11 +52,11 @@ public function run() foreach ($tasks as $task) { // If specific tasks were chosen then skip executing remaining tasks - if (! empty($this->only) && ! in_array($task->name, $this->only, true)) { + if ($this->only !== [] && ! in_array($task->name, $this->only, true)) { continue; } - if (! $task->shouldRun($this->testTime) && empty($this->only)) { + if (! $task->shouldRun($this->testTime) && $this->only === []) { continue; } diff --git a/tests/mock/MockTest.php b/tests/mock/MockTest.php index 09a1ad7..5893119 100644 --- a/tests/mock/MockTest.php +++ b/tests/mock/MockTest.php @@ -20,7 +20,7 @@ */ final class MockTest extends TasksTestCase { - protected MockScheduler $scheduler; + private MockScheduler $scheduler; protected function setUp(): void { diff --git a/tests/unit/CronExpressionTest.php b/tests/unit/CronExpressionTest.php index a26f527..8655f0b 100644 --- a/tests/unit/CronExpressionTest.php +++ b/tests/unit/CronExpressionTest.php @@ -22,7 +22,7 @@ */ final class CronExpressionTest extends TestCase { - protected CronExpression $cron; + private CronExpression $cron; protected function setUp(): void { @@ -207,7 +207,11 @@ public static function provideEveryHour(): iterable $h . ':10 PM', ], range(1, 12)); - return [...$hours24, ...$hoursAM, ...$hoursPM]; + return [ + ...$hours24, + ...$hoursAM, + ...$hoursPM, + ]; } public static function provideNextRun(): iterable diff --git a/tests/unit/FrequenciesTraitTest.php b/tests/unit/FrequenciesTraitTest.php index 7aac4f3..e9c2db3 100644 --- a/tests/unit/FrequenciesTraitTest.php +++ b/tests/unit/FrequenciesTraitTest.php @@ -19,7 +19,7 @@ */ final class FrequenciesTraitTest extends TestCase { - protected object $class; + private object $class; protected function setUp(): void { diff --git a/tests/unit/SchedulerTest.php b/tests/unit/SchedulerTest.php index 504fa35..ed1c5cd 100644 --- a/tests/unit/SchedulerTest.php +++ b/tests/unit/SchedulerTest.php @@ -20,7 +20,7 @@ */ final class SchedulerTest extends TestCase { - protected Scheduler $scheduler; + private Scheduler $scheduler; protected function setUp(): void { diff --git a/tests/unit/TaskTest.php b/tests/unit/TaskTest.php index 5267079..d08ad58 100644 --- a/tests/unit/TaskTest.php +++ b/tests/unit/TaskTest.php @@ -26,11 +26,6 @@ final class TaskTest extends TasksTestCase protected $namespace; - /** - * @var bool|resource - */ - protected $streamFilter; - protected function setUp(): void { parent::setUp(); From e5d1efd6b824a050ba61055ba600d0df65982b42 Mon Sep 17 00:00:00 2001 From: michalsn Date: Thu, 27 Mar 2025 10:02:26 +0100 Subject: [PATCH 2/2] update phpstan baseline --- phpstan-baseline.neon | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 1a0f597..f275e39 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -12,6 +12,18 @@ parameters: count: 1 path: src/Commands/Lister.php + - + message: '#^Call to an undefined method CodeIgniter\\I18n\\Time\:\:getMonthDay\(\)\.$#' + identifier: method.notFound + count: 1 + path: src/RunResolver.php + + - + message: '#^Call to an undefined method CodeIgniter\\I18n\\Time\:\:getWeekDay\(\)\.$#' + identifier: method.notFound + count: 1 + path: src/RunResolver.php + - message: '#^Call to method PHPUnit\\Framework\\Assert\:\:assertInstanceOf\(\) with ''CodeIgniter\\\\I18n\\\\Time'' and CodeIgniter\\I18n\\Time will always evaluate to true\.$#' identifier: method.alreadyNarrowedType