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にあるようにcurl
やwget
でダウンロードでもいいです。
ファイルを入れるだけで動かせます、binフォルダ内のphpcsを実行してバージョンを確認してみます。
$ phpcs/bin/phpcs --version
別途、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
49行目
「次の関数はエスケープ処理を行うべきです(Codexの『データバリデーション』を参照)、’get_first_post_year’」
50行目
「関数呼び出しの閉じ括弧の後ろのスペースは禁止されています」
最後に
「マークされた1件の違反は、PHPCBFで自動修正が可能です」
50行目は自動修正が可能なようですので、CodeSnifferのphpcbfツールで修正します。
$ phpcs/bin/phpcbf --standard=wordpress front-page.php
1カ所が修正されました。
もう一度、phpcsでチェックしてみます。
50行目のエラーが修正されたので、エスケープ処理がされていないエラーだけ残っています。
こちらは適切なエスケープ処理を書いてやる必要があります。
エラー処理前のコードは下図の通りです。50行目のhome_url()
の直後だけ余計なスペースがあります。
また、get_first_post_year関数はfunctions.phpで定義している、年号を返す関数なのでエスケープ処理が必要です。
intval
にて整数型へキャストするようにWordPress Codexに記載があります。
git hooksファイルの作成
先に試した修正とチェックをコミット前に行うよう、git hooksにスクリプトを書きます。
ローカルリポジトリの.git/hooks/
にサンプルがあります。
中身はシェルスクリプトです。簡単に使い方など書いてあります。
ファイル名から.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
スクリプトの処理内容は、下記の通り。
- git addされたファイルから拡張子がphpかcssのファイル名を取り出す
→ FILES変数へ格納する - 取り出したファイル一つずつに対し、自動修正をかける
for FILES in $FILE do
内の処理 - さらに、そのファイルにCodeSnifferでチェックを行う
- エラーがなかったファイルは、
git add
でステージングし直す。 - エラーコードを返して終了
動作確認
git commit
してみます。
pre-commitフックはコミットメッセージを書くためのエディタが立ち上がる直前に実行されます。
先ほどのように修正してチェックが実行されています。
エスケープ処理は自分で書かなくてはいけないので、エラーで終わっています。
この場合、エディタが起動しません。
SourceTreeからコミットしようとしてもこの通り。
また、下記のように「手動で調査が必要」というアラートが出ることがあります。
Detected access of super global var $_POST, probably needs manual inspection.
コードが規約に準拠していてもアラートが出て、エラーコード1となってしまうため、githooksでCodeSnifferが走る限りコミットできなくなります。
ルールセットの修正などで対応できるのだと思いますが、私は一度エラーメッセージを確認したらバイパスしてコミットしています。
gitコマンドではgit commit --no-verify
でバイパスできます。
さらにShirohanadaテーマはTravisCIでもCodeSnifferを実行するようにしています。
チェック後にテーマをビルドするので、規約違反のコードはデプロイされません。
(設定はローカルと違って、Warningは可としています)
やってはいけないことは、できないようにしておく
例えば工場のプレス機など、プレスをするスイッチは両手で同時押しになっています。
手を挟まないように、両手が安全な位置になければ動作しない構造にしているわけです。
(それでも労働災害は、起きるときは起きる)
危険が伴う作業や現場、機械には、さまざまな安全装置があり原則があります。
有名なところでは「フェイル・セーフ」という原則があります。
例えば鉄道はブレーキの信号線が断線すると自動的に非常ブレーキがかかります。
安全に関わる原則の内「やってはいけないことは、できなくしておく」ことは「フール・プルーフ」という原則に含まれます。
私はデスクワークやコーディングも、このような原則を積極的に取り入れるべきだと思います。
今回紹介したように、コミット時とビルド時に自動修正をかけた上でチェックする仕組みを整えておけば、コーディング規約に準拠するコードだけがコミットされていきます。
こういった「安全確認」は本来やりたいこと、やるべきことに対する付随作業です。
また、コーディング規約の準拠は、手作業でやるには煩雑で、目視では間違えやすいところです。
たった一つの丸括弧の後ろの空白を、手作業で探すのは非現実的ではないでしょうか。
なので、機械に任せてしまう方が楽で確実です。
参考
gitのpre-commit hookを使って、綺麗なPHPファイルしかコミットできないようにする MANA-DOT
フェイルセーフとフールプルーフ~意味の違いと事例 レジリエントメディカル より安全な医療システムを実現する