diff --git a/build/target-repository/README.md b/build/target-repository/README.md index 5e5f718a41..8af1595c0d 100644 --- a/build/target-repository/README.md +++ b/build/target-repository/README.md @@ -129,6 +129,16 @@ return ECSConfig::configure() Or enable everything at once with `->withPreparedSets(common: true)`. +Standalone presets are also available: `psr12: true`, `perCs: true`, and `laravel: true` (the [Laravel Pint](https://github.com/laravel/pint/blob/main/resources/presets/laravel.php) ruleset): + +```php +use Symplify\EasyCodingStandard\Config\ECSConfig; + +return ECSConfig::configure() + ->withPaths([__DIR__ . '/src', __DIR__ . '/tests']) + ->withPreparedSets(laravel: true); +``` +
### Gradual Adoption with Levels diff --git a/config/set/laravel.php b/config/set/laravel.php index 56cf2a23a1..731f4e52da 100644 --- a/config/set/laravel.php +++ b/config/set/laravel.php @@ -11,11 +11,12 @@ use PhpCsFixer\Fixer\ArrayNotation\NoWhitespaceBeforeCommaInArrayFixer; use PhpCsFixer\Fixer\ArrayNotation\TrimArraySpacesFixer; use PhpCsFixer\Fixer\ArrayNotation\WhitespaceAfterCommaInArrayFixer; -use PhpCsFixer\Fixer\Basic\CurlyBracesPositionFixer; +use PhpCsFixer\Fixer\Basic\BracesPositionFixer; use PhpCsFixer\Fixer\Basic\EncodingFixer; use PhpCsFixer\Fixer\Basic\NoMultipleStatementsPerLineFixer; use PhpCsFixer\Fixer\Basic\NoTrailingCommaInSinglelineFixer; use PhpCsFixer\Fixer\Basic\PsrAutoloadingFixer; +use PhpCsFixer\Fixer\Basic\SingleLineEmptyBodyFixer; use PhpCsFixer\Fixer\Casing\ConstantCaseFixer; use PhpCsFixer\Fixer\Casing\IntegerLiteralCaseFixer; use PhpCsFixer\Fixer\Casing\LowercaseKeywordsFixer; @@ -23,7 +24,7 @@ use PhpCsFixer\Fixer\Casing\MagicConstantCasingFixer; 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\NoShortBoolCastFixer; @@ -31,46 +32,54 @@ use PhpCsFixer\Fixer\CastNotation\ShortScalarCastFixer; use PhpCsFixer\Fixer\ClassNotation\ClassAttributesSeparationFixer; use PhpCsFixer\Fixer\ClassNotation\ClassDefinitionFixer; +use PhpCsFixer\Fixer\ClassNotation\ModifierKeywordsFixer; use PhpCsFixer\Fixer\ClassNotation\NoBlankLinesAfterClassOpeningFixer; +use PhpCsFixer\Fixer\ClassNotation\OrderedInterfacesFixer; +use PhpCsFixer\Fixer\ClassNotation\OrderedTraitsFixer; use PhpCsFixer\Fixer\ClassNotation\SelfAccessorFixer; use PhpCsFixer\Fixer\ClassNotation\SelfStaticAccessorFixer; use PhpCsFixer\Fixer\ClassNotation\SingleClassElementPerStatementFixer; -use PhpCsFixer\Fixer\ClassNotation\VisibilityRequiredFixer; use PhpCsFixer\Fixer\Comment\NoTrailingWhitespaceInCommentFixer; +use PhpCsFixer\Fixer\Comment\SingleLineCommentSpacingFixer; +use PhpCsFixer\Fixer\Comment\SingleLineCommentStyleFixer; use PhpCsFixer\Fixer\ControlStructure\ControlStructureBracesFixer; use PhpCsFixer\Fixer\ControlStructure\ControlStructureContinuationPositionFixer; use PhpCsFixer\Fixer\ControlStructure\ElseifFixer; use PhpCsFixer\Fixer\ControlStructure\IncludeFixer; use PhpCsFixer\Fixer\ControlStructure\NoAlternativeSyntaxFixer; +use PhpCsFixer\Fixer\ControlStructure\NoUnneededBracesFixer; use PhpCsFixer\Fixer\ControlStructure\NoUnneededControlParenthesesFixer; -use PhpCsFixer\Fixer\ControlStructure\NoUnneededCurlyBracesFixer; use PhpCsFixer\Fixer\ControlStructure\SwitchCaseSemicolonToColonFixer; use PhpCsFixer\Fixer\ControlStructure\SwitchCaseSpaceFixer; use PhpCsFixer\Fixer\ControlStructure\TrailingCommaInMultilineFixer; +use PhpCsFixer\Fixer\ControlStructure\YodaStyleFixer; use PhpCsFixer\Fixer\FunctionNotation\FunctionDeclarationFixer; -use PhpCsFixer\Fixer\FunctionNotation\FunctionTypehintSpaceFixer; use PhpCsFixer\Fixer\FunctionNotation\LambdaNotUsedImportFixer; use PhpCsFixer\Fixer\FunctionNotation\MethodArgumentSpaceFixer; use PhpCsFixer\Fixer\FunctionNotation\NoSpacesAfterFunctionNameFixer; use PhpCsFixer\Fixer\FunctionNotation\NoUnreachableDefaultArgumentValueFixer; +use PhpCsFixer\Fixer\FunctionNotation\NullableTypeDeclarationForDefaultNullValueFixer; use PhpCsFixer\Fixer\FunctionNotation\ReturnTypeDeclarationFixer; use PhpCsFixer\Fixer\Import\FullyQualifiedStrictTypesFixer; use PhpCsFixer\Fixer\Import\NoLeadingImportSlashFixer; +use PhpCsFixer\Fixer\Import\NoUnneededImportAliasFixer; use PhpCsFixer\Fixer\Import\NoUnusedImportsFixer; use PhpCsFixer\Fixer\Import\OrderedImportsFixer; use PhpCsFixer\Fixer\Import\SingleImportPerStatementFixer; use PhpCsFixer\Fixer\Import\SingleLineAfterImportsFixer; use PhpCsFixer\Fixer\LanguageConstruct\DeclareEqualNormalizeFixer; use PhpCsFixer\Fixer\LanguageConstruct\DeclareParenthesesFixer; +use PhpCsFixer\Fixer\LanguageConstruct\NullableTypeDeclarationFixer; use PhpCsFixer\Fixer\LanguageConstruct\SingleSpaceAroundConstructFixer; use PhpCsFixer\Fixer\ListNotation\ListSyntaxFixer; use PhpCsFixer\Fixer\NamespaceNotation\BlankLineAfterNamespaceFixer; +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\IncrementStyleFixer; +use PhpCsFixer\Fixer\Operator\NewWithParenthesesFixer; use PhpCsFixer\Fixer\Operator\NoSpaceAroundDoubleColonFixer; use PhpCsFixer\Fixer\Operator\NotOperatorWithSuccessorSpaceFixer; use PhpCsFixer\Fixer\Operator\ObjectOperatorWithoutWhitespaceFixer; @@ -81,6 +90,7 @@ use PhpCsFixer\Fixer\Phpdoc\NoBlankLinesAfterPhpdocFixer; use PhpCsFixer\Fixer\Phpdoc\NoEmptyPhpdocFixer; use PhpCsFixer\Fixer\Phpdoc\NoSuperfluousPhpdocTagsFixer; +use PhpCsFixer\Fixer\Phpdoc\PhpdocAlignFixer; use PhpCsFixer\Fixer\Phpdoc\PhpdocIndentFixer; use PhpCsFixer\Fixer\Phpdoc\PhpdocInlineTagNormalizerFixer; use PhpCsFixer\Fixer\Phpdoc\PhpdocNoAccessFixer; @@ -100,6 +110,8 @@ use PhpCsFixer\Fixer\PhpTag\FullOpeningTagFixer; use PhpCsFixer\Fixer\PhpTag\LinebreakAfterOpeningTagFixer; use PhpCsFixer\Fixer\PhpTag\NoClosingTagFixer; +use PhpCsFixer\Fixer\PhpUnit\PhpUnitMethodCasingFixer; +use PhpCsFixer\Fixer\PhpUnit\PhpUnitSetUpTearDownVisibilityFixer; use PhpCsFixer\Fixer\ReturnNotation\NoUselessReturnFixer; use PhpCsFixer\Fixer\ReturnNotation\SimplifiedNullReturnFixer; use PhpCsFixer\Fixer\Semicolon\MultilineWhitespaceBeforeSemicolonsFixer; @@ -111,17 +123,19 @@ use PhpCsFixer\Fixer\StringNotation\SingleQuoteFixer; use PhpCsFixer\Fixer\Whitespace\ArrayIndentationFixer; use PhpCsFixer\Fixer\Whitespace\BlankLineBeforeStatementFixer; -use PhpCsFixer\Fixer\Whitespace\CompactNullableTypehintFixer; +use PhpCsFixer\Fixer\Whitespace\BlankLineBetweenImportGroupsFixer; +use PhpCsFixer\Fixer\Whitespace\CompactNullableTypeDeclarationFixer; use PhpCsFixer\Fixer\Whitespace\IndentationTypeFixer; use PhpCsFixer\Fixer\Whitespace\LineEndingFixer; use PhpCsFixer\Fixer\Whitespace\MethodChainingIndentationFixer; use PhpCsFixer\Fixer\Whitespace\NoExtraBlankLinesFixer; use PhpCsFixer\Fixer\Whitespace\NoSpacesAroundOffsetFixer; -use PhpCsFixer\Fixer\Whitespace\NoSpacesInsideParenthesisFixer; use PhpCsFixer\Fixer\Whitespace\NoTrailingWhitespaceFixer; use PhpCsFixer\Fixer\Whitespace\NoWhitespaceInBlankLineFixer; use PhpCsFixer\Fixer\Whitespace\SingleBlankLineAtEofFixer; +use PhpCsFixer\Fixer\Whitespace\SpacesInsideParenthesesFixer; use PhpCsFixer\Fixer\Whitespace\StatementIndentationFixer; +use PhpCsFixer\Fixer\Whitespace\TypeDeclarationSpacesFixer; use PhpCsFixer\Fixer\Whitespace\TypesSpacesFixer; use Symplify\EasyCodingStandard\Config\ECSConfig; @@ -129,25 +143,25 @@ * Ruleset converted from Laravel Pint * @see https://github.com/laravel/pint/blob/main/resources/presets/laravel.php * Rule order should be kept alphabetical - * Note: does not include Laravel's custom LaravelPhpdocAlignmentFixer + * Note: Pint replaces phpdoc_align with its custom LaravelPhpdocAlignmentFixer at runtime; here the stock PhpdocAlignFixer is used */ return ECSConfig::configure() ->withRules([ ArrayIndentationFixer::class, BlankLineAfterNamespaceFixer::class, BlankLineAfterOpeningTagFixer::class, + BlankLineBetweenImportGroupsFixer::class, + BlankLinesBeforeNamespaceFixer::class, CastSpacesFixer::class, CleanNamespaceFixer::class, - CompactNullableTypehintFixer::class, + CompactNullableTypeDeclarationFixer::class, ControlStructureBracesFixer::class, DeclareEqualNormalizeFixer::class, DeclareParenthesesFixer::class, ElseifFixer::class, EncodingFixer::class, FullOpeningTagFixer::class, - FullyQualifiedStrictTypesFixer::class, FunctionDeclarationFixer::class, - FunctionTypehintSpaceFixer::class, GeneralPhpdocTagRenameFixer::class, HeredocToNowdocFixer::class, IncludeFixer::class, @@ -160,10 +174,11 @@ LowercaseCastFixer::class, LowercaseKeywordsFixer::class, LowercaseStaticReferenceFixer::class, - MagicMethodCasingFixer::class, MagicConstantCasingFixer::class, + MagicMethodCasingFixer::class, + MethodChainingIndentationFixer::class, NativeFunctionCasingFixer::class, - NativeFunctionTypeDeclarationCasingFixer::class, + NativeTypeDeclarationCasingFixer::class, NoAliasFunctionsFixer::class, NoAliasLanguageConstructCallFixer::class, NoAlternativeSyntaxFixer::class, @@ -173,20 +188,19 @@ NoClosingTagFixer::class, NoEmptyPhpdocFixer::class, NoEmptyStatementFixer::class, - MethodChainingIndentationFixer::class, + NoLeadingImportSlashFixer::class, + NoLeadingNamespaceWhitespaceFixer::class, NoMultilineWhitespaceAroundDoubleArrowFixer::class, NoMultipleStatementsPerLineFixer::class, NoShortBoolCastFixer::class, NoSinglelineWhitespaceBeforeSemicolonsFixer::class, - NoSpacesAfterFunctionNameFixer::class, NoSpaceAroundDoubleColonFixer::class, - NoLeadingImportSlashFixer::class, - NoLeadingNamespaceWhitespaceFixer::class, - NoSpacesInsideParenthesisFixer::class, + NoSpacesAfterFunctionNameFixer::class, NoTrailingCommaInSinglelineFixer::class, NoTrailingWhitespaceFixer::class, NoTrailingWhitespaceInCommentFixer::class, - NoUnneededCurlyBracesFixer::class, + NoUnneededBracesFixer::class, + NoUnneededImportAliasFixer::class, NoUnreachableDefaultArgumentValueFixer::class, NoUnsetCastFixer::class, NoUnusedImportsFixer::class, @@ -195,7 +209,12 @@ NoWhitespaceInBlankLineFixer::class, NormalizeIndexBraceFixer::class, NotOperatorWithSuccessorSpaceFixer::class, + NullableTypeDeclarationFixer::class, + NullableTypeDeclarationForDefaultNullValueFixer::class, ObjectOperatorWithoutWhitespaceFixer::class, + OrderedInterfacesFixer::class, + OrderedTraitsFixer::class, + PhpUnitSetUpTearDownVisibilityFixer::class, PhpdocIndentFixer::class, PhpdocInlineTagNormalizerFixer::class, PhpdocNoAccessFixer::class, @@ -209,20 +228,24 @@ SelfStaticAccessorFixer::class, ShortScalarCastFixer::class, SingleBlankLineAtEofFixer::class, - SingleBlankLineBeforeNamespaceFixer::class, SingleImportPerStatementFixer::class, SingleLineAfterImportsFixer::class, + SingleLineCommentSpacingFixer::class, + SingleLineEmptyBodyFixer::class, SingleQuoteFixer::class, SingleSpaceAroundConstructFixer::class, SpaceAfterSemicolonFixer::class, + SpacesInsideParenthesesFixer::class, StandardizeNotEqualsFixer::class, + StatementIndentationFixer::class, SwitchCaseSemicolonToColonFixer::class, SwitchCaseSpaceFixer::class, TernaryOperatorSpacesFixer::class, - WhitespaceAfterCommaInArrayFixer::class, TrimArraySpacesFixer::class, + TypeDeclarationSpacesFixer::class, TypesSpacesFixer::class, UnaryOperatorSpacesFixer::class, + WhitespaceAfterCommaInArrayFixer::class, ]) ->withConfiguredRule(ArraySyntaxFixer::class, [ 'syntax' => 'short', @@ -233,6 +256,15 @@ ->withConfiguredRule(BlankLineBeforeStatementFixer::class, [ 'statements' => ['continue', 'return'], ]) + ->withConfiguredRule(BracesPositionFixer::class, [ + 'control_structures_opening_brace' => 'same_line', + 'functions_opening_brace' => 'next_line_unless_newline_at_signature_end', + 'anonymous_functions_opening_brace' => 'same_line', + 'classes_opening_brace' => 'next_line_unless_newline_at_signature_end', + 'anonymous_classes_opening_brace' => 'next_line_unless_newline_at_signature_end', + 'allow_single_line_empty_anonymous_classes' => false, + 'allow_single_line_anonymous_functions' => false, + ]) ->withConfiguredRule(ClassAttributesSeparationFixer::class, [ 'elements' => [ 'const' => 'one', @@ -255,14 +287,50 @@ ->withConfiguredRule(ControlStructureContinuationPositionFixer::class, [ 'position' => 'same_line', ]) - ->withConfiguredRule(CurlyBracesPositionFixer::class, [ - 'control_structures_opening_brace' => 'same_line', - 'functions_opening_brace' => 'next_line_unless_newline_at_signature_end', - 'anonymous_functions_opening_brace' => 'same_line', - 'classes_opening_brace' => 'next_line_unless_newline_at_signature_end', - 'anonymous_classes_opening_brace' => 'next_line_unless_newline_at_signature_end', - 'allow_single_line_empty_anonymous_classes' => false, - 'allow_single_line_anonymous_functions' => false, + ->withConfiguredRule(FullyQualifiedStrictTypesFixer::class, [ + 'import_symbols' => true, + 'phpdoc_tags' => [ + 'param', + 'phpstan-param', + 'phpstan-property', + 'phpstan-property-read', + 'phpstan-property-write', + 'phpstan-return', + 'phpstan-var', + 'property', + 'property-read', + 'property-write', + 'psalm-param', + 'psalm-property', + 'psalm-property-read', + 'psalm-property-write', + 'psalm-return', + 'psalm-var', + 'return', + 'see', + 'throws', + 'var', + 'extends', + 'implements', + 'use', + 'phpstan-extends', + 'phpstan-implements', + 'phpstan-use', + 'psalm-extends', + 'psalm-implements', + 'psalm-use', + 'mixin', + 'param-out', + 'param-closure-this', + 'phpstan-param-out', + 'phpstan-assert', + 'phpstan-assert-if-true', + 'phpstan-assert-if-false', + 'phpstan-self-out', + 'phpstan-this-out', + 'phpstan-require-extends', + 'phpstan-require-implements', + ], ]) ->withConfiguredRule(IncrementStyleFixer::class, [ 'style' => 'post', @@ -270,9 +338,16 @@ ->withConfiguredRule(MethodArgumentSpaceFixer::class, [ 'on_multiline' => 'ignore', ]) + ->withConfiguredRule(ModifierKeywordsFixer::class, [ + 'elements' => ['method', 'property'], + ]) ->withConfiguredRule(MultilineWhitespaceBeforeSemicolonsFixer::class, [ 'strategy' => 'no_multi_line', ]) + ->withConfiguredRule(NewWithParenthesesFixer::class, [ + 'named_class' => false, + 'anonymous_class' => false, + ]) ->withConfiguredRule(NoExtraBlankLinesFixer::class, [ 'tokens' => ['extra', 'throw', 'use'], ]) @@ -291,6 +366,16 @@ ]) ->withConfiguredRule(OrderedImportsFixer::class, [ 'sort_algorithm' => 'alpha', + 'imports_order' => ['const', 'class', 'function'], + ]) + ->withConfiguredRule(PhpUnitMethodCasingFixer::class, [ + 'case' => 'snake_case', + ]) + ->withConfiguredRule(PhpdocAlignFixer::class, [ + 'align' => 'left', + 'spacing' => [ + 'param' => 2, + ], ]) ->withConfiguredRule(PhpdocOrderFixer::class, [ 'order' => ['param', 'return', 'throws'], @@ -315,28 +400,24 @@ ->withConfiguredRule(SingleClassElementPerStatementFixer::class, [ 'elements' => ['const', 'property'], ]) + ->withConfiguredRule(SingleLineCommentStyleFixer::class, [ + 'comment_types' => ['hash'], + ]) ->withConfiguredRule(TrailingCommaInMultilineFixer::class, [ 'elements' => ['arrays'], ]) - ->withConfiguredRule(VisibilityRequiredFixer::class, [ - 'elements' => ['method', 'property'], + ->withConfiguredRule(YodaStyleFixer::class, [ + 'always_move_variable' => false, + 'equal' => false, + 'identical' => false, + 'less_and_greater' => false, ]) - // any rules marked as 'false' are skipped + // any rules marked as 'false' in the Pint preset are skipped ->withSkip([ PhpdocSummaryFixer::class, PhpdocToCommentFixer::class, PsrAutoloadingFixer::class, SelfAccessorFixer::class, SimplifiedNullReturnFixer::class, - StatementIndentationFixer::class, - // App\Factories\ConfigurationFactory::$notName - '_ide_helper*.php', - '.phpstorm.meta.php', - '*.blade.php', - // App\Factories\ConfigurationFactory::$exclude - __DIR__ . 'bootstrap/cache', - __DIR__ . 'build', - __DIR__ . 'node_modules', - __DIR__ . 'storage', ]); diff --git a/src/DependencyInjection/ServiceContainerFactory.php b/src/DependencyInjection/ServiceContainerFactory.php index 97fbd4b3bc..606df86cee 100644 --- a/src/DependencyInjection/ServiceContainerFactory.php +++ b/src/DependencyInjection/ServiceContainerFactory.php @@ -25,6 +25,8 @@ final class ServiceContainerFactory */ public function create(array $configFiles = []): ECSConfig { + SimpleParameterProvider::reset(); + $this->loadPHPCodeSnifferConstants(); $ecsConfig = new ECSConfig(); diff --git a/src/DependencyInjection/SimpleParameterProvider.php b/src/DependencyInjection/SimpleParameterProvider.php index f18724e8a1..8624df4a20 100644 --- a/src/DependencyInjection/SimpleParameterProvider.php +++ b/src/DependencyInjection/SimpleParameterProvider.php @@ -13,6 +13,11 @@ final class SimpleParameterProvider */ private static array $parameters = []; + public static function reset(): void + { + self::$parameters = []; + } + public static function addParameter(string $key, mixed $value): void { if (is_array($value)) { diff --git a/tests/Set/Laravel/Fixture/fixture.php.inc b/tests/Set/Laravel/Fixture/fixture.php.inc new file mode 100644 index 0000000000..af45a4e7dd --- /dev/null +++ b/tests/Set/Laravel/Fixture/fixture.php.inc @@ -0,0 +1,26 @@ +doTestFile($filePath); + } + + public static function provideData(): Iterator + { + return self::yieldFiles(__DIR__ . '/Fixture'); + } + + public function provideConfig(): string + { + return SetList::LARAVEL; + } +}