顯示具有 php-cs-fixer 標籤的文章。 顯示所有文章
顯示具有 php-cs-fixer 標籤的文章。 顯示所有文章

2022年8月3日 星期三

PHP 開發筆記 - 關於 CodeIgniter4 starter app / PHP Coding Standards Fixer v3.9.5 / PHP 7.4 @ macOS 與 Windows

之前初探 PHP Coding Standards Fixer (php-cs-fixer) 時,略知預設跑下去已經有一定水準的 Coding Style 制約機制,然而,工作上引導同事在使用時,碰到了一些雷區。

首先是用 CodeIgniter 4 官方文件建立出的資料後,要跑 PHP Coding Standards Fixer 時會出現要修正語法的問題

```
// https://www.codeigniter.com/user_guide/installation/installing_composer.html
% composer create-project codeigniter4/appstarter project-root
% ./vendor/bin/php-cs-fixer fix --dry-run -v .
PHP CS Fixer 3.9.5 Grand Awaiting by Fabien Potencier and Dariusz Ruminski.
PHP runtime: 7.4.30
Loaded config CodeIgniter4 Coding Standards from "/path/./.php-cs-fixer.dist.php".
Using cache file ".php-cs-fixer.cache".
Paths from configuration file have been overridden by paths provided as command arguments.
.....F......................................F.............                                                                            58 / 58 (100%)
Legend: ?-unknown, I-invalid file syntax (file ignored), S-skipped (cached or empty file), .-no changes, F-fixed, E-error
   1) app/Config/Logger.php (ordered_imports)
   2) app/Views/errors/html/error_exception.php (braces, unary_operator_spaces, not_operator_with_successor_space)

Checked all files in 1.104 seconds, 16.000 MB memory used
```

然後故意降版本到 v3.8.0 又可以正常

```
% mv composer.json composer.json-bak
% composer require friendsofphp/php-cs-fixer:3.8.0 --dev
% ./vendor/bin/php-cs-fixer fix --dry-run -v .
PHP CS Fixer 3.8.0 BerSzcz against war! by Fabien Potencier and Dariusz Ruminski.
PHP runtime: 7.4.30
Loaded config default.
Using cache file ".php-cs-fixer.cache".
..........................................................                                                                            58 / 58 (100%)
Legend: ?-unknown, I-invalid file syntax (file ignored), S-skipped (cached or empty file), .-no changes, F-fixed, E-error

Checked all files in 0.303 seconds, 14.000 MB memory used
```

為了避免未來同事不同平台開發的困局,就來安分地寫一下 .php-cs-fixer.dist.php 檔案吧!也順道研究到 CodeIgniter 也有個 CodeIgniter/coding-standard 規範,接著參考 github.com/CodeIgniter/coding-standard#setup 一步一步測試

```
% cat .php-cs-fixer.dist.php
<?php

use CodeIgniter\CodingStandard\CodeIgniter4;
use Nexus\CsConfig\Factory;

return Factory::create(new CodeIgniter4())->forProjects();

% ./vendor/bin/php-cs-fixer fix --dry-run -v .
PHP CS Fixer 3.9.5 Grand Awaiting by Fabien Potencier and Dariusz Ruminski.
PHP runtime: 7.4.30
Loaded config CodeIgniter4 Coding Standards from "/path/./.php-cs-fixer.dist.php".
Using cache file ".php-cs-fixer.cache".
Paths from configuration file have been overridden by paths provided as command arguments.
.....F......................................F.............                                                                            58 / 58 (100%)
Legend: ?-unknown, I-invalid file syntax (file ignored), S-skipped (cached or empty file), .-no changes, F-fixed, E-error
   1) app/Config/Logger.php (ordered_imports)
   2) app/Views/errors/html/error_exception.php (braces, unary_operator_spaces, not_operator_with_successor_space)

Checked all files in 1.104 seconds, 16.000 MB memory used
```

開始先找一下怎樣略過那兩個檔案的用法:

```
% cat .php-cs-fixer.dist.php
<?php
use CodeIgniter\CodingStandard\CodeIgniter4;
use Nexus\CsConfig\Factory;
use PhpCsFixer\Finder;

// https://github.com/codeigniter4/CodeIgniter4/blob/develop/.php-cs-fixer.dist.php
$finder = Finder::create()
->files()
->notPath([
'app/Config/Logger.php',
'app/Views/errors/html/error_exception.php',
]);

// https://github.com/NexusPHP/cs-config/blob/develop/src/Factory.php
//return Factory::create(new CodeIgniter4())->forProjects();
return Factory::create(new CodeIgniter4(), [], [
'finder' => $finder,
])->forProjects();

% ./vendor/bin/php-cs-fixer fix --dry-run .
Loaded config CodeIgniter4 Coding Standards from "/path/./.php-cs-fixer.dist.php".
Using cache file ".php-cs-fixer.cache".

Checked all files in 0.032 seconds, 14.000 MB memory used
```

接著去 Windows 跑:

```
C:\path>.\vendor\bin\php-cs-fixer fix --dry-run .
PHP CS Fixer 3.9.1 Grand Awaiting by Fabien Potencier and Dariusz Ruminski.
PHP runtime: 7.4.30
Loaded config CodeIgniter4 Coding Standards from "C:\path\.\.php-cs-fixer.dist.php".
Using cache file ".php-cs-fixer.cache".
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF          56 / 56 (100%)
Legend: ?-unknown, I-invalid file syntax (file ignored), S-skipped (cached or empty file), .-no changes, F-fixed, E-error

   1) app\Common.php (line_ending)
  ...
  55) tests\_support\Libraries\ConfigReader.php (line_ending)
  56) tests\_support\Models\ExampleModel.php (line_ending)

Checked all files in 1.187 seconds, 16.000 MB memory used
```

