こちらはJoolen Advent Calendar 2019 8日目の記事です。
カレンダーのURLはこちら
Joolen Advent Calendar 2019
まえがき
PHPを書いてるとコーディング規約とか守らない人出てきますよね。
私も気付かず破ってしまうことがあります。
それを防ぐためにPHP-CS-FixerとGitフックを利用して治安保持を目指します。
PHP-CS-Fixerとは
コードの整形ツールと呼ばれるものです。
.php_cs.distという設定ファイルにルールを記述することで、コマンド一つでルールに沿ったコードに整形してくれます。
ルールはPHPの配列形式で設定します。
またFinderと呼ばれるものもあり、こちらを設定すると、整形して欲しくないファイルやディレクトリを指定できます。
例:
return PhpCsFixer\Config::create()
->setRiskyAllowed(true)
->setRules([
...
'array_syntax' => ['syntax' => 'short'], // 配列の書き方を'short'にする
...
])
->setFinder(PhpCsFixer\Finder::create()
->exclude('vendor')
->in(__DIR__)
);
実行結果
- $arrRet = array();
+ $arrRet = [];
同じようなツールにPHP_CodeSnifferというツールもあります。
こちらはphpcs.xmlという設定ファイルに記述する形式になります。
こちらに関しては今回は触れません。
Git フックとは
Gitには発生したアクションに応じてスクリプトを実行する仕組みがあります。
これがGit フックです。
実行するスクリプトはGitディレクトリ(普通は.git)内のhooks/フック名をファイル名にした状態で格納されます。(.git/hooks/pre-commit等)
フックはクライアントサイドフックとサーバーサイドフックの2グループに分けられます。
公式ドキュメント
pre-commit
やcommit-msg
など多くある中で、今回はpre-commit
フックを使用します。
pre-commit
- コミットメッセージが入力される前に実行されます。
- このフックがゼロでない値を返すと、コミットが中断されます。
- この検査は git commit --no-verify で飛ばすこともできます。
- ここではコーディングスタイルの検査(lintを実行するなど)や、行末の空白文字の検査(デフォルトのフックがまさにそうです)、新しく追加されたメソッドのドキュメントが正しいかどうかの検査といったことが可能です。
PHP-CS-Fixerのインストール
composerを利用してインストールします。
$ composer require --dev friendsofphp/php-cs-fixer
...
$ vendor/bin/php-cs-fixer -V
PHP CS Fixer 2.16.1 Yellow Bird by Fabien Potencier and Dariusz Ruminski
PHP-CS-Fixerの設定を行う
早速設定をしていきたいところですが、PHP-CS-Fixerの設定を全てやっていると膨大な時間がかかります。
そこで、設定をパッケージ化して公開してくれている方がいるので、自分にあった物を見つけて利用しましょう。
私が公開しているものやhttps://github.com/suin/php-cs-fixer-rules
などありますので、探してみてください。
探して無事インストールできたら、今度は設定を少々変えていきましょう。
ほとんどのパッケージはルールが上書きできるようになっているはずです。
php-cs-fixer-configuratorを参考にして、設定を書き換えていきましょう。
整形予定の確認。 そして整形
設定が完了したら整形!
といきたいところですが、その前に整形予定を確認して、設定の間違いがないか以下のコマンドで確認しましょう。
$ vandor/bin/php-cs-fixer fix --dry-run --diff
こちらのコマンドは
fix
によって設定ファイルに沿って整形
--dry-run
オプションによって整形せず整形予定ファイルの表示
--diff
オプションによって整形内容の表示となっています。
実行して予期せぬ変更がなければ以下のコマンドで実際に整形します。
$ vandor/bin/php-cs-fixer fix
pre-commitフックでPHP-CS-Fixerを実行
PHP-CS-Fixerによる整形ができるようになったので、最初に紹介したpre-commitフックを利用して整形前のコードがコミットされないようにします。
.git/hooksディレクトリにpre-commitという名前でファイルを作成します。
$ touch .git/hooks/pre-commit
作成したファイルを修正してPHP-CS-Fixerを実行するようにします。
#!/bin/bash
# ディレクトリ定義
ROOT_DIR=$(git rev-parse --show-toplevel)
LIST=$(git diff --name-only --cached --diff-filter=AM | grep '\.php')
# php-cs-fixer
error=false
for file in $LIST
do
# --path-modeをintersectionにすることで、Finderが無視されないようにします。
$ROOT_DIR/vendor/bin/php-cs-fixer fix --path-mode=intersection --dry-run $ROOT_DIR/$file > /dev/null 2>&1
if [ $? != 0 ]; then
echo -e " please, cs fix to $ROOT_DIR/$file"
error=true
fi
done
if "${error}"; then
echo
echo -e "\033[31mCommit fail\033[m please run \"vendor/bin/php-cs-fixer fix\" command"
exit 1
fi
これで、規約を無視したコードをコミットしようとすると以下のように表示されるようになります。
please, cs fix to /path/to/invalid-file.php
Commit fail please run "vendor/bin/php-cs-fixer fix" command
これで治安保持できるようになりました!
コーディング規約にそってないコードは精神衛生上よろしくないので、駆逐していきましょう!
明日は@joolenkoyamaさんのEC-CUBE4のContainerの探検記録です。