symplify / coding-standard

Coding Standard rules for PHP projects with focus on Clean Architecture
MIT License
347 stars 20 forks source link

How to use with php-cs-fixer without ECS #52

Closed lyrixx closed 2 months ago

lyrixx commented 2 months ago

Hello,

It would be nice a simple doc to explain how to use this packages with php-cs-fixer without ECS.

Thanks

TomasVotruba commented 2 months ago

Hey, I think that's already in php-cs-fixer docs: https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/blob/master/doc/custom_rules.rst

lyrixx commented 2 months ago

I did that, but custom rule instantiation is quite complex... There are many deps. So I hoped there is a better way than reverse engineering this package

See https://github.com/symplify/coding-standard/blob/8a14f9277b3a3be5c23654a0291005741171f765/src/Fixer/Spacing/StandaloneLineConstructorParamFixer.php#L29-L33 and so on

TomasVotruba commented 2 months ago

Use the same way it needs to be passed/created by container in php-cs-fixer. There is nothing different.

Personally, I used Laravel container to handle these.

lyrixx commented 2 months ago

Well, I did this with symfony/dependency-injection

object(Symplify\CodingStandard\Fixer\Spacing\StandaloneLineConstructorParamFixer)#2507 (2) {                                                                                                
  ["paramNewliner":"Symplify\CodingStandard\Fixer\Spacing\StandaloneLineConstructorParamFixer":private]=>                                                                                   
  object(Symplify\CodingStandard\TokenAnalyzer\ParamNewliner)#2514 (2) {                                                                                                                    
    ["blockFinder":"Symplify\CodingStandard\TokenAnalyzer\ParamNewliner":private]=>                                                                                                         
    object(Symplify\CodingStandard\TokenRunner\Analyzer\FixerAnalyzer\BlockFinder)#2542 (0) {                                                                                               
    }                                                                                                                                                                                       
    ["tokensNewliner":"Symplify\CodingStandard\TokenAnalyzer\ParamNewliner":private]=>                                                                                                      
    object(Symplify\CodingStandard\TokenRunner\Transformer\FixerTransformer\TokensNewliner)#2571 (5) {                                                                                      
      ["lineLengthCloserTransformer":"Symplify\CodingStandard\TokenRunner\Transformer\FixerTransformer\TokensNewliner":private]=>                                                           
      object(Symplify\CodingStandard\TokenRunner\Transformer\FixerTransformer\LineLengthCloserTransformer)#2554 (2) {                                                                       
        ["callAnalyzer":"Symplify\CodingStandard\TokenRunner\Transformer\FixerTransformer\LineLengthCloserTransformer":private]=>                                                           
        object(Symplify\CodingStandard\TokenRunner\Analyzer\FixerAnalyzer\CallAnalyzer)#2544 (0) {                                                                                          
        }                                                                                                                                                                                   
        ["tokenFinder":"Symplify\CodingStandard\TokenRunner\Transformer\FixerTransformer\LineLengthCloserTransformer":private]=>                                                            
        object(Symplify\CodingStandard\TokenRunner\TokenFinder)#2551 (0) {                                                                                                                  
        }                                                                                                                                                                                   
      }                                                                                                                                                                                     
      ["tokenSkipper":"Symplify\CodingStandard\TokenRunner\Transformer\FixerTransformer\TokensNewliner":private]=>                                                                          
      object(Symplify\CodingStandard\TokenRunner\Analyzer\FixerAnalyzer\TokenSkipper)#2556 (1) {                                                                                            
        ["blockFinder":"Symplify\CodingStandard\TokenRunner\Analyzer\FixerAnalyzer\TokenSkipper":private]=>                                                                                 
        object(Symplify\CodingStandard\TokenRunner\Analyzer\FixerAnalyzer\BlockFinder)#2542 (0) {                                                                                           
        }                                                                                                                                                                                   
      }                                                                                                                                                                                     
      ["lineLengthOpenerTransformer":"Symplify\CodingStandard\TokenRunner\Transformer\FixerTransformer\TokensNewliner":private]=>                                                           
      object(Symplify\CodingStandard\TokenRunner\Transformer\FixerTransformer\LineLengthOpenerTransformer)#2559 (1) {                                                                       
        ["callAnalyzer":"Symplify\CodingStandard\TokenRunner\Transformer\FixerTransformer\LineLengthOpenerTransformer":private]=>                                                           
        object(Symplify\CodingStandard\TokenRunner\Analyzer\FixerAnalyzer\CallAnalyzer)#2544 (0) {                                                                                          
        }                                                                                                                                                                                   
      }                                                                                                                                                                                     
      ["whitespacesFixerConfig":"Symplify\CodingStandard\TokenRunner\Transformer\FixerTransformer\TokensNewliner":private]=>                                                                
      object(PhpCsFixer\WhitespacesFixerConfig)#2562 (2) {                                                                                                                                  
        ["indent":"PhpCsFixer\WhitespacesFixerConfig":private]=>                                                                                                                            
        string(4) "    "                                                                                                                                                                    
        ["lineEnding":"PhpCsFixer\WhitespacesFixerConfig":private]=>                                                                                                                        
        string(1) "                                                                                                                                                                         
