junstyle / vscode-php-cs-fixer

PHP CS Fixer extension for VS Code
https://marketplace.visualstudio.com/items?itemName=junstyle.php-cs-fixer
MIT License
357 stars 45 forks source link

The result of VS Code formatter vs cli - differs with same config file #195

Open palansher opened 1 year ago

palansher commented 1 year ago

Good day!

Thank you for great extension!

The problem:

I get different results for formatting. Maybe extension does not pay attention to rulesets in the provided config file ?

For example, in such cli I get correct results:

vendor/friendsofphp/php-cs-fixer/php-cs-fixer fix --config=.php-cs-fixer.php --allow-risky=yes --dry-run --diff "/file-path"

image

But in VS Code (formatting, ) I got less rules applied for the same PHP file.. i.e. after formatting in VSCODE (and saving file, for sure), the CLI version founds to format something more (extra).

Is it known feature/bug? Is it possible to get same result with same config file for CLI and VSCODE extension methods?

If you interested, I can provide some example PHP file.

The Environment is:

VS Code config settings are (workspace):

"php-cs-fixer.executablePath": "${workspaceRoot}/vendor/friendsofphp/php-cs-fixer/php-cs-fixer",
"php-cs-fixer.config": ".php-cs-fixer.php",
"php-cs-fixer.toolPath": "${workspaceRoot}/vendor/friendsofphp/php-cs-fixer/php-cs-fixer",
"php-cs-fixer.formatHtml": true,
"php-cs-fixer.allowRisky": true,
"php-cs-fixer.autoFixByBracket": false,

php cs fixer ext ver: v0.3.8 PHP CS Fixer 3.13.1 Oliva by Fabien Potencier and Dariusz Ruminski. PHP runtime: 8.1.13 ubuntu 20.04 vscode ver: 1.74.2

.php-cs-fixer.php in workspace root:

<?php

declare(strict_types=1);

return
    (new PhpCsFixer\Config())
        ->setCacheFile(__DIR__ . '/var/cache/.php_cs')
        ->setFinder(
            PhpCsFixer\Finder::create()
                ->in([
                    __DIR__ . '/bin',
                    __DIR__ . '/config',
                    __DIR__ . '/public',
                    __DIR__ . '/service',
                    __DIR__ . '/src',
                    __DIR__ . '/test',
                    __DIR__ . '/tests',
                ])
                ->append([
                    __FILE__,
                ])
        )
        ->setRules([
            '@PSR12' => true,
            // '@PSR12:risky' => true,
            '@DoctrineAnnotation' => true,
            '@PHP80Migration' => true,
            // '@PHP80Migration:risky' => true,
            // '@PHPUnit84Migration:risky' => true,
            '@PhpCsFixer' => true,
            // '@PhpCsFixer:risky' => true,
            'psr_autoloading' => [
                'dir' => 'src/'
            ],

            'ordered_imports' => ['imports_order' => ['class', 'function', 'const']], // Импорт отсортирован по типам

            'concat_space' => ['spacing' => 'one'], // пробел вокруг точки при конкатенации
            'cast_spaces' => ['space' => 'none'], // без пробела после кастинга типов переменных
            // без пробелов вокруг бинарных операторов, чтобы не раздвигались union типы,
            // из за странности фиксера (воспринимает как банарное ИЛИ)
            'binary_operator_spaces' => false,

            'phpdoc_to_comment' => false, // избавляет от неверноего преобразования некотороых phpoc в обычные комментарии
            'phpdoc_separation' => false, // отключено кривое выравнивание фиксером phpdoc (слишком вправо)
            'phpdoc_types_order' => ['null_adjustment' => 'always_last'], // null всегда справа для объединенных типов phpdoc
            'phpdoc_align' => false,

            'operator_linebreak' => false, // отключение переносов при многострочных IF

            'global_namespace_import' => true,  // автоматический импорт exceptios и всего прочего в use (без слеша в коде)

            /* отключаем - новая строка перед return и пр
            или можно перечислисть список statements для которых правило будет работать */
            'blank_line_before_statement' => false,
            'multiline_whitespace_before_semicolons' => ['strategy' => 'no_multi_line'], // не переносить ; на новую строку

            'fopen_flags' => ['b_mode' => true],  // работа с файлами автоматически в бинарном режиме

            /** юнит тесты */
            'php_unit_strict' => false, // отключение strict type в юнит тестах (self::assertEquals/ self::assertSame )
            'php_unit_test_class_requires_covers' => false,  // отключаем covers анностацию
            'php_unit_test_case_static_method_calls' => ['call_type' => 'self'], // static instead of self в тестах

            'yoda_style' => false,

            // 'final_class' => true,
            'final_public_method_for_abstract_class' => true,
            'self_static_accessor' => true,

            // 'static_lambda' => true,

            // my
            // 'strict_comparison' => true,
        ]);
