LoginSignup
16
9

PHP-CS-FixerとGit フックで治安保持活動

Last updated at Posted at 2019-12-07

こちらはJoolen Advent Calendar 2019 8日目の記事です。
カレンダーのURLはこちら
Joolen Advent Calendar 2019

まえがき

PHPを書いてるとコーディング規約とか守らない人出てきますよね。
私も気付かず破ってしまうことがあります。
それを防ぐためにPHP-CS-FixerとGitフックを利用して治安保持を目指します。

PHP-CS-Fixerとは:question:

コードの整形ツールと呼ばれるものです。
.php_cs.distという設定ファイルにルールを記述することで、コマンド一つでルールに沿ったコードに整形してくれます。
ルールはPHPの配列形式で設定します。
またFinderと呼ばれるものもあり、こちらを設定すると、整形して欲しくないファイルやディレクトリを指定できます。

例:

.php_cs.dist
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 フックとは:question:

Gitには発生したアクションに応じてスクリプトを実行する仕組みがあります。
これがGit フックです。
実行するスクリプトはGitディレクトリ(普通は.git)内のhooks/フック名をファイル名にした状態で格納されます。(.git/hooks/pre-commit等)
フックはクライアントサイドフックとサーバーサイドフックの2グループに分けられます。
公式ドキュメント
pre-commitcommit-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を実行するようにします。

pre-commit
#!/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の探検記録です。

16
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
9