From afa127444e3dcb1f851a40408ce8df9add98a0a0 Mon Sep 17 00:00:00 2001 From: Martin Guth Date: Fri, 5 Apr 2024 18:06:48 +0200 Subject: [PATCH 1/2] Upgrade everything to its newest version, use PSR-12 --- .github/workflows/tests.yaml | 6 +- CHANGELOG.md | 8 + README.md | 90 ++- UPGRADE-4.0.md | 58 ++ composer.json | 18 +- ecs-7.4.php | 17 - ecs-8.0.php | 93 --- ecs-8.1.php | 15 +- ecs-8.2.php | 6 + ecs-8.3.php | 6 + ecs.php | 765 +++++++++--------- src/Fixer/SpecifyArgSeparatorFixer.php | 6 +- src/Helper/Naming.php | 6 +- src/Helper/SniffClassWrapper.php | 25 +- src/Sniffs/Naming/AbstractClassNameSniff.php | 22 +- .../Naming/ClassNameSuffixByParentSniff.php | 15 +- src/Sniffs/Naming/InterfaceNameSniff.php | 21 +- src/Sniffs/Naming/TraitNameSniff.php | 21 +- tests/Fixer/SpecifyArgSeparatorFixerTest.php | 2 +- 19 files changed, 562 insertions(+), 638 deletions(-) create mode 100644 UPGRADE-4.0.md delete mode 100644 ecs-7.4.php delete mode 100644 ecs-8.0.php create mode 100644 ecs-8.2.php create mode 100644 ecs-8.3.php diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index b371943..0d2d5eb 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -15,10 +15,10 @@ jobs: strategy: matrix: - php-version: ['7.3', '7.4', '8.0', '8.1'] + php-version: ['8.0', '8.1', '8.2', '8.3'] dependencies: [''] include: - - { php-version: '7.3', dependencies: '--prefer-lowest --prefer-stable' } + - { php-version: '8.0', dependencies: '--prefer-lowest --prefer-stable' } name: PHP ${{ matrix.php-version }} ${{ matrix.dependencies }} @@ -55,7 +55,7 @@ jobs: - name: Setup PHP uses: shivammathur/setup-php@v2 with: - php-version: '8.1' + php-version: '8.3' extensions: mbstring, intl tools: composer:v2 diff --git a/CHANGELOG.md b/CHANGELOG.md index 54aefb6..1464251 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,14 @@ ## Unreleased +- Require PHP ^8.0 +- Update to slevomat/coding-standard ^8.0 +- Update to squizlabs/php_codesniffer ^3.9 +- Update to symplify/easy-coding-standard ^12.1 +- Move coding standard declarations from `ecs-7.4.php` and `ecs-8.0.php` to `ecs.php` and remove the former files +- Change deprecated rules to new ones +- Add new `ecs-8.2.php` coding standard declaration file for PHP 8.2+ +- Add new `ecs-8.3.php` coding standard declaration file for PHP 8.3+ ## 3.3.1 - 2022-05-23 - Lock `symplify/easy-coding-standard` to <10.2.4 because of backward incompatibilities introduced in its bugfix releases. diff --git a/README.md b/README.md index 2942880..e44e6b7 100644 --- a/README.md +++ b/README.md @@ -4,8 +4,8 @@ PHP coding standard used in [LMC](https://www.lmc.eu/en/) projects. -Standard is based on [PSR-2](https://www.php-fig.org/psr/psr-2/) and adds various checks to make sure the code is readable, -does follow the same conventions and does not contain common mistakes. +Standard is based on [PSR-12](https://www.php-fig.org/psr/psr-12/) and adds +various checks to make sure the code is readable, does follow the same conventions and does not contain common mistakes. We use [EasyCodingStandard] to define and execute checks created for both [PHP-CS-Fixer] and [PHP_CodeSniffer]. @@ -22,18 +22,27 @@ composer require --dev lmc/coding-standard ```php import(__DIR__ . '/vendor/lmc/coding-standard/ecs.php'); - - // Be default only checks compatible with PHP 7.3 are enabled. - // Depending on the lowest PHP version your project need to support, you can enable additional checks for PHP 7.4, 8.0 or 8.1. - - - // Import one of ecs-7.4.php, ecs-8.0.php or ecs-8.1.php. Use only one file (for the highest possible PHP version). - //$containerConfigurator->import(__DIR__ . '/vendor/lmc/coding-standard/ecs-7.4.php'); -}; +return ECSConfig::configure() + ->withSets( + [ + __DIR__ . '/vendor/lmc/coding-standard/ecs.php', + ] + ); + + // Be default only checks compatible with PHP 8.0 are enabled. + // Depending on the lowest PHP version your project need to support, you can enable additional checks for + // PHP 8.1, 8.2 and 8.3. + + + // Import one of ecs-8.1.php, ecs-8.2.php or ecs-8.3.php. Use only one file (for the highest possible PHP version). + //->withSets( + // [ + // __DIR__ . '/vendor/lmc/coding-standard/ecs.php', + // __DIR__ . '/vendor/lmc/coding-standard/ecs-8.3.php', + // ] + //); ``` 2. Run the check command (for `src/` and `tests/` directories): @@ -71,21 +80,18 @@ Be aware you must add these settings **after** import of the base LMC code-style use PHP_CodeSniffer\Standards\Generic\Sniffs\Files\LineLengthSniff; use PhpCsFixer\Fixer\PhpUnit\PhpUnitTestAnnotationFixer; -use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator; - -return static function (ContainerConfigurator $containerConfigurator): void { - $containerConfigurator->import(__DIR__ . '/vendor/lmc/coding-standard/ecs.php'); - - $services = $containerConfigurator->services(); +use Symplify\EasyCodingStandard\Config\ECSConfig; +return ECSConfig::configure() + ->withSets( + [ + __DIR__ . '/vendor/lmc/coding-standard/ecs.php', + ] + ) // Enforce line-length to 120 characters - $services->set(LineLengthSniff::class) - ->property('absoluteLineLimit', 120); - + ->withConfiguredRule(LineLengthSniff::class, ['absoluteLineLimit' => 120]) // Tests must have @test annotation - $services->set(PhpUnitTestAnnotationFixer::class) - ->call('configure', [['style' => 'annotation']]); -}; + ->withConfiguredRule(PhpUnitTestAnnotationFixer::class, ['style' => 'annotation']); ``` See [EasyCodingStandard docs](https://github.com/symplify/easy-coding-standard#configuration) for more configuration options. @@ -102,28 +108,24 @@ Unlike adding/modifying checks, skips must be added **before** import of the bas use PHP_CodeSniffer\Standards\Generic\Sniffs\PHP\ForbiddenFunctionsSniff; use PHP_CodeSniffer\Standards\Squiz\Sniffs\Arrays\ArrayDeclarationSniff; -use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator; -use Symplify\EasyCodingStandard\ValueObject\Option; - -return static function (ContainerConfigurator $containerConfigurator): void { - $parameters = $containerConfigurator->parameters(); - - $parameters->set( - Option::SKIP, +use Symplify\EasyCodingStandard\Config\ECSConfig; + +return ECSConfig::configure() + ->withSkip([ + // Ignore specific check only in specific files + ForbiddenFunctionsSniff::class => [__DIR__ . '/src-tests/bootstrap.php'], + // Disable check entirely + ArrayDeclarationSniff::class, + // Skip one file + __DIR__ . '/file/to/be/skipped.php', + // Skip entire directory + __DIR__ . '/ignored/directory/*', + ]) + ->withSets( [ - // Ignore specific check only in specific files - ForbiddenFunctionsSniff::class => [__DIR__ . '/src-tests/bootstrap.php'], - // Disable check entirely - ArrayDeclarationSniff::class, - // Skip one file - __DIR__ . '/file/to/be/skipped.php', - // Skip entire directory - __DIR__ . '/ignored/directory/*', + __DIR__ . '/vendor/lmc/coding-standard/ecs.php', ] ); - - $containerConfigurator->import(__DIR__ . '/vendor/lmc/coding-standard/ecs.php'); -}; ``` See [EasyCodingStandard docs](https://github.com/symplify/easy-coding-standard#configuration) for more configuration options. diff --git a/UPGRADE-4.0.md b/UPGRADE-4.0.md new file mode 100644 index 0000000..731b381 --- /dev/null +++ b/UPGRADE-4.0.md @@ -0,0 +1,58 @@ +# Upgrading from 3.x to 4.0 + +### 1. Update dependency in composer.json +In require-dev section change the version constraint: + +```diff +- "lmc/coding-standard": "^3.3", ++ "lmc/coding-standard": "^4.0", +``` + +Then run `composer update`. + +### 2. Configuration updates + +Configuration now uses ECSConfig class instead of ContainerConfigurator. Update your `ecs.php` to use the new configuration style: + +```diff +-use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator; +- +-return static function (ContainerConfigurator $containerConfigurator): void { ++use Symplify\EasyCodingStandard\Config\ECSConfig; ++ ++return ECSConfig::configure() +``` + +Rules are now set using `ECSConfig::configure()->withRules([])` or `ECSConfig::configure()->withConfiguredRule()` instead of `$services->set()`. +Skiping tests is now done using `ECSConfig::configure()->withSkip()` instead of `$parameters->set(Option::SKIP, ...)`. +Imports are now done using `ECSConfig::configure()->withSets()` instead of `$containerConfigurator->import()`. + +See [ECS documentation](https://github.com/easy-coding-standard/easy-coding-standard/tree/main?tab=readme-ov-file#configure) for more configuration options +Examples of configurations can be seen [here](https://tomasvotruba.com/blog/new-in-ecs-simpler-config) + +### 3. Remove imports of `ecs-7.4.php` and/or `ecs-8.0.php` from your `ecs.php` +```diff + ->withSets(__DIR__ . '/vendor/lmc/coding-standard/ecs.php') +- ->withSets(__DIR__ . '/vendor/lmc/coding-standard/ecs-7.4.php') +- ->withSets(__DIR__ . '/vendor/lmc/coding-standard/ecs-8.0.php') + ->withSets(__DIR__ . '/vendor/lmc/coding-standard/ecs-8.1.php') +``` + +### 4. Sanity check +Besides running your code style checks, you can ensure all predefined LMC checks are loaded as well, by running: + +```sh +vendor/bin/ecs list-checkers +``` + +The result should end with something like: +``` + 41 checkers from PHP_CodeSniffer: + ... + 147 checkers from PHP-CS-Fixer: + ... + 2 checkers are skipped: + ... +``` + +(or some close number, depending on your custom code-style settings). diff --git a/composer.json b/composer.json index e1eae0c..5cac995 100644 --- a/composer.json +++ b/composer.json @@ -10,12 +10,12 @@ } ], "require": { - "php": "^7.3 || ^8.0", + "php": "^8.0", "friendsofphp/php-cs-fixer": "^3.0", "nette/utils": "^3.2", - "slevomat/coding-standard": "^6.4.1 || ^7.0", - "squizlabs/php_codesniffer": "^3.6", - "symplify/easy-coding-standard": "^10.0 <10.2.4" + "slevomat/coding-standard": "^8.0", + "squizlabs/php_codesniffer": "^3.9", + "symplify/easy-coding-standard": "^12.1.4" }, "require-dev": { "ergebnis/composer-normalize": "^2.13.2", @@ -24,7 +24,7 @@ "phpstan/extension-installer": "^1.1", "phpstan/phpstan": "^1.3.0", "phpstan/phpstan-phpunit": "^1.0.0", - "phpunit/phpunit": "^9.5.2" + "phpunit/phpunit": "^9.6.19" }, "prefer-stable": true, "autoload": { @@ -55,16 +55,16 @@ "@test" ], "analyze": [ - "vendor/bin/ecs check src/ tests/ ecs.php ecs-7.4.php ecs-8.0.php ecs-8.1.php --ansi", - "vendor/bin/ecs check-markdown README.md --ansi", + "vendor/bin/ecs check src/ tests/ ecs.php ecs-8.1.php ecs-8.2.php ecs-8.3.php --ansi", + "vendor/bin/ecs check README.md --ansi", "vendor/bin/phpstan analyze -c phpstan.neon --ansi" ], "fix": [ "@composer normalize", - "vendor/bin/ecs check ./src/ ./tests/ ecs.php ecs-7.4.php ecs-8.0.php ecs-8.1.php --ansi --fix" + "vendor/bin/ecs check ./src/ ./tests/ ecs.php ecs-8.1.php ecs-8.2.php ecs-8.3.php --ansi --fix" ], "lint": [ - "vendor/bin/parallel-lint -j 10 -e php ./src ./tests ecs.php ecs-7.4.php ecs-8.0.php ecs-8.1.php", + "vendor/bin/parallel-lint -j 10 -e php ./src ./tests ecs.php ecs-8.1.php ecs-8.2.php ecs-8.3.php", "@composer validate", "@composer normalize --dry-run" ], diff --git a/ecs-7.4.php b/ecs-7.4.php deleted file mode 100644 index 030c016..0000000 --- a/ecs-7.4.php +++ /dev/null @@ -1,17 +0,0 @@ -services(); - - // Takes `@var` annotation of non-mixed types and adjusts accordingly the property signature. - $services->set(PhpdocToPropertyTypeFixer::class); - // Takes `@param` annotations of non-mixed types and adjusts accordingly the function signature. - $services->set(PhpdocToParamTypeFixer::class); - // Takes `@return` annotation of non-mixed types and adjusts accordingly the function signature. - $services->set(PhpdocToReturnTypeFixer::class); -}; diff --git a/ecs-8.0.php b/ecs-8.0.php deleted file mode 100644 index 1bde654..0000000 --- a/ecs-8.0.php +++ /dev/null @@ -1,93 +0,0 @@ -services(); - - (function () use ($services): void { - // Promote constructor properties - // @see https://github.com/FriendsOfPHP/PHP-CS-Fixer/issues/5956 - $services->set(RequireConstructorPropertyPromotionSniff::class); - - // switch -> match - // @see https://github.com/FriendsOfPHP/PHP-CS-Fixer/issues/5894 - - // Require \Stringable interface in classes implementing __toString() method - // > it may probably be a phpstan rule, more than cs rule - since it needs a class hierarchy to solve this - // @see https://github.com/FriendsOfPHP/PHP-CS-Fixer/issues/6235 - - // Takes `@var` annotation and adjusts accordingly the property signature. - $services->set(PhpdocToPropertyTypeFixer::class); - $services->set(PropertyTypeHintSniff::class); - - // Takes `@param` annotations and adjusts accordingly the function signature. - $services->set(PhpdocToParamTypeFixer::class); - $services->set(ParameterTypeHintSniff::class); - - // Takes `@return` annotation types and adjusts accordingly the function signature. - $services->set(PhpdocToReturnTypeFixer::class); - $services->set(ReturnTypeHintSniff::class); - - // Removes `@param` and `@return` tags that don't provide any useful information - $services->set(NoSuperfluousPhpdocTagsFixer::class) - ->call( - 'configure', - [ - [ - 'allow_mixed' => false, // allow `@mixed` annotations to be preserved - 'allow_unused_params' => false, // whether param annotation without actual signature is allowed - 'remove_inheritdoc' => true, // remove @inheritDoc tags - ], - ] - ); - - // php docs annotation -> attributes #[...] - // @see https://www.php.net/releases/8.0/en.php#attributes - - // Format union types - $services->set(UnionTypeHintFormatSniff::class) - ->property('withSpaces', 'no'); - - // Multi-line arguments list in function/method declaration must have a trailing comma - $services->set(RequireTrailingCommaInDeclarationSniff::class); - // Multi-line arguments list in function/method call must have a trailing comma - $services->set(RequireTrailingCommaInCallSniff::class); - - // Use `null-safe` operator `?->` where possible - $services->set(RequireNullSafeObjectOperatorSniff::class); - })(); - - $parameters = $containerConfigurator->parameters(); - (function () use ($parameters): void { - $parameters->set( - Option::SKIP, - [ - // Skip unwanted rules from PropertyTypeHintSniff - PropertyTypeHintSniff::class . '.' . PropertyTypeHintSniff::CODE_MISSING_TRAVERSABLE_TYPE_HINT_SPECIFICATION => null, - PropertyTypeHintSniff::class . '.' . PropertyTypeHintSniff::CODE_MISSING_ANY_TYPE_HINT => null, - - // Skip unwanted rules from ParameterTypeHintSniff - ParameterTypeHintSniff::class . '.' . ParameterTypeHintSniff::CODE_MISSING_TRAVERSABLE_TYPE_HINT_SPECIFICATION => null, - ParameterTypeHintSniff::class . '.' . ParameterTypeHintSniff::CODE_MISSING_ANY_TYPE_HINT => null, - - // Skip unwanted rules from ReturnTypeHintSniff - ReturnTypeHintSniff::class . '.' . ReturnTypeHintSniff::CODE_MISSING_TRAVERSABLE_TYPE_HINT_SPECIFICATION => null, - ReturnTypeHintSniff::class . '.' . ReturnTypeHintSniff::CODE_MISSING_ANY_TYPE_HINT => null, - ] - ); - })(); -}; diff --git a/ecs-8.1.php b/ecs-8.1.php index 0cac279..f5adedb 100644 --- a/ecs-8.1.php +++ b/ecs-8.1.php @@ -1,16 +1,5 @@ import(__DIR__ . '/ecs-8.0.php'); - - // class with constants only -> enum - // @see https://www.php.net/releases/8.1/en.php#enumerations - - // readonly properties - // @see https://www.php.net/releases/8.1/en.php#readonly_properties - - // first-class callable - // @see https://www.php.net/releases/8.1/en.php#first_class_callable_syntax -}; +return ECSConfig::configure(); diff --git a/ecs-8.2.php b/ecs-8.2.php new file mode 100644 index 0000000..a8115aa --- /dev/null +++ b/ecs-8.2.php @@ -0,0 +1,6 @@ +withSets([__DIR__ . '/ecs-8.1.php']); diff --git a/ecs-8.3.php b/ecs-8.3.php new file mode 100644 index 0000000..3c0ad94 --- /dev/null +++ b/ecs-8.3.php @@ -0,0 +1,6 @@ +withSets([__DIR__ . '/ecs-8.2.php']); diff --git a/ecs.php b/ecs.php index 3659a5b..9c8fb3c 100644 --- a/ecs.php +++ b/ecs.php @@ -31,6 +31,7 @@ use PHP_CodeSniffer\Standards\Squiz\Sniffs\WhiteSpace\LanguageConstructSpacingSniff; use PHP_CodeSniffer\Standards\Squiz\Sniffs\WhiteSpace\LogicalOperatorSpacingSniff; use PHP_CodeSniffer\Standards\Squiz\Sniffs\WhiteSpace\OperatorSpacingSniff; +use PHP_CodeSniffer\Standards\Squiz\Sniffs\WhiteSpace\ScopeClosingBraceSniff; use PHP_CodeSniffer\Standards\Squiz\Sniffs\WhiteSpace\ScopeKeywordSpacingSniff; use PHP_CodeSniffer\Standards\Squiz\Sniffs\WhiteSpace\SemicolonSpacingSniff; use PhpCsFixer\Fixer\Alias\ArrayPushFixer; @@ -40,14 +41,14 @@ use PhpCsFixer\Fixer\Alias\SetTypeToCastFixer; use PhpCsFixer\Fixer\ArrayNotation\ArraySyntaxFixer; use PhpCsFixer\Fixer\ArrayNotation\NormalizeIndexBraceFixer; -use PhpCsFixer\Fixer\ArrayNotation\NoTrailingCommaInSinglelineArrayFixer; use PhpCsFixer\Fixer\ArrayNotation\TrimArraySpacesFixer; use PhpCsFixer\Fixer\ArrayNotation\WhitespaceAfterCommaInArrayFixer; use PhpCsFixer\Fixer\Basic\BracesFixer; +use PhpCsFixer\Fixer\Basic\NoTrailingCommaInSinglelineFixer; use PhpCsFixer\Fixer\Basic\PsrAutoloadingFixer; use PhpCsFixer\Fixer\Casing\MagicMethodCasingFixer; use PhpCsFixer\Fixer\Casing\NativeFunctionCasingFixer; -use PhpCsFixer\Fixer\Casing\NativeFunctionTypeDeclarationCasingFixer; +use PhpCsFixer\Fixer\Casing\NativeTypeDeclarationCasingFixer; use PhpCsFixer\Fixer\CastNotation\CastSpacesFixer; use PhpCsFixer\Fixer\CastNotation\LowercaseCastFixer; use PhpCsFixer\Fixer\CastNotation\ShortScalarCastFixer; @@ -64,11 +65,13 @@ use PhpCsFixer\Fixer\FunctionNotation\CombineNestedDirnameFixer; use PhpCsFixer\Fixer\FunctionNotation\FopenFlagOrderFixer; use PhpCsFixer\Fixer\FunctionNotation\FopenFlagsFixer; -use PhpCsFixer\Fixer\FunctionNotation\FunctionTypehintSpaceFixer; use PhpCsFixer\Fixer\FunctionNotation\ImplodeCallFixer; use PhpCsFixer\Fixer\FunctionNotation\LambdaNotUsedImportFixer; use PhpCsFixer\Fixer\FunctionNotation\NoUnreachableDefaultArgumentValueFixer; use PhpCsFixer\Fixer\FunctionNotation\NoUselessSprintfFixer; +use PhpCsFixer\Fixer\FunctionNotation\PhpdocToParamTypeFixer; +use PhpCsFixer\Fixer\FunctionNotation\PhpdocToPropertyTypeFixer; +use PhpCsFixer\Fixer\FunctionNotation\PhpdocToReturnTypeFixer; use PhpCsFixer\Fixer\FunctionNotation\ReturnTypeDeclarationFixer; use PhpCsFixer\Fixer\FunctionNotation\VoidReturnFixer; use PhpCsFixer\Fixer\Import\NoLeadingImportSlashFixer; @@ -76,14 +79,14 @@ use PhpCsFixer\Fixer\Import\OrderedImportsFixer; use PhpCsFixer\Fixer\LanguageConstruct\DeclareEqualNormalizeFixer; use PhpCsFixer\Fixer\LanguageConstruct\IsNullFixer; -use PhpCsFixer\Fixer\LanguageConstruct\SingleSpaceAfterConstructFixer; +use PhpCsFixer\Fixer\LanguageConstruct\SingleSpaceAroundConstructFixer; use PhpCsFixer\Fixer\ListNotation\ListSyntaxFixer; +use PhpCsFixer\Fixer\NamespaceNotation\BlankLinesBeforeNamespaceFixer; use PhpCsFixer\Fixer\NamespaceNotation\CleanNamespaceFixer; use PhpCsFixer\Fixer\NamespaceNotation\NoLeadingNamespaceWhitespaceFixer; -use PhpCsFixer\Fixer\NamespaceNotation\SingleBlankLineBeforeNamespaceFixer; use PhpCsFixer\Fixer\Operator\BinaryOperatorSpacesFixer; use PhpCsFixer\Fixer\Operator\ConcatSpaceFixer; -use PhpCsFixer\Fixer\Operator\NewWithBracesFixer; +use PhpCsFixer\Fixer\Operator\NewWithParenthesesFixer; use PhpCsFixer\Fixer\Operator\ObjectOperatorWithoutWhitespaceFixer; use PhpCsFixer\Fixer\Operator\StandardizeNotEqualsFixer; use PhpCsFixer\Fixer\Operator\TernaryOperatorSpacesFixer; @@ -106,6 +109,7 @@ use PhpCsFixer\Fixer\Phpdoc\PhpdocTrimFixer; use PhpCsFixer\Fixer\Phpdoc\PhpdocTypesFixer; use PhpCsFixer\Fixer\Phpdoc\PhpdocVarAnnotationCorrectOrderFixer; +use PhpCsFixer\Fixer\PhpTag\BlankLineAfterOpeningTagFixer; use PhpCsFixer\Fixer\PhpTag\FullOpeningTagFixer; use PhpCsFixer\Fixer\PhpUnit\PhpUnitConstructFixer; use PhpCsFixer\Fixer\PhpUnit\PhpUnitDedicateAssertFixer; @@ -124,405 +128,418 @@ use PhpCsFixer\Fixer\Strict\StrictParamFixer; use PhpCsFixer\Fixer\StringNotation\SingleQuoteFixer; use PhpCsFixer\Fixer\Whitespace\BlankLineBeforeStatementFixer; -use PhpCsFixer\Fixer\Whitespace\CompactNullableTypehintFixer; +use PhpCsFixer\Fixer\Whitespace\CompactNullableTypeDeclarationFixer; use PhpCsFixer\Fixer\Whitespace\HeredocIndentationFixer; use PhpCsFixer\Fixer\Whitespace\NoExtraBlankLinesFixer; use PhpCsFixer\Fixer\Whitespace\NoWhitespaceInBlankLineFixer; +use PhpCsFixer\Fixer\Whitespace\TypeDeclarationSpacesFixer; +use SlevomatCodingStandard\Sniffs\Classes\RequireConstructorPropertyPromotionSniff; +use SlevomatCodingStandard\Sniffs\ControlStructures\RequireNullSafeObjectOperatorSniff; use SlevomatCodingStandard\Sniffs\Exceptions\ReferenceThrowableOnlySniff; -use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator; +use SlevomatCodingStandard\Sniffs\Functions\RequireTrailingCommaInCallSniff; +use SlevomatCodingStandard\Sniffs\Functions\RequireTrailingCommaInDeclarationSniff; +use SlevomatCodingStandard\Sniffs\TypeHints\ParameterTypeHintSniff; +use SlevomatCodingStandard\Sniffs\TypeHints\PropertyTypeHintSniff; +use SlevomatCodingStandard\Sniffs\TypeHints\ReturnTypeHintSniff; +use SlevomatCodingStandard\Sniffs\TypeHints\UnionTypeHintFormatSniff; use Symplify\CodingStandard\Fixer\Commenting\ParamReturnAndVarTagMalformsFixer; -use Symplify\EasyCodingStandard\ValueObject\Option; +use Symplify\EasyCodingStandard\Config\ECSConfig; -return static function (ContainerConfigurator $containerConfigurator): void { - $vendorDir = __DIR__ . '/vendor'; // When used directly (during development) - if (!is_dir($vendorDir)) { - $vendorDir = __DIR__ . '/../..'; // When installed as a dependency (in vendor dir) - } +return ECSConfig::configure() + ->withPreparedSets(psr12: true) + ->withRules( + [ + // Function http_build_query() should always have specified `$arg_separator` parameter + SpecifyArgSeparatorFixer::class, + // Abstract class should have prefix "Abstract" + AbstractClassNameSniff::class, + // Classes should have suffix by theirs parent class/interface + ClassNameSuffixByParentSniff::class, + // Interface should have suffix "Interface" + InterfaceNameSniff::class, + // Trait should have suffix "Trait" + TraitNameSniff::class, + // Class and Interface names should be unique in a project, they should never be duplicated + DuplicateClassNameSniff::class, + // Control Structures must have at least one statement inside of the body (empty catch rules is skipped) + EmptyStatementSniff::class, + // For loops that have only a second expression (the condition) should be converted to while loops + ForLoopShouldBeWhileLoopSniff::class, + // Incrementers in nested loops should use different variable names + JumbledIncrementerSniff::class, + // If statements that are always evaluated should not be used + UnconditionalIfStatementSniff::class, + // Methods should not be declared final inside of classes that are declared final + UnnecessaryFinalModifierSniff::class, + // Methods should not be defined that only call the parent method + UselessOverridingMethodSniff::class, + // Doc comment formatting (but some of the rules are skipped) + DocCommentSniff::class, + // There should only be one class defined in a file + OneClassPerFileSniff::class, + // There should only be one interface defined in a file + OneInterfacePerFileSniff::class, + // There should only be one trait defined in a file + OneTraitPerFileSniff::class, + // Exactly one space is allowed after a cast + SpaceAfterCastSniff::class, + // When referencing arrays you should not put whitespace around the opening bracket or before the closing bracket + ArrayBracketSpacingSniff::class, + // Various array declaration rules (but some of the rules are skipped) + ArrayDeclarationSniff::class, + // The self keyword should be used instead of the current class name + SelfMemberReferenceSniff::class, + // The asterisks in a doc comment should align, and there should be one space between the asterisk and tags + DocCommentAlignmentSniff::class, + // Empty catch statements must have comment explaining why the exception is not handled + EmptyCatchCommentSniff::class, + // Tests that the ++ operators are used when possible and not used when it makes the code confusing + IncrementDecrementUsageSniff::class, + // Verifies that class members have scope modifiers + MemberVarScopeSniff::class, + // Detects merge conflict artifacts left in files + GitMergeConflictSniff::class, + // Casts should not have whitespace inside the parentheses + CastSpacingSniff::class, + // The php constructs like echo, return, include, etc. should have one space after them + LanguageConstructSpacingSniff::class, + // Verifies that operators have valid spacing surrounding them + LogicalOperatorSpacingSniff::class, + // The php keywords static, public, private, and protected should have one space after them + ScopeKeywordSpacingSniff::class, + // Semicolons should not have spaces before them + SemicolonSpacingSniff::class, + // Converts simple usages of `array_push($x, $y,` to `$x[] = $y;`. + ArrayPushFixer::class, + // Replace non multibyte-safe functions with corresponding mb function + MbStrFunctionsFixer::class, + // Master functions shall be used instead of aliases + NoAliasFunctionsFixer::class, + // Replaces `rand`, `srand`, `getrandmax` functions calls with their `mt_*` analogs + RandomApiMigrationFixer::class, + // Cast shall be used, not `settype()` + SetTypeToCastFixer::class, + // Array index should always be written by using square braces + NormalizeIndexBraceFixer::class, + // PHP single-line arrays should not have trailing comma + NoTrailingCommaInSinglelineFixer::class, + // Multi-line arrays, arguments list and parameters list must have a trailing comma + TrailingCommaInMultilineFixer::class, + // Arrays should be formatted like function/method arguments + TrimArraySpacesFixer::class, + // In array declaration, there MUST be a whitespace after each comma + WhitespaceAfterCommaInArrayFixer::class, + // Classes must be in a path that matches their namespace + PsrAutoloadingFixer::class, + // Magic method definitions and calls must be using the correct casing + MagicMethodCasingFixer::class, + // Function defined by PHP should be called using the correct casing + NativeFunctionCasingFixer::class, + // Native type hints for functions should use the correct case + NativeTypeDeclarationCasingFixer::class, + // A single space or none should be between cast and variable + CastSpacesFixer::class, + // Cast should be written in lower case + LowercaseCastFixer::class, + // Cast like `(boolean)` and `(integer)` should be written as `(bool)`, `(int)` etc. + ShortScalarCastFixer::class, + // There should be no empty lines after class opening brace + NoBlankLinesAfterClassOpeningFixer::class, + // Inside class or interface element `self` should be preferred to the class name itself + SelfAccessorFixer::class, + // Each trait `use` must be done as single statement + SingleTraitInsertPerStatementFixer::class, + // There should not be any empty comments + NoEmptyCommentFixer::class, + // There should not be useless `else` cases + NoUselessElseFixer::class, + // Switch case must not be ended with `continue` but with `break`. + SwitchContinueToBreakFixer::class, + // Replace multiple nested calls of `dirname` by only one call with second `$level` parameter. + CombineNestedDirnameFixer::class, + // Order the flags in `fopen` calls, `b` and `t` must be last. + FopenFlagOrderFixer::class, + // The flags in `fopen` calls must contain `b` and must omit `t`. + FopenFlagsFixer::class, + // Add missing space between function's argument and its typehint. + TypeDeclarationSpacesFixer::class, + // Function `implode` must be called with 2 arguments in the documented order. + ImplodeCallFixer::class, + // Lambda must not import variables it doesn't use. + LambdaNotUsedImportFixer::class, + // In function arguments there must not be arguments with default values before non-default ones. + NoUnreachableDefaultArgumentValueFixer::class, + // There must be no `sprintf` calls with only the first argument. + NoUselessSprintfFixer::class, - $containerConfigurator->import($vendorDir . '/symplify/easy-coding-standard/config/set/php_cs_fixer/php-cs-fixer-psr2.php'); - $containerConfigurator->import($vendorDir . '/symplify/easy-coding-standard/config/set/php_codesniffer/php-codesniffer-psr2.php'); + ReturnTypeDeclarationFixer::class, - $services = $containerConfigurator->services(); - (function () use ($services): void { - // Function http_build_query() should always have specified `$arg_separator` parameter - $services->set(SpecifyArgSeparatorFixer::class); - // Abstract class should have prefix "Abstract" - $services->set(AbstractClassNameSniff::class); - // Classes should have suffix by theirs parent class/interface - $services->set(ClassNameSuffixByParentSniff::class); - // Interface should have suffix "Interface" - $services->set(InterfaceNameSniff::class); - // Trait should have suffix "Trait" - $services->set(TraitNameSniff::class); - // Class and Interface names should be unique in a project, they should never be duplicated - $services->set(DuplicateClassNameSniff::class); - // Control Structures must have at least one statement inside of the body (empty catch rules is skipped) - $services->set(EmptyStatementSniff::class); - // For loops that have only a second expression (the condition) should be converted to while loops - $services->set(ForLoopShouldBeWhileLoopSniff::class); - // Incrementers in nested loops should use different variable names - $services->set(JumbledIncrementerSniff::class); - // If statements that are always evaluated should not be used - $services->set(UnconditionalIfStatementSniff::class); - // Methods should not be declared final inside of classes that are declared final - $services->set(UnnecessaryFinalModifierSniff::class); - // Methods should not be defined that only call the parent method - $services->set(UselessOverridingMethodSniff::class); - // Doc comment formatting (but some of the rules are skipped) - $services->set(DocCommentSniff::class); - // Line length should not exceed 120 characters - $services->set(LineLengthSniff::class) - ->property('absoluteLineLimit', 0) - ->property('lineLimit', 120); - // There should only be one class defined in a file - $services->set(OneClassPerFileSniff::class); - // There should only be one interface defined in a file - $services->set(OneInterfacePerFileSniff::class); - // There should only be one trait defined in a file - $services->set(OneTraitPerFileSniff::class); - // Exactly one space is allowed after a cast - $services->set(SpaceAfterCastSniff::class); - // Some functions should not appear in the code - $services->set(ForbiddenFunctionsSniff::class) - ->property( - 'forbiddenFunctions', - [ - // Program execution functions, inspired by https://github.com/spaze/phpstan-disallowed-calls - 'exec' => null, - 'passthru' => null, - 'proc_open' => null, - 'shell_exec' => null, - 'system' => null, - 'pcntl_exec' => null, - 'popen' => null, + VoidReturnFixer::class, - // Dangerous function calls, inspired by https://github.com/spaze/phpstan-disallowed-calls - 'apache_setenv' => null, // might overwrite existing variables - 'dl' => null, // removed from most SAPIs, might load untrusted code - 'eval' => null, // eval is evil, please write more code and do not use eval() - 'extract' => null, // do not use extract() and especially not on untrusted data - 'highlight_file' => null, // might reveal source code or config files - 'pfsockopen' => null, // use fsockopen() to create non-persistent socket connections - 'posix_getpwuid' => null, // might reveal system user information - 'posix_kill' => null, // do not send signals to processes from the script - 'posix_mkfifo' => null, // do not create named pipes in the script - 'posix_mknod' => null, // do not create special files in the script - 'proc_nice' => null, // changes the priority of the current process - 'putenv' => null, // might overwrite existing variables - 'show_source' => null, // might reveal source code or config files (alias of highlight_file()) - 'socket_create_listen' => null, // do not accept new socket connections in the PHP script - 'socket_listen' => null, // do not accept new socket connections in the PHP script + NoLeadingImportSlashFixer::class, - // PHP include/require functions, use autoloading instead - 'include' => null, - 'include_once' => null, - 'require' => null, - 'require_once' => null, + NoUnusedImportsFixer::class, - // Probably forgotten debug calls, use logger instead - 'dump' => null, - 'echo' => null, - 'phpinfo' => null, - 'print_r' => null, - 'printf' => null, - 'var_export' => null, - 'var_dump' => null, - ] - ); - // When referencing arrays you should not put whitespace around the opening bracket or before the closing bracket - $services->set(ArrayBracketSpacingSniff::class); - // Various array declaration rules (but some of the rules are skipped) - $services->set(ArrayDeclarationSniff::class); - // The self keyword should be used instead of the current class name - $services->set(SelfMemberReferenceSniff::class); - // The asterisks in a doc comment should align, and there should be one space between the asterisk and tags - $services->set(DocCommentAlignmentSniff::class); - // Empty catch statements must have comment explaining why the exception is not handled - $services->set(EmptyCatchCommentSniff::class); - // Tests that the ++ operators are used when possible and not used when it makes the code confusing - $services->set(IncrementDecrementUsageSniff::class); - // Verifies that class members have scope modifiers - $services->set(MemberVarScopeSniff::class); - // Detects merge conflict artifacts left in files - $services->set(GitMergeConflictSniff::class); - // Casts should not have whitespace inside the parentheses - $services->set(CastSpacingSniff::class); - // The php constructs like echo, return, include, etc. should have one space after them - $services->set(LanguageConstructSpacingSniff::class); - // Verifies that operators have valid spacing surrounding them - $services->set(LogicalOperatorSpacingSniff::class); - // Proper operator spacing - $services->set(OperatorSpacingSniff::class) - ->property('ignoreNewlines', true); - // The php keywords static, public, private, and protected should have one space after them - $services->set(ScopeKeywordSpacingSniff::class); - // Semicolons should not have spaces before them - $services->set(SemicolonSpacingSniff::class); - // Converts simple usages of `array_push($x, $y);` to `$x[] = $y;`. - $services->set(ArrayPushFixer::class); - // Replace non multibyte-safe functions with corresponding mb function - $services->set(MbStrFunctionsFixer::class); - // Master functions shall be used instead of aliases - $services->set(NoAliasFunctionsFixer::class); - // Replaces `rand`, `srand`, `getrandmax` functions calls with their `mt_*` analogs - $services->set(RandomApiMigrationFixer::class); - // Cast shall be used, not `settype()` - $services->set(SetTypeToCastFixer::class); - // PHP arrays should be declared using the configured syntax - $services->set(ArraySyntaxFixer::class) - ->call('configure', [['syntax' => 'short']]); - // Array index should always be written by using square braces - $services->set(NormalizeIndexBraceFixer::class); - // PHP single-line arrays should not have trailing comma - $services->set(NoTrailingCommaInSinglelineArrayFixer::class); - // Multi-line arrays, arguments list and parameters list must have a trailing comma - $services->set(TrailingCommaInMultilineFixer::class); - // Arrays should be formatted like function/method arguments - $services->set(TrimArraySpacesFixer::class); - // In array declaration, there MUST be a whitespace after each comma - $services->set(WhitespaceAfterCommaInArrayFixer::class); - // The body of each structure MUST be enclosed by braces. Braces should be properly placed - $services->set(BracesFixer::class) - ->call( - 'configure', - [['allow_single_line_closure' => true, 'allow_single_line_anonymous_class_with_empty_body' => true]] - ); - // Classes must be in a path that matches their namespace - $services->set(PsrAutoloadingFixer::class); + OrderedImportsFixer::class, - // Magic method definitions and calls must be using the correct casing - $services->set(MagicMethodCasingFixer::class); - // Function defined by PHP should be called using the correct casing - $services->set(NativeFunctionCasingFixer::class); - // Native type hints for functions should use the correct case - $services->set(NativeFunctionTypeDeclarationCasingFixer::class); - // A single space or none should be between cast and variable - $services->set(CastSpacesFixer::class); - // Cast should be written in lower case - $services->set(LowercaseCastFixer::class); - // Cast like `(boolean)` and `(integer)` should be written as `(bool)`, `(int)` etc. - $services->set(ShortScalarCastFixer::class); - // Class, trait and interface elements must be separated with one or none blank line - $services->set(ClassAttributesSeparationFixer::class) - ->call('configure', [['elements' => ['method' => 'one']]]); - // There should be no empty lines after class opening brace - $services->set(NoBlankLinesAfterClassOpeningFixer::class); - // Inside class or interface element `self` should be preferred to the class name itself - $services->set(SelfAccessorFixer::class); - // Each trait `use` must be done as single statement - $services->set(SingleTraitInsertPerStatementFixer::class); - // Visibility MUST be declared on all properties, methods and class constants - $services->set(VisibilityRequiredFixer::class) - ->call('configure', [['elements' => ['const', 'method', 'property']]]); - // There should not be any empty comments - $services->set(NoEmptyCommentFixer::class); - // There should not be useless `else` cases - $services->set(NoUselessElseFixer::class); - // Switch case must not be ended with `continue` but with `break`. - $services->set(SwitchContinueToBreakFixer::class); - // Conditions must be written in non-Yoda style - $services->set(YodaStyleFixer::class) - ->call('configure', [['equal' => false, 'identical' => false, 'less_and_greater' => false]]); - // Replace multiple nested calls of `dirname` by only one call with second `$level` parameter. - $services->set(CombineNestedDirnameFixer::class); - // Order the flags in `fopen` calls, `b` and `t` must be last. - $services->set(FopenFlagOrderFixer::class); - // The flags in `fopen` calls must contain `b` and must omit `t`. - $services->set(FopenFlagsFixer::class); - // Add missing space between function's argument and its typehint. - $services->set(FunctionTypehintSpaceFixer::class); - // Function `implode` must be called with 2 arguments in the documented order. - $services->set(ImplodeCallFixer::class); - // Lambda must not import variables it doesn't use. - $services->set(LambdaNotUsedImportFixer::class); - // In function arguments there must not be arguments with default values before non-default ones. - $services->set(NoUnreachableDefaultArgumentValueFixer::class); - // There must be no `sprintf` calls with only the first argument. - $services->set(NoUselessSprintfFixer::class); + DeclareEqualNormalizeFixer::class, + // Replaces `is_null($var)` expression with `null === $var` + IsNullFixer::class, + // Ensures a single space around language constructs. + SingleSpaceAroundConstructFixer::class, + // Namespace must not contain spacing, comments or PHPDoc. + CleanNamespaceFixer::class, + // The namespace declaration line shouldn't contain leading whitespace. + NoLeadingNamespaceWhitespaceFixer::class, - $services->set(ReturnTypeDeclarationFixer::class); + BinaryOperatorSpacesFixer::class, - $services->set(VoidReturnFixer::class); + NewWithParenthesesFixer::class, - $services->set(NoLeadingImportSlashFixer::class); + ObjectOperatorWithoutWhitespaceFixer::class, - $services->set(NoUnusedImportsFixer::class); + StandardizeNotEqualsFixer::class, + // Standardize spaces around ternary operator. + TernaryOperatorSpacesFixer::class, + // Use the Elvis operator `?:` where possible. + TernaryToElvisOperatorFixer::class, + // Use `null` coalescing operator `??` where possible. + TernaryToNullCoalescingFixer::class, - $services->set(OrderedImportsFixer::class); + UnaryOperatorSpacesFixer::class, - $services->set(DeclareEqualNormalizeFixer::class); - // Replaces `is_null($var)` expression with `null === $var` - $services->set(IsNullFixer::class); - // Ensures a single space after language constructs. - $services->set(SingleSpaceAfterConstructFixer::class); + NoBlankLinesAfterPhpdocFixer::class, - $services->set(ListSyntaxFixer::class) - ->call('configure', [['syntax' => 'short']]); - // Namespace must not contain spacing, comments or PHPDoc. - $services->set(CleanNamespaceFixer::class); - // The namespace declaration line shouldn\'t contain leading whitespace. - $services->set(NoLeadingNamespaceWhitespaceFixer::class); - // There should be exactly one blank line before a namespace declaration. - $services->set(SingleBlankLineBeforeNamespaceFixer::class); + NoEmptyPhpdocFixer::class, + // PHPDoc should contain `@param` for all params. + PhpdocAddMissingParamAnnotationFixer::class, + // Docblocks should have the same indentation as the documented subject. + PhpdocIndentFixer::class, + // `@access` annotations should be omitted from PHPDoc. + PhpdocNoAccessFixer::class, + // `@return void` and `@return null` annotations should be omitted from PHPDoc. + PhpdocNoEmptyReturnFixer::class, + // `@package` and `@subpackage` annotations should be omitted from PHPDoc. + PhpdocNoPackageFixer::class, + // Annotations in PHPDoc should be ordered. + PhpdocOrderFixer::class, + // The type of `@return` annotations of methods returning a reference to itself must the configured one. + PhpdocReturnSelfReferenceFixer::class, + // Scalar types should always be written in the same form. + PhpdocScalarFixer::class, + // Single line `@var` PHPDoc should have proper spacing. + PhpdocSingleLineVarSpacingFixer::class, + // PHPDoc should start and end with content + PhpdocTrimFixer::class, + // The correct case must be used for standard PHP types in PHPDoc. + PhpdocTypesFixer::class, + // `@var` and `@type` annotations must have type and name in the correct order + PhpdocVarAnnotationCorrectOrderFixer::class, + // PHP code must use the long `assertSame(true, $foo) should be written with dedicated method like ->assertTrue($foo) + PhpUnitConstructFixer::class, + // PHPUnit assertions like assertInternalType, assertFileExists, should be used over assertTrue + PhpUnitDedicateAssertFixer::class, + // PHPUnit assertions like assertIsArray should be used over assertInternalType + PhpUnitDedicateAssertInternalTypeFixer::class, + // Use dedicated helper methods createMock() and createPartialMock() where possible + PhpUnitMockFixer::class, + // Use of eg. ->will($this->returnValue(..)) must be replaced by its shorter equivalent such as ->willReturn(...) + PhpUnitMockShortWillReturnFixer::class, + // Use expectedException*() methods instead of @expectedException* annotation (both following fixers must be applied to do so) + PhpUnitNoExpectationAnnotationFixer::class, + // Usages of ->setExpectedException* methods MUST be replaced by ->expectException* methods + PhpUnitExpectationFixer::class, + // Visibility of setUp() and tearDown() method should be kept protected + PhpUnitSetUpTearDownVisibilityFixer::class, + // There should not be an empty `return` statement at the end of a function + NoUselessReturnFixer::class, + // Remove useless (semicolon) statements + NoEmptyStatementFixer::class, + // Single-line whitespace before closing semicolon are prohibited + NoSinglelineWhitespaceBeforeSemicolonsFixer::class, + // Fix whitespace after a semicolon + SpaceAfterSemicolonFixer::class, + // Force strict types declaration in all files + DeclareStrictTypesFixer::class, + // Functions should be used with `$strict` param set to `true` + StrictParamFixer::class, + // Convert double quotes to single quotes for simple strings + SingleQuoteFixer::class, + // Remove extra spaces in a nullable typehint + CompactNullableTypeDeclarationFixer::class, + // Heredoc/nowdoc content must be properly indented. + HeredocIndentationFixer::class, + // Remove trailing whitespace at the end of blank lines + NoWhitespaceInBlankLineFixer::class, + // Use \Throwable instead of \Exception + ReferenceThrowableOnlySniff::class, + // The @param, @return, @var and inline @var annotations should keep standard format + ParamReturnAndVarTagMalformsFixer::class, + // Takes `@var` annotation of non-mixed types and adjusts accordingly the property signature. + PhpdocToPropertyTypeFixer::class, + // Takes `@param` annotations of non-mixed types and adjusts accordingly the function signature. + PhpdocToParamTypeFixer::class, + // Takes `@return` annotation of non-mixed types and adjusts accordingly the function signature. + PhpdocToReturnTypeFixer::class, + // Promote constructor properties + // @see https://github.com/FriendsOfPHP/PHP-CS-Fixer/issues/5956 + RequireConstructorPropertyPromotionSniff::class, - $services->set(BinaryOperatorSpacesFixer::class); + // switch -> match + // @see https://github.com/FriendsOfPHP/PHP-CS-Fixer/issues/5894 - $services->set(ConcatSpaceFixer::class) - ->call('configure', [['spacing' => 'one']]); + // Require \Stringable interface in classes implementing __toString() method + // > it may probably be a phpstan rule, more than cs rule - since it needs a class hierarchy to solve this + // @see https://github.com/FriendsOfPHP/PHP-CS-Fixer/issues/6235 + PropertyTypeHintSniff::class, - $services->set(NewWithBracesFixer::class); + ParameterTypeHintSniff::class, + ReturnTypeHintSniff::class, - $services->set(ObjectOperatorWithoutWhitespaceFixer::class); + // Multi-line arguments list in function/method declaration must have a trailing comma + RequireTrailingCommaInDeclarationSniff::class, + // Multi-line arguments list in function/method call must have a trailing comma + RequireTrailingCommaInCallSniff::class, - $services->set(StandardizeNotEqualsFixer::class); - // Standardize spaces around ternary operator. - $services->set(TernaryOperatorSpacesFixer::class); - // Use the Elvis operator `?:` where possible. - $services->set(TernaryToElvisOperatorFixer::class); - // Use `null` coalescing operator `??` where possible. - $services->set(TernaryToNullCoalescingFixer::class); + // Use `null-safe` operator `?->` where possible + RequireNullSafeObjectOperatorSniff::class, + ], + ) + // Line length should not exceed 120 characters + ->withConfiguredRule(LineLengthSniff::class, ['absoluteLineLimit' => 0, 'lineLimit' => 120]) + ->withConfiguredRule(ForbiddenFunctionsSniff::class, [ + 'forbiddenFunctions' => [ + // Program execution functions, inspired by https://github.com/spaze/phpstan-disallowed-calls + 'exec' => null, + 'passthru' => null, + 'proc_open' => null, + 'shell_exec' => null, + 'system' => null, + 'pcntl_exec' => null, + 'popen' => null, - $services->set(UnaryOperatorSpacesFixer::class); + // Dangerous function calls, inspired by https://github.com/spaze/phpstan-disallowed-calls + 'apache_setenv' => null, // might overwrite existing variables + 'dl' => null, // removed from most SAPIs, might load untrusted code + 'eval' => null, // eval is evil, please write more code and do not use eval() + 'extract' => null, // do not use extract() and especially not on untrusted data + 'highlight_file' => null, // might reveal source code or config files + 'pfsockopen' => null, // use fsockopen() to create non-persistent socket connections + 'posix_getpwuid' => null, // might reveal system user information + 'posix_kill' => null, // do not send signals to processes from the script + 'posix_mkfifo' => null, // do not create named pipes in the script + 'posix_mknod' => null, // do not create special files in the script + 'proc_nice' => null, // changes the priority of the current process + 'putenv' => null, // might overwrite existing variables + 'show_source' => null, // might reveal source code or config files (alias of highlight_file()) + 'socket_create_listen' => null, // do not accept new socket connections in the PHP script + 'socket_listen' => null, // do not accept new socket connections in the PHP script - $services->set(NoBlankLinesAfterPhpdocFixer::class); + // PHP include/require functions, use autoloading instead + 'include' => null, + 'include_once' => null, + 'require' => null, + 'require_once' => null, - $services->set(NoEmptyPhpdocFixer::class); - // Removes `@param` and `@return` tags that don't provide any useful information - $services->set(NoSuperfluousPhpdocTagsFixer::class) - ->call( - 'configure', - [ - [ - 'allow_mixed' => true, // allow `@mixed` annotations to be preserved - 'allow_unused_params' => false, // whether param annotation without actual signature is allowed - 'remove_inheritdoc' => true, // remove @inheritDoc tags - ], - ] - ); - // PHPDoc should contain `@param` for all params. - $services->set(PhpdocAddMissingParamAnnotationFixer::class); - // Docblocks should have the same indentation as the documented subject. - $services->set(PhpdocIndentFixer::class); - // `@access` annotations should be omitted from PHPDoc. - $services->set(PhpdocNoAccessFixer::class); - // `@return void` and `@return null` annotations should be omitted from PHPDoc. - $services->set(PhpdocNoEmptyReturnFixer::class); - // `@package` and `@subpackage` annotations should be omitted from PHPDoc. - $services->set(PhpdocNoPackageFixer::class); - // Order phpdoc tags by value. - $services->set(PhpdocOrderByValueFixer::class) - ->call( - 'configure', - [['annotations' => ['covers', 'group', 'throws']]] - ); - // Annotations in PHPDoc should be ordered. - $services->set(PhpdocOrderFixer::class); - // The type of `@return` annotations of methods returning a reference to itself must the configured one. - $services->set(PhpdocReturnSelfReferenceFixer::class); - // Scalar types should always be written in the same form. - $services->set(PhpdocScalarFixer::class); - // Single line `@var` PHPDoc should have proper spacing. - $services->set(PhpdocSingleLineVarSpacingFixer::class); - // PHPDoc should start and end with content - $services->set(PhpdocTrimFixer::class); - // The correct case must be used for standard PHP types in PHPDoc. - $services->set(PhpdocTypesFixer::class); - // `@var` and `@type` annotations must have type and name in the correct order - $services->set(PhpdocVarAnnotationCorrectOrderFixer::class); - // PHP code must use the long `set(FullOpeningTagFixer::class); - // PHPUnit assertion method calls like ->assertSame(true, $foo) should be written with dedicated method like ->assertTrue($foo) - $services->set(PhpUnitConstructFixer::class); - // PHPUnit assertions like assertInternalType, assertFileExists, should be used over assertTrue - $services->set(PhpUnitDedicateAssertFixer::class); - // PHPUnit assertions like assertIsArray should be used over assertInternalType - $services->set(PhpUnitDedicateAssertInternalTypeFixer::class); - // Use dedicated helper methods createMock() and createPartialMock() where possible - $services->set(PhpUnitMockFixer::class); - // Use of eg. ->will($this->returnValue(..)) must be replaced by its shorter equivalent such as ->willReturn(...) - $services->set(PhpUnitMockShortWillReturnFixer::class); - // Use expectedException*() methods instead of @expectedException* annotation (both following fixers must be applied to do so) - $services->set(PhpUnitNoExpectationAnnotationFixer::class); + // Probably forgotten debug calls, use logger instead + 'dump' => null, + 'echo' => null, + 'phpinfo' => null, + 'print_r' => null, + 'printf' => null, + 'var_export' => null, + 'var_dump' => null, + ], + ]) + // There should be exactly one blank line before a namespace declaration. + ->withConfiguredRule(BlankLinesBeforeNamespaceFixer::class, ['min_line_breaks' => 2, 'max_line_breaks' => 2]) + // Proper operator spacing + ->withConfiguredRule(OperatorSpacingSniff::class, ['ignoreNewlines' => true]) + // PHP arrays should be declared using the configured syntax + ->withConfiguredRule(ArraySyntaxFixer::class, ['syntax' => 'short']) + // The body of each structure MUST be enclosed by braces. Braces should be properly placed + // @TODO move configuration to BracesPositionFixer after BracesFixer is not included in PSR-12 check anymore + ->withConfiguredRule(BracesFixer::class, ['allow_single_line_closure' => true, 'allow_single_line_anonymous_class_with_empty_body' => true]) + // Class, trait and interface elements must be separated with one or none blank line + ->withConfiguredRule(ClassAttributesSeparationFixer::class, ['elements' => ['method' => 'one']]) + // Visibility MUST be declared on all properties, methods and class constants + ->withConfiguredRule(VisibilityRequiredFixer::class, ['elements' => ['const', 'method', 'property']]) + // Conditions must be written in non-Yoda style + ->withConfiguredRule(YodaStyleFixer::class, ['equal' => false, 'identical' => false, 'less_and_greater' => false]) + ->withConfiguredRule(ListSyntaxFixer::class, ['syntax' => 'short']) + ->withConfiguredRule(ConcatSpaceFixer::class, ['spacing' => 'one']) + // Removes `@param` and `@return` tags that don't provide any useful information + ->withConfiguredRule(NoSuperfluousPhpdocTagsFixer::class, [ + 'allow_mixed' => true, // allow `@mixed` annotations to be preserved + 'allow_unused_params' => false, // whether param annotation without actual signature is allowed + 'remove_inheritdoc' => true, // remove @inheritDoc tags + ]) + // Order phpdoc tags by value. + ->withConfiguredRule(PhpdocOrderByValueFixer::class, ['annotations' => ['covers', 'group', 'throws']]) + // Calls to `PHPUnit\Framework\TestCase` static methods must all be of the same type (`$this->...`) + ->withConfiguredRule(PhpUnitTestCaseStaticMethodCallsFixer::class, ['call_type' => 'this']) + // An empty line feed must precede any configured statement + ->withConfiguredRule(BlankLineBeforeStatementFixer::class, ['statements' => ['return', 'try']]) + // Removes extra blank lines and/or blank lines following configuration + ->withConfiguredRule(NoExtraBlankLinesFixer::class, [ + 'tokens' => [ + 'break', + 'continue', + 'curly_brace_block', + 'extra', + 'parenthesis_brace_block', + 'return', + 'square_brace_block', + 'throw', + 'use', + 'use_trait', + ], + ]) + // Format union types + ->withConfiguredRule(UnionTypeHintFormatSniff::class, ['withSpaces' => 'no']) + ->withSkip([ + // We allow empty catch statements (but they must have comment - see EmptyCatchCommentSniff) + EmptyStatementSniff::class . '.DetectedCatch' => null, - // Following check fails on PHP <8.0. See https://github.com/symplify/symplify/issues/3130 - if (PHP_VERSION_ID >= 80000) { - // Usages of ->setExpectedException* methods MUST be replaced by ->expectException* methods - $services->set(PhpUnitExpectationFixer::class); - } + // Skip unwanted rules from DocCommentSniff + DocCommentSniff::class . '.ContentAfterOpen' => null, + DocCommentSniff::class . '.ContentBeforeClose' => null, + DocCommentSniff::class . '.MissingShort' => null, + DocCommentSniff::class . '.NonParamGroup' => null, + DocCommentSniff::class . '.ParamGroup' => null, + DocCommentSniff::class . '.ParamNotFirst' => null, + DocCommentSniff::class . '.SpacingBeforeTags' => null, + DocCommentSniff::class . '.TagValueIndent' => null, + + // Skip unwanted rules from ArrayDeclarationSniff + ArrayDeclarationSniff::class . '.CloseBraceNotAligned' => null, + ArrayDeclarationSniff::class . '.DoubleArrowNotAligned' => null, + ArrayDeclarationSniff::class . '.KeyNotAligned' => null, + ArrayDeclarationSniff::class . '.MultiLineNotAllowed' => null, + ArrayDeclarationSniff::class . '.SingleLineNotAllowed' => null, + ArrayDeclarationSniff::class . '.ValueNoNewline' => null, + ArrayDeclarationSniff::class . '.ValueNotAligned' => null, - // Visibility of setUp() and tearDown() method should be kept protected - $services->set(PhpUnitSetUpTearDownVisibilityFixer::class); - // Calls to `PHPUnit\Framework\TestCase` static methods must all be of the same type (`$this->...`) - $services->set(PhpUnitTestCaseStaticMethodCallsFixer::class) - ->call('configure', [['call_type' => 'this']]); - // There should not be an empty `return` statement at the end of a function - $services->set(NoUselessReturnFixer::class); - // Remove useless (semicolon) statements - $services->set(NoEmptyStatementFixer::class); - // Single-line whitespace before closing semicolon are prohibited - $services->set(NoSinglelineWhitespaceBeforeSemicolonsFixer::class); - // Fix whitespace after a semicolon - $services->set(SpaceAfterSemicolonFixer::class); - // Force strict types declaration in all files - $services->set(DeclareStrictTypesFixer::class); - // Functions should be used with `$strict` param set to `true` - $services->set(StrictParamFixer::class); - // Convert double quotes to single quotes for simple strings - $services->set(SingleQuoteFixer::class); - // An empty line feed must precede any configured statement - $services->set(BlankLineBeforeStatementFixer::class) - ->call('configure', [['statements' => ['return', 'try']]]); - // Remove extra spaces in a nullable typehint - $services->set(CompactNullableTypehintFixer::class); - // Heredoc/nowdoc content must be properly indented. - $services->set(HeredocIndentationFixer::class); - // Removes extra blank lines and/or blank lines following configuration - $services->set(NoExtraBlankLinesFixer::class) - ->call( - 'configure', - [['tokens' => ['break', 'continue', 'curly_brace_block', 'extra', 'parenthesis_brace_block', 'return', 'square_brace_block', 'throw', 'use', 'use_trait']]] - ); - // Remove trailing whitespace at the end of blank lines - $services->set(NoWhitespaceInBlankLineFixer::class); - // Use \Throwable instead of \Exception - $services->set(ReferenceThrowableOnlySniff::class); - // The @param, @return, @var and inline @var annotations should keep standard format - $services->set(ParamReturnAndVarTagMalformsFixer::class); - })(); + // There could be more than one space after star (eg. in Doctrine annotations) + DocCommentAlignmentSniff::class . '.SpaceAfterStar' => null, - $parameters = $containerConfigurator->parameters(); - (function () use ($parameters): void { - $parameters->set( - Option::SKIP, - [ - // We allow empty catch statements (but they must have comment - see EmptyCatchCommentSniff) - 'PHP_CodeSniffer\Standards\Generic\Sniffs\CodeAnalysis\EmptyStatementSniff.DetectedCatch' => null, + // Allow single line closures + ScopeClosingBraceSniff::class . '.ContentBefore' => null, - // Skip unwanted rules from DocCommentSniff - 'PHP_CodeSniffer\Standards\Generic\Sniffs\Commenting\DocCommentSniff.ContentAfterOpen' => null, - 'PHP_CodeSniffer\Standards\Generic\Sniffs\Commenting\DocCommentSniff.ContentBeforeClose' => null, - 'PHP_CodeSniffer\Standards\Generic\Sniffs\Commenting\DocCommentSniff.MissingShort' => null, - 'PHP_CodeSniffer\Standards\Generic\Sniffs\Commenting\DocCommentSniff.NonParamGroup' => null, - 'PHP_CodeSniffer\Standards\Generic\Sniffs\Commenting\DocCommentSniff.ParamGroup' => null, - 'PHP_CodeSniffer\Standards\Generic\Sniffs\Commenting\DocCommentSniff.ParamNotFirst' => null, - 'PHP_CodeSniffer\Standards\Generic\Sniffs\Commenting\DocCommentSniff.SpacingBeforeTags' => null, - 'PHP_CodeSniffer\Standards\Generic\Sniffs\Commenting\DocCommentSniff.TagValueIndent' => null, + // Skip unwanted rules from PropertyTypeHintSniff + PropertyTypeHintSniff::class . '.' . PropertyTypeHintSniff::CODE_MISSING_TRAVERSABLE_TYPE_HINT_SPECIFICATION => null, + PropertyTypeHintSniff::class . '.' . PropertyTypeHintSniff::CODE_MISSING_ANY_TYPE_HINT => null, - // Skip unwanted rules from ArrayDeclarationSniff - 'PHP_CodeSniffer\Standards\Squiz\Sniffs\Arrays\ArrayDeclarationSniff.CloseBraceNotAligned' => null, - 'PHP_CodeSniffer\Standards\Squiz\Sniffs\Arrays\ArrayDeclarationSniff.DoubleArrowNotAligned' => null, - 'PHP_CodeSniffer\Standards\Squiz\Sniffs\Arrays\ArrayDeclarationSniff.KeyNotAligned' => null, - 'PHP_CodeSniffer\Standards\Squiz\Sniffs\Arrays\ArrayDeclarationSniff.MultiLineNotAllowed' => null, - 'PHP_CodeSniffer\Standards\Squiz\Sniffs\Arrays\ArrayDeclarationSniff.SingleLineNotAllowed' => null, - 'PHP_CodeSniffer\Standards\Squiz\Sniffs\Arrays\ArrayDeclarationSniff.ValueNoNewline' => null, - 'PHP_CodeSniffer\Standards\Squiz\Sniffs\Arrays\ArrayDeclarationSniff.ValueNotAligned' => null, + // Skip unwanted rules from ParameterTypeHintSniff + ParameterTypeHintSniff::class . '.' . ParameterTypeHintSniff::CODE_MISSING_TRAVERSABLE_TYPE_HINT_SPECIFICATION => null, + ParameterTypeHintSniff::class . '.' . ParameterTypeHintSniff::CODE_MISSING_ANY_TYPE_HINT => null, - // There could be more than one space after star (eg. in Doctrine annotations) - 'PHP_CodeSniffer\Standards\Squiz\Sniffs\Commenting\DocCommentAlignmentSniff.SpaceAfterStar' => null, + // Skip unwanted rules from ReturnTypeHintSniff + ReturnTypeHintSniff::class . '.' . ReturnTypeHintSniff::CODE_MISSING_TRAVERSABLE_TYPE_HINT_SPECIFICATION => null, + ReturnTypeHintSniff::class . '.' . ReturnTypeHintSniff::CODE_MISSING_ANY_TYPE_HINT => null, - // Allow single line closures - 'PHP_CodeSniffer\Standards\Squiz\Sniffs\WhiteSpace\ScopeClosingBraceSniff.ContentBefore' => null, - ] - ); - })(); -}; + // We use declare(strict_types=1); after opening tag + BlankLineAfterOpeningTagFixer::class => null, + ]); diff --git a/src/Fixer/SpecifyArgSeparatorFixer.php b/src/Fixer/SpecifyArgSeparatorFixer.php index 0495bbf..819b932 100644 --- a/src/Fixer/SpecifyArgSeparatorFixer.php +++ b/src/Fixer/SpecifyArgSeparatorFixer.php @@ -24,7 +24,7 @@ public function getDefinition(): FixerDefinitionInterface . 'however when its default value "&" is changed, query string assembled by the method will be ' . 'unexpectedly invalid. This Fixer forces you to not rely on ini settings and rather define ' . '`$arg_separator` in third argument of the function.', - 'Risky when other than default "&" argument separator should be used in query strings.' + 'Risky when other than default "&" argument separator should be used in query strings.', ); } @@ -84,7 +84,7 @@ private function fixFunction(Tokens $tokens, int $functionIndex): void $thirdArgumentTuple = $this->getThirdArgumentTokenTuple( $tokens, $openParenthesisIndex, - $closeParenthesisIndex + $closeParenthesisIndex, ); if ($thirdArgumentTuple === []) { return; @@ -134,7 +134,7 @@ private function isFunctionCall(Tokens $tokens, int $index): bool private function getThirdArgumentTokenTuple( Tokens $tokens, int $openParenthesisIndex, - int $closeParenthesisIndex + int $closeParenthesisIndex, ): array { $argumentsAnalyzer = new ArgumentsAnalyzer(); $allArguments = $argumentsAnalyzer->getArguments($tokens, $openParenthesisIndex, $closeParenthesisIndex); diff --git a/src/Helper/Naming.php b/src/Helper/Naming.php index 92ba8a5..eb99a74 100644 --- a/src/Helper/Naming.php +++ b/src/Helper/Naming.php @@ -42,12 +42,12 @@ final class Naming /** * @var mixed[][] */ - private $referencedNamesByFilePath = []; + private array $referencedNamesByFilePath = []; /** * @var string[][] */ - private $fqnClassNameByFilePathAndClassName = []; + private array $fqnClassNameByFilePathAndClassName = []; public function getClassName(File $file, int $classNameStartPosition): string { @@ -97,7 +97,7 @@ private function getFqnClassName(File $file, string $className, int $classTokenP $resolvedName = NamespaceHelper::resolveClassName( $file, $referencedName->getNameAsReferencedInFile(), - $classTokenPosition + $classTokenPosition, ); if ($referencedName->getNameAsReferencedInFile() === $className) { diff --git a/src/Helper/SniffClassWrapper.php b/src/Helper/SniffClassWrapper.php index ed36207..84d05f2 100644 --- a/src/Helper/SniffClassWrapper.php +++ b/src/Helper/SniffClassWrapper.php @@ -33,26 +33,8 @@ final class SniffClassWrapper { - /** - * @var int - */ - private $position; - - /** - * @var File - */ - private $file; - - /** - * @var Naming - */ - private $naming; - - public function __construct(File $file, int $position, Naming $naming) + public function __construct(private File $file, private int $position, private Naming $naming) { - $this->file = $file; - $this->position = $position; - $this->naming = $naming; } public function getClassName(): ?string @@ -111,10 +93,7 @@ public function getParentClassName(): ?string return $this->naming->getClassName($this->file, $parentClassPosition); } - /** - * @return bool|int - */ - private function getImplementsPosition() + private function getImplementsPosition(): bool|int { return $this->file->findNext(T_IMPLEMENTS, $this->position, $this->position + 15); } diff --git a/src/Sniffs/Naming/AbstractClassNameSniff.php b/src/Sniffs/Naming/AbstractClassNameSniff.php index 4a7e314..41c10d9 100644 --- a/src/Sniffs/Naming/AbstractClassNameSniff.php +++ b/src/Sniffs/Naming/AbstractClassNameSniff.php @@ -39,15 +39,8 @@ final class AbstractClassNameSniff implements Sniff */ private const ERROR_MESSAGE = 'Abstract class should have prefix "Abstract".'; - /** - * @var int - */ - private $position; - - /** - * @var File - */ - private $file; + private int $position; + private File $file; /** * @return int[] @@ -57,19 +50,16 @@ public function register(): array return [T_CLASS]; } - /** - * @param int $position - */ - public function process(File $file, $position): void + public function process(File $phpcsFile, $stackPtr): void { - $this->file = $file; - $this->position = $position; + $this->file = $phpcsFile; + $this->position = $stackPtr; if ($this->shouldBeSkipped()) { return; } - $file->addError(self::ERROR_MESSAGE, $position, self::class); + $phpcsFile->addError(self::ERROR_MESSAGE, $stackPtr, self::class); } private function shouldBeSkipped(): bool diff --git a/src/Sniffs/Naming/ClassNameSuffixByParentSniff.php b/src/Sniffs/Naming/ClassNameSuffixByParentSniff.php index 21a87a9..ee66c17 100644 --- a/src/Sniffs/Naming/ClassNameSuffixByParentSniff.php +++ b/src/Sniffs/Naming/ClassNameSuffixByParentSniff.php @@ -44,7 +44,7 @@ final class ClassNameSuffixByParentSniff implements Sniff /** * @var string[] */ - public $defaultParentClassToSuffixMap = [ + public array $defaultParentClassToSuffixMap = [ 'Command', 'Controller', 'Repository', @@ -60,7 +60,7 @@ final class ClassNameSuffixByParentSniff implements Sniff /** * @var string[] */ - public $extraParentTypesToSuffixes = []; + public array $extraParentTypesToSuffixes = []; /** * @return int[] @@ -70,12 +70,9 @@ public function register(): array return [T_CLASS]; } - /** - * @param int $position - */ - public function process(File $file, $position): void + public function process(File $phpcsFile, $stackPtr): void { - $classWrapper = $this->getWrapperForFirstClassInFile($file); + $classWrapper = $this->getWrapperForFirstClassInFile($phpcsFile); if ($classWrapper === null) { return; } @@ -87,11 +84,11 @@ public function process(File $file, $position): void $parentClassName = $classWrapper->getParentClassName(); if ($parentClassName) { - $this->processType($file, $parentClassName, $className, $position); + $this->processType($phpcsFile, $parentClassName, $className, $stackPtr); } foreach ($classWrapper->getPartialInterfaceNames() as $interfaceName) { - $this->processType($file, $interfaceName, $className, $position); + $this->processType($phpcsFile, $interfaceName, $className, $stackPtr); } } diff --git a/src/Sniffs/Naming/InterfaceNameSniff.php b/src/Sniffs/Naming/InterfaceNameSniff.php index 0b2243f..497db63 100644 --- a/src/Sniffs/Naming/InterfaceNameSniff.php +++ b/src/Sniffs/Naming/InterfaceNameSniff.php @@ -39,15 +39,9 @@ final class InterfaceNameSniff implements Sniff */ private const ERROR_MESSAGE = 'Interface should have suffix "Interface".'; - /** - * @var int - */ - private $position; + private int $position; - /** - * @var File - */ - private $file; + private File $file; /** * @return int[] @@ -57,19 +51,16 @@ public function register(): array return [T_INTERFACE]; } - /** - * @param int $position - */ - public function process(File $file, $position): void + public function process(File $phpcsFile, $stackPtr): void { - $this->file = $file; - $this->position = $position; + $this->file = $phpcsFile; + $this->position = $stackPtr; if (Strings::endsWith($this->getInterfaceName(), 'Interface')) { return; } - $file->addError(self::ERROR_MESSAGE, $position, self::class); + $phpcsFile->addError(self::ERROR_MESSAGE, $stackPtr, self::class); } private function getInterfaceName(): string diff --git a/src/Sniffs/Naming/TraitNameSniff.php b/src/Sniffs/Naming/TraitNameSniff.php index 659606e..d977e3a 100644 --- a/src/Sniffs/Naming/TraitNameSniff.php +++ b/src/Sniffs/Naming/TraitNameSniff.php @@ -39,15 +39,9 @@ final class TraitNameSniff implements Sniff */ private const ERROR_MESSAGE = 'Trait should have suffix "Trait".'; - /** - * @var int - */ - private $position; + private int $position; - /** - * @var File - */ - private $file; + private File $file; /** * @return int[] @@ -57,19 +51,16 @@ public function register(): array return [T_TRAIT]; } - /** - * @param int $position - */ - public function process(File $file, $position): void + public function process(File $phpcsFile, $stackPtr): void { - $this->file = $file; - $this->position = $position; + $this->file = $phpcsFile; + $this->position = $stackPtr; if (Strings::endsWith($this->getTraitName(), 'Trait')) { return; } - $file->addError(self::ERROR_MESSAGE, $position, self::class); + $phpcsFile->addError(self::ERROR_MESSAGE, $stackPtr, self::class); } private function getTraitName(): string diff --git a/tests/Fixer/SpecifyArgSeparatorFixerTest.php b/tests/Fixer/SpecifyArgSeparatorFixerTest.php index 52a5781..1515ba4 100644 --- a/tests/Fixer/SpecifyArgSeparatorFixerTest.php +++ b/tests/Fixer/SpecifyArgSeparatorFixerTest.php @@ -21,7 +21,7 @@ public function shouldFixCode(string $inputFile, string $expectedOutputFile): vo $this->assertStringEqualsFile( __DIR__ . '/Fixtures/' . $expectedOutputFile, - $tokens->generateCode() + $tokens->generateCode(), ); } From be67c3d258b306f678f13fc31975f1ed45ed4a22 Mon Sep 17 00:00:00 2001 From: Martin Guth Date: Tue, 16 Apr 2024 11:03:41 +0200 Subject: [PATCH 2/2] Remove markdown check which is removed from ECS --- composer.json | 1 - 1 file changed, 1 deletion(-) diff --git a/composer.json b/composer.json index 5cac995..4e8724a 100644 --- a/composer.json +++ b/composer.json @@ -56,7 +56,6 @@ ], "analyze": [ "vendor/bin/ecs check src/ tests/ ecs.php ecs-8.1.php ecs-8.2.php ecs-8.3.php --ansi", - "vendor/bin/ecs check README.md --ansi", "vendor/bin/phpstan analyze -c phpstan.neon --ansi" ], "fix": [