palansher commented 1 year ago

And yes, vs code extension output has nothing suspicious if I "format current file":

[
  "fix",
  "--using-cache=no",
  "--format=json",
  "--config=/home/vladp/dev/gtdev-advert/.php-cs-fixer.php",
  "--allow-risky=yes",
  "--path-mode=override",
  "/tmp/pcf-tmp0.7450716497125385/FrontController.php"
]
{"files":[],"time":{"total":0.031},"memory":16}
Loaded config default from "/home/vladp/dev/gtdev-advert/.php-cs-fixer.php".
Paths from configuration file have been overridden by paths provided as command arguments.
AryaSvitkona commented 5 months ago

Dear @palansher Did you solve this problem? I can confirm, that the CLI and the extension use the same config File which is placed in my project root folder and named .php-cs-fixer.php.

We use @PSR12 standard but position_after_functions_and_oop_constructsat the same line. Looks like it uses only @PSR12 without our adjustments.

<?php

use PhpCsFixer\Config;
use PhpCsFixer\Finder;

$finder = Finder::create()
    ->in([
        __DIR__ . '/app',
        __DIR__ . '/config',
        __DIR__ . '/database',
        __DIR__ . '/resources',
        __DIR__ . '/routes',
        __DIR__ . '/tests',
    ])
    ->name('*.php')
    ->notName('*.blade.php')
    ->ignoreDotFiles(true)
    ->ignoreVCS(true);

return (new Config('Extranet Laravel Rules'))
    ->setRules([
        '@PSR12' => true,
        'braces' => [
            'position_after_functions_and_oop_constructs' => 'same',
        ]
    ])
    ->setFinder($finder)
    ->setRiskyAllowed(true)
    ->setUsingCache(true);
palansher commented 5 months ago

Hello, Stefano!

Did you solve this problem?

Unfortunately, I was not.

Thank you for your example. Maybe author will pay attention to provided details.

AryaSvitkona commented 5 months ago

Well I think I possibly found the issue. If I'm using the friends-of-php/cs-fixer v 2.x (due some project restrictions to PHP 7.4) everything worked and after using the VSCode Extension with "build in" cs-fixer binary, my configuration was not correctly applied.

Id turned out, that the cs-fixer versions where different and so the name of some deprecated rule names. Thats why it applied the PSR12 rules but not those for the braces on the same line.

Maybe you can check that for yourself again :)

palansher commented 5 months ago

If I'm using the friends-of-php/cs-fixer v 2.x (due some project restrictions to PHP 7.4) everything worked

Great! You gave a hope. I will record that.

Now after two years, I am focused on DevOps and currently even have no PHP environment to check :) Excuse me, my friend. I will surely use your experience when return to the dev community.

AryaSvitkona commented 5 months ago

Just to clear up any ambiguities. The problem could be that a different php-cs-fixer version is used in the extension than the one installed in the /vendor/ folder. The extension comes with its own php-cs-fixer version.

Thanks for the feedback and in this case good luck for the future :)