修正した部分だけPHPの構文チェックをする仕組みを作ってみました。
構文に問題があればGithubのPull Requestにコメントされます。
この方法のよいところは既存のソースを変えることなくPHPの構文チェックの仕組みを導入できることです。
規約に沿っていないコードが大量にあり、かつテストコードがないような環境(レガシー環境)にも導入することができます。
使用したツールは以下です。
また、packsaddleのツールはRuby製ですので、Rubyが動作する環境が必要です。
サンプルとしてGithubにphp-syntax-checkというリポジトリを作成しているので参考にしてください。
以下のスクリプトをCircleCIで実行しています。
check_syntax.sh
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| #!/bin/bash
echo "Start" LIST=`git diff --name-only origin/master | grep -e '.php$'`
if [ -z "$LIST" ]; then echo "PHP file not changed." exit 0 fi
if [ -n "$CI_PULL_REQUEST" ]; then git diff --name-only origin/master \ | grep -e '.php$' \ | xargs vendor/bin/phpcs -n --standard=PSR2 --report=checkstyle \ | bundle exec checkstyle_filter-git diff origin/master \ | bundle exec saddler report \ --require saddler/reporter/github \ --reporter Saddler::Reporter::Github::PullRequestReviewComment fi
|
仕組み
以下の3つのセクションに分類されます。
- 対象のファイルを抽出
- 構文チェック
- 結果をレポート
1. 対象のファイルを抽出
以下のコマンドでmasterと差分のあるファイル名を取得します。
1
| git diff --name-only origin/master
|
さらに grepで拡張子が .phpのファイルのみ対象にします。
1
| git diff --name-only origin/master | grep -e ‘.php$'
|
2. 構文チェック
構文チェックツールは好きなものを使えます(CheckStyleフォーマットで出力できるものに限りますが)。
今回はPHP_CodeSnifferを使いました。
1
| xargs vendor/bin/phpcs -n --standard=PSR2 --report=checkstyle
|
xargs
は前のコマンドを引数でとるために必要です。
以下のコマンドでmasterとブランチの差分をチェックして、差分があるところのエラーを検知対象のエラーとしています。
1
| bundle exec checkstyle_filter-git diff origin/master
|
エラーの差分の抽出にcheckstyle_filter-gitというツールを使っています。
これは、入力として渡したCheckStyle formatの文字列から、変更した内容の部分のエラーを抽出するツールです。
例えばファイルの10行目〜15行目を変更した場合、その行で発生したエラーのみを抽出します。
3. 結果をレポート
saddlerを使って結果をGithubに通知します。
1 2 3
| bundle exec saddler report \ --require saddler/reporter/github \ --reporter Saddler::Reporter::Github::PullRequestReviewComment
|
注意点としては、PRを作っていないと通知でエラーとなります。
ですので、Pull Requestがあるかどうかをチェックするif文をいれています。
$CI_PULL_REQUEST
はCIrcleCIの変数で、Pull Requestが作られていればこの変数にURLが格納されています。
1 2 3
| if [ -n "$CI_PULL_REQUESTS" ]; then
fi
|
また、通知にはGITHUB_ACCESS_TOKEN
を発行して環境変数に登録しておく必要があります。
CircleCIの環境変数の設定については、以下を参照ください。
また、通知ではなく単に結果を出力する場合は、saddler/reporter/textを指定します。
1 2 3
| bundle exec saddler report \ --require saddler/reporter/text \ --reporter Saddler::Reporter::Text
|
以下は、出力があった場合はエラーにする例です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| RESULT=`git diff --name-only origin/master \ | grep -e '.php$' \ | xargs vendor/bin/phpcs -n --standard=custom_ruleset.xml --report=checkstyle \ | bundle exec checkstyle_filter-git diff origin/master \ | bundle exec saddler report \ --require saddler/reporter/text \ --reporter Saddler::Reporter::Text`
if [ -n "$RESULT" ]; then echo "" echo "An error has been detected,this following:" echo "$RESULT" exit 1 fi
|
その他
ファイルのエンコードがEUC-JPのソースコードに適用したところエラーとなりました。
リポジトリをフォークして対応しました。
1.1.0より使えるようになりました!
以下のように設定します。
Gemfile
1
| gem "checkstyle_filter-git", git: "https://github.com/shoyan/ruby-checkstyle_filter-git.git", branch: "implement-exec"
|
iconvでgit diffの出力結果の文字コードをEUC-JP
->UTF-8
に変換して渡せるようにしました。
1 2 3 4
| git diff --name-only origin/master \ | grep -e '.php$' \ | xargs phpcs -n --standard=custom_ruleset.xml --report=checkstyle \ | bundle exec checkstyle_filter-git exec "git diff origin/master | iconv -f EUCJP -t UTF8"
|
PRもしているので直ることに期待です。
Mergeいただきました。
サンプルとしてGithubにphp-syntax-checkというリポジトリを作成しているので参考にしてください。
関連記事
参考リンク