CodeSniffer

コミット時にWordPressコーディング規約に自動的に準拠させる方法

GitにはGitフックという仕組みがあります。
Git Documentation 8.3より

Gitのカスタマイズ ー Git フック
Gitにも特定のアクションが発生した時にカスタムスクリプトを叩く方法があります。

これを使って、WordPressのコーディング規約に準拠するようPHP/CSSをコミット時に自動修正します。
また、チェックにパスできない場合はコミットできないようにもなります。
コードのチェックにはPHP Code Snifferを使います。
さらに、Code Snifferが参照するWordPressのコーディング規約
WordPress-Coding-Standards
参考として、大元になるWordPressのコーディング規約集
WordPress コーディング規約 WordPress Codex 日本語版

PHP Code Snifferのインストールと設定

ローカルでPHPの実行環境が必要になりますので、インストールしておいて下さい。
WindowsでのPHP単体インストールは当サイトに記事があります。
参照:PHP7を単体でインストールする
Code Snifferをインストールします。
Composerでも行けるし、公式のGitHubにあるようにcurlwgetでダウンロードでもいいです。

ファイルを入れるだけで動かせます、binフォルダ内のphpcsを実行してバージョンを確認してみます。

$ phpcs/bin/phpcs --version

PHPCSの動作確認
別途、WordPress用のルールセットWordPress-Coding-Standardsをダウンロードしておきます。
今回はルールセットをwpcsフォルダにダウンロードしています。
このフォルダを下記コマンドでCode Snifferのinstalled_pathsに登録します。

$ phpcs/bin/phpcs --config-set installed_paths .\wpcs

コマンドラインで単体ファイルの修正とチェックを行ってみます。

$ phpcs/bin/phpcs --standard=wordpress front-page.php

PHPCSでコードをチェック
2箇所のエラーがありますね。

49行目
「次の関数はエスケープ処理を行うべきです(Codexの『データバリデーション』を参照)、’get_first_post_year’」
50行目
「関数呼び出しの閉じ括弧の後ろのスペースは禁止されています」
最後に
「マークされた1件の違反は、PHPCBFで自動修正が可能です」

50行目は自動修正が可能なようですので、CodeSnifferのphpcbfツールで修正します。

$ phpcs/bin/phpcbf --standard=wordpress front-page.php

PHPCBFにて自動修正
1カ所が修正されました。
もう一度、phpcsでチェックしてみます。
PHPCSで2回目のチェック
50行目のエラーが修正されたので、エスケープ処理がされていないエラーだけ残っています。
こちらは適切なエスケープ処理を書いてやる必要があります。
エラー処理前のコードは下図の通りです。50行目のhome_url()の直後だけ余計なスペースがあります。
また、get_first_post_year関数はfunctions.phpで定義している、年号を返す関数なのでエスケープ処理が必要です。
intvalにて整数型へキャストするようにWordPress Codexに記載があります。
PHPCSでエラーになる例

git hooksファイルの作成

先に試した修正とチェックをコミット前に行うよう、git hooksにスクリプトを書きます。
ローカルリポジトリの.git/hooks/にサンプルがあります。
中身はシェルスクリプトです。簡単に使い方など書いてあります。
githooksのフォルダ
ファイル名から.sampleを削除すると、該当するgitの処理が走る時に実行されます。
今回、pre-commitとして、このようなスクリプトを配置します。

#!/bin/sh
IS_ERROR=0
# コミットされるファイルのうち、.phpかcssで終わるもの
FILES=` git status --short | grep -E "^[M|A].*(.css|.php)$" | cut -c4-`
for FILE in $FILES
do
    ./phpcs/bin/phpcbf --standard=wordpress $FILE
    if ! ./phpcs/bin/phpcs --standard=wordpress $FILE ; then
        ./phpcs/bin/phpcs --standard=wordpress $FILE
        IS_ERROR=1
    else
        git add $FILE
    fi
done
exit $IS_ERROR

スクリプトの処理内容は、下記の通り。

  1. git addされたファイルから拡張子がphpかcssのファイル名を取り出す
    → FILES変数へ格納する
  2. 取り出したファイル一つずつに対し、自動修正をかける
    for FILES in $FILE do 内の処理
  3. さらに、そのファイルにCodeSnifferでチェックを行う
  4. エラーがなかったファイルは、git addでステージングし直す。
  5. エラーコードを返して終了

動作確認

git commitしてみます。
pre-commitフックはコミットメッセージを書くためのエディタが立ち上がる直前に実行されます。
githooksからPHPCSを走らせる
先ほどのように修正してチェックが実行されています。
エスケープ処理は自分で書かなくてはいけないので、エラーで終わっています。
この場合、エディタが起動しません。
SourceTreeからコミットしようとしてもこの通り。
SourceTreeからもgithooksは実行される
また、下記のように「手動で調査が必要」というアラートが出ることがあります。

Detected access of super global var $_POST, probably needs manual inspection.

手動での調査が必要なエラー
コードが規約に準拠していてもアラートが出て、エラーコード1となってしまうため、githooksでCodeSnifferが走る限りコミットできなくなります。
ルールセットの修正などで対応できるのだと思いますが、私は一度エラーメッセージを確認したらバイパスしてコミットしています。  githooksをバイパスする
gitコマンドではgit commit --no-verifyでバイパスできます。
さらにShirohanadaテーマはTravisCIでもCodeSnifferを実行するようにしています。
チェック後にテーマをビルドするので、規約違反のコードはデプロイされません。
(設定はローカルと違って、Warningは可としています)
TravisCIでのチェックログ

やってはいけないことは、できないようにしておく

例えば工場のプレス機など、プレスをするスイッチは両手で同時押しになっています。
手を挟まないように、両手が安全な位置になければ動作しない構造にしているわけです。
(それでも労働災害は、起きるときは起きる)
危険が伴う作業や現場、機械には、さまざまな安全装置があり原則があります。
有名なところでは「フェイル・セーフ」という原則があります。
例えば鉄道はブレーキの信号線が断線すると自動的に非常ブレーキがかかります。
安全に関わる原則の内「やってはいけないことは、できなくしておく」ことは「フール・プルーフ」という原則に含まれます。
私はデスクワークやコーディングも、このような原則を積極的に取り入れるべきだと思います。
今回紹介したように、コミット時とビルド時に自動修正をかけた上でチェックする仕組みを整えておけば、コーディング規約に準拠するコードだけがコミットされていきます。
こういった「安全確認」は本来やりたいこと、やるべきことに対する付随作業です。
また、コーディング規約の準拠は、手作業でやるには煩雑で、目視では間違えやすいところです。
たった一つの丸括弧の後ろの空白を、手作業で探すのは非現実的ではないでしょうか。
なので、機械に任せてしまう方が楽で確実です。

参考

gitのpre-commit hookを使って、綺麗なPHPファイルしかコミットできないようにする MANA-DOT
フェイルセーフとフールプルーフ~意味の違いと事例 レジリエントメディカル より安全な医療システムを実現する