diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php index c13256e..80b4e00 100644 --- a/.php-cs-fixer.dist.php +++ b/.php-cs-fixer.dist.php @@ -1,22 +1,69 @@ setHeader( + <<setHeader($header, true) + The TYPO3 project - inspiring people to share! + EOM, + true + ) + ->addRules([ + '@PER:risky' => true, + '@PHP80Migration:risky' => true, + '@PHP81Migration' => true, + 'declare_strict_types' => true, + 'fully_qualified_strict_types' => true, + 'global_namespace_import' => [ + 'import_classes' => true, + 'import_constants' => false, + 'import_functions' => false, + ], + 'no_unneeded_import_alias' => true, + 'ordered_imports' => [ + 'imports_order' => ['class', 'function', 'const'], + 'sort_algorithm' => 'alpha', + ], + 'phpdoc_align' => true, + 'phpdoc_annotation_without_dot' => true, + 'phpdoc_indent' => true, + 'phpdoc_inline_tag_normalizer' => true, + 'phpdoc_line_span' => true, + 'phpdoc_no_useless_inheritdoc' => true, + 'phpdoc_order' => true, + 'phpdoc_order_by_value' => true, + 'phpdoc_separation' => true, + 'phpdoc_single_line_var_spacing' => true, + 'phpdoc_summary' => true, + 'phpdoc_tag_casing' => true, + 'phpdoc_tag_type' => true, + 'phpdoc_to_comment' => [ + 'ignored_tags' => [ + 'phpstan-ignore-line', + 'phpstan-ignore-next-line', + 'todo', + ], + ], + 'phpdoc_trim_consecutive_blank_line_separation' => true, + 'phpdoc_types_order' => [ + 'null_adjustment' => 'always_last', + 'sort_algorithm' => 'alpha', + ], + 'phpdoc_var_annotation_correct_order' => true, + 'phpdoc_var_without_name' => true, + 'self_accessor' => true, + ]) ->getFinder() ->exclude('templates') + ->exclude('tests/Unit/Fixtures') ->in(__DIR__) ; diff --git a/rector.php b/rector.php index ae56a8e..565cac6 100644 --- a/rector.php +++ b/rector.php @@ -41,7 +41,7 @@ // define sets of rules $rectorConfig->sets([ - LevelSetList::UP_TO_PHP_82, + LevelSetList::UP_TO_PHP_81, DowngradeLevelSetList::DOWN_TO_PHP_81, SetList::CODE_QUALITY, SetList::CODING_STYLE, diff --git a/src/Console/Application.php b/src/Console/Application.php index aa46082..3e381fc 100644 --- a/src/Console/Application.php +++ b/src/Console/Application.php @@ -36,7 +36,7 @@ final class Application extends BaseApplication public const VERSION = '0.8.0-DEV'; /** - * getcwd() equivalent which always returns a string + * getcwd() equivalent which always returns a string. * * @throws RuntimeException */ diff --git a/src/Console/Command/AbstractSetupCommand.php b/src/Console/Command/AbstractSetupCommand.php index 19148b6..7880232 100644 --- a/src/Console/Command/AbstractSetupCommand.php +++ b/src/Console/Command/AbstractSetupCommand.php @@ -28,7 +28,7 @@ abstract class AbstractSetupCommand extends Command { /** - * @var Setup $setup + * @var Setup */ protected $setup; diff --git a/src/Console/Command/TypeTrait.php b/src/Console/Command/TypeTrait.php index 623f260..4dbc658 100644 --- a/src/Console/Command/TypeTrait.php +++ b/src/Console/Command/TypeTrait.php @@ -16,6 +16,7 @@ namespace TYPO3\CodingStandards\Console\Command; +use RuntimeException; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; @@ -39,6 +40,9 @@ protected function configureBefore(): void )); } + /** + * @throws RuntimeException + */ private function getType(InputInterface $input): string { if ($this->type === '') { @@ -49,17 +53,17 @@ private function getType(InputInterface $input): string $composerManifest = $this->getProjectDir() . '/composer.json'; if (!file_exists($composerManifest)) { - throw new \RuntimeException(sprintf($composerManifestError, 'found')); + throw new RuntimeException(sprintf($composerManifestError, 'found')); } $composerManifest = \file_get_contents($composerManifest); if ($composerManifest === false) { - throw new \RuntimeException(sprintf($composerManifestError, 'read')); // @codeCoverageIgnore + throw new RuntimeException(sprintf($composerManifestError, 'read')); // @codeCoverageIgnore } $composerManifest = \json_decode($composerManifest, true, 512, 0); if ($composerManifest === false || !is_array($composerManifest)) { - throw new \RuntimeException(sprintf($composerManifestError, 'decoded')); + throw new RuntimeException(sprintf($composerManifestError, 'decoded')); } if ( diff --git a/src/CsFixerConfig.php b/src/CsFixerConfig.php index 85f4080..7abce88 100644 --- a/src/CsFixerConfig.php +++ b/src/CsFixerConfig.php @@ -24,17 +24,17 @@ class CsFixerConfig extends Config implements CsFixerConfigInterface * @var string */ protected static $defaultHeader = <<|bool> diff --git a/src/Setup.php b/src/Setup.php index 08af348..10e57d9 100644 --- a/src/Setup.php +++ b/src/Setup.php @@ -16,6 +16,7 @@ namespace TYPO3\CodingStandards; +use RuntimeException; use Symfony\Component\Console\Input\ArrayInput; use Symfony\Component\Console\Output\NullOutput; use Symfony\Component\Console\Style\StyleInterface; @@ -59,6 +60,9 @@ final class Setup private readonly StyleInterface $style; + /** + * @throws RuntimeException + */ public function __construct(string $targetDir, StyleInterface $style = null) { if ($targetDir === '') { @@ -66,7 +70,7 @@ public function __construct(string $targetDir, StyleInterface $style = null) } if (!\is_dir($targetDir)) { - throw new \RuntimeException(sprintf("Target directory '%s' does not exist.", $targetDir)); + throw new RuntimeException(sprintf("Target directory '%s' does not exist.", $targetDir)); } // Normalize separators on Windows @@ -109,10 +113,13 @@ public function forExtension(bool $force): int return $result ? 0 : 1; } + /** + * @throws RuntimeException + */ public function copyPhpCsFixerConfig(bool $force, string $type): bool { if (!in_array($type, self::VALID_TYPES, true)) { - throw new \RuntimeException(sprintf('Invalid type (%s) specified.', $type)); + throw new RuntimeException(sprintf('Invalid type (%s) specified.', $type)); } $targetFile = '.php-cs-fixer.dist.php'; diff --git a/tests/Console/Style/SimpleStyle.php b/tests/Console/Style/SimpleStyle.php index 85f2816..e2d393a 100644 --- a/tests/Console/Style/SimpleStyle.php +++ b/tests/Console/Style/SimpleStyle.php @@ -1,5 +1,7 @@ writeln([ sprintf('%s', OutputFormatter::escapeTrailingBackslash($message)), @@ -88,7 +90,7 @@ public function title($message) /** * @inheritDoc */ - public function section($message) + public function section($message): void { $this->writeln([ sprintf('%s', OutputFormatter::escapeTrailingBackslash($message)), @@ -98,11 +100,9 @@ public function section($message) /** * @inheritDoc */ - public function listing(array $elements) + public function listing(array $elements): void { - $elements = array_map(function ($element) { - return sprintf(' * %s', $element); - }, $elements); + $elements = array_map(fn ($element) => sprintf(' * %s', $element), $elements); $this->writeln($elements); } @@ -110,7 +110,7 @@ public function listing(array $elements) /** * @inheritDoc */ - public function text($message) + public function text($message): void { $messages = \is_array($message) ? array_values($message) : [$message]; foreach ($messages as $message) { @@ -121,9 +121,9 @@ public function text($message) /** * Formats a command comment. * - * @param string|array $message + * @param array|string $message */ - public function comment($message) + public function comment($message): void { $this->block($message, null, null, ' // ', false, false); } @@ -131,7 +131,7 @@ public function comment($message) /** * @inheritDoc */ - public function success($message) + public function success($message): void { $this->block($message, 'OK', 'fg=black;bg=green', ' ', true); } @@ -139,7 +139,7 @@ public function success($message) /** * @inheritDoc */ - public function error($message) + public function error($message): void { $this->block($message, 'ERROR', 'fg=white;bg=red', ' ', true); } @@ -147,7 +147,7 @@ public function error($message) /** * @inheritDoc */ - public function warning($message) + public function warning($message): void { $this->block($message, 'WARNING', 'fg=black;bg=yellow', ' ', true); } @@ -155,7 +155,7 @@ public function warning($message) /** * @inheritDoc */ - public function note($message) + public function note($message): void { $this->block($message, 'NOTE', 'fg=yellow', ' ! '); } @@ -163,7 +163,7 @@ public function note($message) /** * @inheritDoc */ - public function caution($message) + public function caution($message): void { $this->block($message, 'CAUTION', 'fg=white;bg=red', ' ! ', true); } @@ -171,7 +171,7 @@ public function caution($message) /** * @inheritDoc */ - public function table(array $headers, array $rows) + public function table(array $headers, array $rows): void { $style = clone Table::getStyleDefinition('symfony-style-guide'); $style->setCellHeaderFormat('%s'); @@ -188,7 +188,7 @@ public function table(array $headers, array $rows) /** * Formats a horizontal table. */ - public function horizontalTable(array $headers, array $rows) + public function horizontalTable(array $headers, array $rows): void { $style = clone Table::getStyleDefinition('symfony-style-guide'); $style->setCellHeaderFormat('%s'); @@ -211,9 +211,9 @@ public function horizontalTable(array $headers, array $rows) * * ['key' => 'value'] * * new TableSeparator() * - * @param string|array|TableSeparator ...$list + * @param array|string|TableSeparator ...$list */ - public function definitionList(...$list) + public function definitionList(...$list): void { $style = clone Table::getStyleDefinition('symfony-style-guide'); $style->setCellHeaderFormat('%s'); @@ -296,7 +296,7 @@ public function choice($question, array $choices, $default = null) /** * @inheritDoc */ - public function progressStart($max = 0) + public function progressStart($max = 0): void { $this->progressBar = $this->createProgressBar($max); $this->progressBar->start(); @@ -305,7 +305,7 @@ public function progressStart($max = 0) /** * @inheritDoc */ - public function progressAdvance($step = 1) + public function progressAdvance($step = 1): void { $this->getProgressBar()->advance($step); } @@ -313,7 +313,7 @@ public function progressAdvance($step = 1) /** * @inheritDoc */ - public function progressFinish() + public function progressFinish(): void { $this->getProgressBar()->finish(); $this->newLine(2); @@ -362,7 +362,7 @@ public function askQuestion(Question $question) /** * @inheritDoc */ - public function writeln($messages, $type = self::OUTPUT_NORMAL) + public function writeln($messages, $type = self::OUTPUT_NORMAL): void { if (!is_iterable($messages)) { $messages = [$messages]; @@ -377,7 +377,7 @@ public function writeln($messages, $type = self::OUTPUT_NORMAL) /** * @inheritDoc */ - public function write($messages, $newline = false, $type = self::OUTPUT_NORMAL) + public function write($messages, $newline = false, $type = self::OUTPUT_NORMAL): void { if (!is_iterable($messages)) { $messages = [$messages]; @@ -392,7 +392,7 @@ public function write($messages, $newline = false, $type = self::OUTPUT_NORMAL) /** * @inheritDoc */ - public function newLine($count = 1) + public function newLine($count = 1): void { parent::newLine($count); $this->bufferedOutput->write(str_repeat("\n", $count)); diff --git a/tests/Unit/Console/ApplicationTest.php b/tests/Unit/Console/ApplicationTest.php index 05acd82..68b2eee 100644 --- a/tests/Unit/Console/ApplicationTest.php +++ b/tests/Unit/Console/ApplicationTest.php @@ -16,6 +16,7 @@ namespace TYPO3\CodingStandards\Tests\Unit\Console; +use RuntimeException; use Symfony\Component\Console\Input\ArrayInput; use Symfony\Component\Console\Tester\ApplicationTester; use TYPO3\CodingStandards\Console\Application; @@ -60,7 +61,7 @@ public function testGetTargetDir(): void public function testGetTargetDirThrowsOnInvalidPath(): void { - self::expectException(\RuntimeException::class); + self::expectException(RuntimeException::class); self::expectExceptionMessageMatches('#Invalid target directory specified, /.*/invalid-target does not exist.#'); self::getTestPath(); diff --git a/tests/Unit/Console/Command/AbstractSetupCommandTest.php b/tests/Unit/Console/Command/AbstractSetupCommandTest.php index bec9f95..252525f 100644 --- a/tests/Unit/Console/Command/AbstractSetupCommandTest.php +++ b/tests/Unit/Console/Command/AbstractSetupCommandTest.php @@ -16,6 +16,7 @@ namespace TYPO3\CodingStandards\Tests\Unit\Console\Command; +use RuntimeException; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\ArrayInput; use TYPO3\CodingStandards\Console\Command\AbstractSetupCommand; @@ -50,7 +51,7 @@ public function testThrowsOnInvalidPath(): void $commandTester = $this->getCommandTester(''); - self::expectException(\RuntimeException::class); + self::expectException(RuntimeException::class); self::expectExceptionMessageMatches('#.+(invalid-path).+#'); $commandTester->execute($this->getInput($testPath . '/invalid-path')); diff --git a/tests/Unit/Console/Command/AbstractSetupCommandTestImplementation.php b/tests/Unit/Console/Command/AbstractSetupCommandTestImplementation.php index 7026f85..5a1398c 100644 --- a/tests/Unit/Console/Command/AbstractSetupCommandTestImplementation.php +++ b/tests/Unit/Console/Command/AbstractSetupCommandTestImplementation.php @@ -25,13 +25,6 @@ */ final class AbstractSetupCommandTestImplementation extends AbstractSetupCommand { - //protected static $defaultName = 'setup:editor-config'; - - /** - * @ var string - */ - //protected static $defaultDescription = 'Setting up the TYPO3 editorconfig ruleset'; - protected function executeSetup(InputInterface $input, OutputInterface $output): int { //throw new \LogicException('Call to executeSetup()', 1637417318); diff --git a/tests/Unit/Console/Command/SetupCommandTest.php b/tests/Unit/Console/Command/SetupCommandTest.php index 8274ae8..062ba7b 100644 --- a/tests/Unit/Console/Command/SetupCommandTest.php +++ b/tests/Unit/Console/Command/SetupCommandTest.php @@ -16,6 +16,8 @@ namespace TYPO3\CodingStandards\Tests\Unit\Console\Command; +use Generator; +use RuntimeException; use TYPO3\CodingStandards\Console\Command\SetupCommand; use TYPO3\CodingStandards\Setup; @@ -29,9 +31,9 @@ public function testTypeArgument(string $type): void } /** - * @return \Generator> + * @return Generator> */ - public static function typeDataProvider(): \Generator + public static function typeDataProvider(): Generator { foreach (Setup::VALID_TYPES as $type) { yield $type => [ @@ -46,7 +48,7 @@ public function testMissingTypeThrows(): void $commandTester = $this->getCommandTester('setup'); - self::expectException(\RuntimeException::class); + self::expectException(RuntimeException::class); self::expectExceptionMessageMatches('#.+(type).+#'); $commandTester->execute($this->getInput($testPath)); @@ -60,16 +62,16 @@ public function testInvalidComposerManifestThrows(): void $commandTester = $this->getCommandTester('setup'); - self::expectException(\RuntimeException::class); + self::expectException(RuntimeException::class); self::expectExceptionMessageMatches('#.+(type).+#'); $commandTester->execute($this->getInput($testPath)); } /** - * @param array $existingFiles + * @param array $existingFiles * @param array|string> $input - * @param array $expectedFiles + * @param array $expectedFiles */ #[\PHPUnit\Framework\Attributes\DataProvider('setupDataProvider')] public function testSetup( @@ -102,9 +104,16 @@ public function testSetup( } /** - * @return \Generator, targetDir: string, force: bool, input: array|string>, expectedOutput: string, expectedFiles: array}> + * @return Generator, + * targetDir: string, + * force: bool, + * input: array|string>, + * expectedOutput: string, + * expectedFiles: array + * }> */ - public static function setupDataProvider(): \Generator + public static function setupDataProvider(): Generator { yield 'auto-detect extension from type' => [ 'existingFiles' => [ diff --git a/tests/Unit/Console/Command/SetupCommandTestCase.php b/tests/Unit/Console/Command/SetupCommandTestCase.php index b0fc82f..0365acb 100644 --- a/tests/Unit/Console/Command/SetupCommandTestCase.php +++ b/tests/Unit/Console/Command/SetupCommandTestCase.php @@ -19,8 +19,9 @@ class SetupCommandTestCase extends CommandTestCase { /** - * @param array $input - * @return array + * @param array $input + * + * @return array */ protected function getInput(string $testPath, bool $force = false, array $input = []): array { @@ -32,7 +33,7 @@ protected function getInput(string $testPath, bool $force = false, array $input } /** - * @param array $input + * @param array $input */ protected function assertExecuteScenario(string $testPath, string $commandName, array $input = []): void { diff --git a/tests/Unit/Console/Command/UpdateCommandTestCase.php b/tests/Unit/Console/Command/UpdateCommandTestCase.php index 3ca1354..111fb0f 100644 --- a/tests/Unit/Console/Command/UpdateCommandTestCase.php +++ b/tests/Unit/Console/Command/UpdateCommandTestCase.php @@ -19,8 +19,9 @@ class UpdateCommandTestCase extends CommandTestCase { /** - * @param array $input - * @return array + * @param array $input + * + * @return array */ protected function getInput(string $testPath, array $input = []): array { @@ -31,7 +32,7 @@ protected function getInput(string $testPath, array $input = []): array } /** - * @param array $input + * @param array $input */ protected function assertExecuteScenario(string $testPath, string $commandName, array $input = []): void { diff --git a/tests/Unit/SetupTest.php b/tests/Unit/SetupTest.php index 6a63fb1..17f8d3d 100644 --- a/tests/Unit/SetupTest.php +++ b/tests/Unit/SetupTest.php @@ -16,6 +16,8 @@ namespace TYPO3\CodingStandards\Tests\Unit; +use Generator; +use RuntimeException; use Symfony\Component\Console\Input\ArrayInput; use Symfony\Component\Console\Output\BufferedOutput; use TYPO3\CodingStandards\Setup; @@ -74,8 +76,8 @@ private function calculateOutput(array $expectedOutput, string $type): string } /** - * @param array $existingFiles - * @param array $expectedOutput + * @param array $existingFiles + * @param array $expectedOutput * @param array $expectedFiles */ private function assertScenario( @@ -119,8 +121,8 @@ private function assertScenario( } /** - * @param array $existingFiles - * @param array $expectedOutput + * @param array $existingFiles + * @param array $expectedOutput * @param array $expectedFiles */ #[\PHPUnit\Framework\Attributes\DataProvider('scenariosProvider')] @@ -135,8 +137,8 @@ public function testForProjectScenarios( } /** - * @param array $existingFiles - * @param array $expectedOutput + * @param array $existingFiles + * @param array $expectedOutput * @param array $expectedFiles */ #[\PHPUnit\Framework\Attributes\DataProvider('scenariosProvider')] @@ -151,7 +153,7 @@ public function testForExtensionScenarios( } /** - * @return \Generator, * force: bool, * expectedResult: int, @@ -159,7 +161,7 @@ public function testForExtensionScenarios( * expectedFiles: array * }> */ - public static function scenariosProvider(): \Generator + public static function scenariosProvider(): Generator { yield 'all files are created' => [ 'existingFiles' => [], @@ -337,9 +339,9 @@ public function testCopyPhpCsFixerConfig(string $type): void } /** - * @return \Generator> + * @return Generator> */ - public static function typeDataProvider(): \Generator + public static function typeDataProvider(): Generator { foreach (Setup::VALID_TYPES as $type) { yield $type => [ @@ -352,7 +354,7 @@ public function testInvalidPathThrows(): void { $testPath = self::getTestPath() . '/invalid-path'; - self::expectException(\RuntimeException::class); + self::expectException(RuntimeException::class); self::expectExceptionMessageMatches('#.+(invalid-path).+#'); new Setup($testPath); @@ -375,7 +377,7 @@ public function testIoIsCreated(): void public function testInvalidTypeThrows(): void { - self::expectException(\RuntimeException::class); + self::expectException(RuntimeException::class); self::expectExceptionMessageMatches('#.+(type).+#'); $setup = new Setup(self::getTestPath()); diff --git a/tests/Unit/Smoke/InstallViaComposerTest.php b/tests/Unit/Smoke/InstallViaComposerTest.php index 374ebd5..c39f1ac 100644 --- a/tests/Unit/Smoke/InstallViaComposerTest.php +++ b/tests/Unit/Smoke/InstallViaComposerTest.php @@ -17,6 +17,7 @@ namespace TYPO3\CodingStandards\Tests\Unit\Smoke; use Keradus\CliExecutor\CommandExecutor; +use RuntimeException; use TYPO3\CodingStandards\Console\Application; use TYPO3\CodingStandards\Tests\Unit\TestCase; @@ -53,19 +54,19 @@ public static function setUpBeforeClass(): void try { CommandExecutor::create('php --version', __DIR__)->getResult(); - } catch (\RuntimeException $runtimeException) { + } catch (RuntimeException $runtimeException) { self::markTestIncomplete('Missing `php` env script. Details:' . "\n" . $runtimeException->getMessage()); } try { CommandExecutor::create('composer --version', __DIR__)->getResult(); - } catch (\RuntimeException $runtimeException) { + } catch (RuntimeException $runtimeException) { self::markTestIncomplete('Missing `composer` env script. Details:' . "\n" . $runtimeException->getMessage()); } try { CommandExecutor::create('composer check', self::getRootPath())->getResult(); - } catch (\RuntimeException $runtimeException) { + } catch (RuntimeException $runtimeException) { if (\getenv('EXPERIMENTAL') !== 'true') { self::markTestIncomplete('Composer check failed. Details:' . "\n" . $runtimeException->getMessage()); } diff --git a/tests/Unit/TestCase.php b/tests/Unit/TestCase.php index 753aad8..4ee2b7d 100644 --- a/tests/Unit/TestCase.php +++ b/tests/Unit/TestCase.php @@ -17,6 +17,7 @@ namespace TYPO3\CodingStandards\Tests\Unit; use PHPUnit\Framework\TestCase as BaseTestCase; +use RuntimeException; use Symfony\Component\Filesystem\Filesystem; abstract class TestCase extends BaseTestCase @@ -75,7 +76,7 @@ protected static function getFilename(string $filename, ?array $replacePairs = n return match ($prefix) { 'TPL' => self::getTemplateFilename($filename), 'FIX' => self::getFixtureFilename($filename), - default => throw new \RuntimeException(sprintf('Invalid prefix (%s).', $prefix), 1_636_451_407), + default => throw new RuntimeException(sprintf('Invalid prefix (%s).', $prefix), 1_636_451_407), }; }