"                                                                                                                                                                                           
      }                                                                                                                                                                                     
      ["indentResolver":"Symplify\CodingStandard\TokenRunner\Transformer\FixerTransformer\TokensNewliner":private]=>                                                                        
      object(Symplify\CodingStandard\TokenRunner\Whitespace\IndentResolver)#2569 (2) {                                                                                                      
        ["indentDetector":"Symplify\CodingStandard\TokenRunner\Whitespace\IndentResolver":private]=>                                                                                        
        object(Symplify\CodingStandard\TokenRunner\Analyzer\FixerAnalyzer\IndentDetector)#2565 (1) {                                                                                        
          ["whitespacesFixerConfig":"Symplify\CodingStandard\TokenRunner\Analyzer\FixerAnalyzer\IndentDetector":private]=>                                                                  
          object(PhpCsFixer\WhitespacesFixerConfig)#2562 (2) {                                                                                                                              
            ["indent":"PhpCsFixer\WhitespacesFixerConfig":private]=>                                                                                                                        
            string(4) "    "                                                                                                                                                                
            ["lineEnding":"PhpCsFixer\WhitespacesFixerConfig":private]=>                                                                                                                    
            string(1) "                                                                                                                                                                     
"                                                                                                                                                                                           
          }                                                                                                                                                                                 
        }                                                                                                                                                                                   
        ["whitespacesFixerConfig":"Symplify\CodingStandard\TokenRunner\Whitespace\IndentResolver":private]=>                                                                                
        object(PhpCsFixer\WhitespacesFixerConfig)#2562 (2) {                                                                                                                                
          ["indent":"PhpCsFixer\WhitespacesFixerConfig":private]=>                                                                                                                          
          string(4) "    "                                                                                                                                                                  
          ["lineEnding":"PhpCsFixer\WhitespacesFixerConfig":private]=>                                                                                                                      
          string(1) "                                                                                                                                                                       
"                                                                                                                                                                                           
        }                                                                                                                                                                                   
      }                                                                                                                                                                                     
    }                                                                                                                                                                                       
  }                                                                                                                                                                                         
  ["methodNameResolver":"Symplify\CodingStandard\Fixer\Spacing\StandaloneLineConstructorParamFixer":private]=>                                                                              
  object(Symplify\CodingStandard\TokenAnalyzer\Naming\MethodNameResolver)#2306 (0) {                                                                                                        
  }
}

Anyway, now I get an error

    0/2108 [░░░░░░░░░░░░░░░░░░░░░░░░░░░░]   0%
In FixerFactory.php line 139:

  Fixer named "Symplify\CodingStandard\Fixer\Spacing\StandaloneLineConstructorParamFixer" has invalid name.                                               

So it looks like this packages is not compatible with php-cs-fixer

lyrixx commented 2 months ago

For other developers that need to use this packages with php-cs-fixer, I found this way:

Apply this patch to your php-cs-fixer config

diff --git a/.php-cs-fixer.php b/.php-cs-fixer.php
index c32c4fbfb2..48adc499ec 100644
--- a/.php-cs-fixer.php
+++ b/.php-cs-fixer.php
@@ -1,5 +1,10 @@
 <?php

+use Symfony\Component\Config\FileLocator;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
+use Symfony\Component\DependencyInjection\Loader\PhpFileLoader;
+
+$container = new ContainerBuilder();
+$phpLoader = new PhpFileLoader($container, new FileLocator());
+$instanceof = [];
+$configurator = new ContainerConfigurator($container, $phpLoader, $instanceof, __DIR__, __FILE__);
+$services = $configurator->services();
+$services
+    ->defaults()
+        ->autowire()
+        ->autowire()
+        ->autoconfigure()
+    ->load('Symplify\CodingStandard\\', __DIR__ . '/tools/php-cs-fixer/vendor/symplify/coding-standard/src/*')
+    ->load('PhpCsFixer\\', __DIR__ . '/tools/php-cs-fixer/vendor/friendsofphp/php-cs-fixer/src/*')
+    ->set(Symplify\CodingStandard\Fixer\Spacing\StandaloneLineConstructorParamFixer::class)
+        ->public(true)
+;
+$container->compile();
+
 return (new PhpCsFixer\Config())
     ->setRiskyAllowed(true)
     ->setParallelConfig(PhpCsFixer\Runner\Parallel\ParallelConfigFactory::detect())
+    ->registerCustomFixers([
+        $container->get(Symplify\CodingStandard\Fixer\Spacing\StandaloneLineConstructorParamFixer::class),
+    ])
     ->setRules([
         '@PHP83Migration' => true,
         '@PhpCsFixer' => true,
@@ -39,6 +64,7 @@ return (new PhpCsFixer\Config())
         'blank_line_before_statement' => true, // Symfony(PSR12) override the default value, but we don't want
         'nullable_type_declaration' => true, // Same as symfony
         'method_chaining_indentation' => false, // Do not work well with "tree builder"
+        'Foo/bar' => true,
     ])
     ->setFinder($finder)
 ;

In your composer.json

--- a/tools/php-cs-fixer/composer.json
+++ b/tools/php-cs-fixer/composer.json
@@ -1,6 +1,9 @@
 {
     "type": "project",
     "require": {
-        "friendsofphp/php-cs-fixer": "^3.59.3"
+        "friendsofphp/php-cs-fixer": "^3.59.3",
+        "symplify/coding-standard": "^12.2",
+        "symfony/dependency-injection": "^7.1",
+        "symfony/config": "^7.1"
     }
 }

An you'll have to edit the following file:

vendor/symplify/coding-standard/src/Fixer/AbstractSymplifyFixer.php

     public function getName(): string
     {
-        return static::class;
+        return 'Foo/bar';
     }

@TomasVotruba Thanks for the package 👍🏼