最後再加個 line_ending 來處理一下:

```
% cat .php-cs-fixer.dist.php
<?php
use CodeIgniter\CodingStandard\CodeIgniter4;
use Nexus\CsConfig\Factory;
use PhpCsFixer\Finder;

// https://github.com/codeigniter4/CodeIgniter4/blob/develop/.php-cs-fixer.dist.php
$finder = Finder::create()
->files()
->notPath([
'app/Config/Logger.php',
'app/Views/errors/html/error_exception.php',
]);

// https://github.com/NexusPHP/cs-config/blob/develop/src/Factory.php
//return Factory::create(new CodeIgniter4())->forProjects();
return Factory::create(new CodeIgniter4(), [], [
'finder' => $finder,
// https://github.com/FriendsOfPHP/PHP-CS-Fixer/issues/3955
'lineEnding' => PHP_EOL,
])->forProjects();
```

收工!

2022年6月10日 星期五

PHP 開發筆記 - 使用 PHP-CS-FIXER 維護團隊的 Coding Style

使用 PHP 語言開發網站服務時,採用各類框架後,其撰寫風格已定下八九成了,那為何還需要呢?主要用來提升產出品質。就像程式碼都能動,QA也驗證過,也上線服務百人千人了,這時有測試涵蓋率資訊,可以讓未來增減功能時,更加大膽。

稍微研究後,在 PHP 語言上,可以直接使用 PHP Coding Standards Fixer 工具,整體上還滿舒適的,裡頭有提到非常多編碼風格檢驗,基本上用預設的即可。備忘一下:

首先故意把 php-cs-fixer 安裝在程式碼上一層名為 tools 目錄,且 tools 內有 composer.phar 工具可用:

% mkdir -p tools/php-cs-fixer
% php tools/composer.phar require --working-dir=tools/php-cs-fixer friendsofphp/php-cs-fixer

先列出當前目錄中,有哪些要修改的項目:

% cd src
% ../tools/php-cs-fixer/vendor/bin/php-cs-fixer fix --dry-run --diff .

對當前目錄進行修正的用法:

% cd src
% ../tools/php-cs-fixer/vendor/bin/php-cs-fixer fix .

接著,可以把上面兩個指令包在 composer.json 中,靠 run-script 處理:

% cd src
% cat composer.json | jq '.scripts'
{
  "test": "phpunit",
  "cs-diff": "../tools/php-cs-fixer/vendor/bin/php-cs-fixer fix --dry-run --diff .",
  "cs": "../tools/php-cs-fixer/vendor/bin/php-cs-fixer fix ."
}

使用方式:

% ../tools/composer.phar run-script cs-diff
> ../tools/php-cs-fixer/vendor/bin/php-cs-fixer fix --dry-run --diff .
Loaded config default.
Using cache file ".php-cs-fixer.cache".

Checked all files in 0.032 seconds, 12.000 MB memory used

% ../tools/composer.phar run-script cs     
> ../tools/php-cs-fixer/vendor/bin/php-cs-fixer fix .
Loaded config default.
Using cache file ".php-cs-fixer.cache".

Fixed all files in 0.006 seconds, 12.000 MB memory used

接著,可以評估一下自己打算用哪些規範,從 PHP Framework Interop Group (簡稱PHP-FIG) 常見的推薦用法,就是要來個 PSR-12 就對了:

% cat test.php 
<?php

    $x                = "hello world";

     $y =            "123";

% ../tools/php-cs-fixer/vendor/bin/php-cs-fixer fix --dry-run --using-cache=no --rules=@PSR12  -vvv test.php
PHP CS Fixer 3.8.0 BerSzcz against war! by Fabien Potencier and Dariusz Ruminski.
PHP runtime: 7.4.29
Loaded config default.
.                                                                                                                           1 / 1 (100%)
Legend: ?-unknown, I-invalid file syntax (file ignored), S-skipped (cached or empty file), .-no changes, F-fixed, E-error

Checked all files in 0.005 seconds, 12.000 MB memory used

規則嚴一點,使用 Symfony framework 語法:

% ../tools/php-cs-fixer/vendor/bin/php-cs-fixer fix --dry-run --diff --using-cache=no --rules=@PSR12,@Symfony -vvv test.php 
PHP CS Fixer 3.8.0 BerSzcz against war! by Fabien Potencier and Dariusz Ruminski.
PHP runtime: 7.4.29
Loaded config default.
F                                                                                                                           1 / 1 (100%)
Legend: ?-unknown, I-invalid file syntax (file ignored), S-skipped (cached or empty file), .-no changes, F-fixed, E-error
   1) web/test.php (single_quote, binary_operator_spaces)
      ---------- begin diff ----------
--- /Volumes/Data/project/src/test.php
+++ /Volumes/Data/project/src/test.php
@@ -1,5 +1,5 @@
 <?php
 
-    $x                = "hello world";
+    $x = 'hello world';
 
-     $y =            "123";
+     $y = '123';

      ----------- end diff -----------


Checked all files in 0.011 seconds, 12.000 MB memory used

進行修正:

% ../tools/php-cs-fixer/vendor/bin/php-cs-fixer fix --using-cache=no --rules=@PSR12,@Symfony test.php
Loaded config default.
   1) web/test.php

Fixed all files in 0.011 seconds, 12.000 MB memory used

% cat test.php 
<?php

    $x = 'hello world';

     $y = '123';

更多語法修正可以參考 github.com/FriendsOfPHP/PHP-CS-Fixer/blob/master/doc/rules/index.rst 解說,例如變數運算時的空白規劃,就可以參考 binary_operator_spaces 的設計。