PHPCSとJenkinsでコードレビューの負担をちょっとだけ軽くしたい

#いつもの
こんにちは。
[CYBIRDエンジニア Advent Calendar 2014](http://qiita.com/advent-calendar/2014/cybird)の19日目は、[khironori](http://qiita.com/khironori)です。
もういつの間にか４年くらいWEBエンジニアをしています。 

昨日は、[doidoidon](http://qiita.com/doidoidon)さんの[はじめてのPromise](http://qiita.com/doidoidon/items/fdc32896319f487993f3)でした。
タイトルは貸金会社のキャッチコピーをもじったのでしょか。
ネーミングセンスに脱帽ですね。

STAR WARS Episode VII の予告↓↓
https://www.youtube.com/watch?v=hnNfulu3Vp4
来年2015年のアドベントカレンダーの時期にはエピソード７が公開されるんですねー。
もう今から楽しみです。

#本題
Jenkinsと組み合わせて、コーディング規約チェック（phpcs）を自動化してみた。

#背景
今やっているプロジェクトでは、GithubのPullRequestを利用してPHPのコードレビューをしているのですが、結構活発に開発していたり、一人で複数人をレビューしているとレビュアーの負担が増えるものですよね。

で、phpcsをレビューの前に実行して、コーディング規約チェックだけでもレビューする手間を省きたいなーと。しかも、コーディング規約って細かいところまで覚えられないし！
ってことでコードレビューの前に、Jenkinsでphpcsを走らせてみました。

#プルリクまでの流れ
その前に、現状のプルリクまでの流れを簡単に説明します。

GithubのfeatureブランチにPushしたら、
JenkinsでPushをフックして
Jenkinsサーバ上にGithubから対象のブランチのソースをプルし、
ユニットテストをし、
OKならばプルリクするという流れにしています。

そこで、プルリクの前にphpcsを挟んでコーディング規約チェックをしたい！

#phpcs(PHP_CodeSniffer)の準備
phpcsのインストールは、検索すればたくさん出てくるのでそちらをみてください。また、phpcsには、コーディング規約の設定ができるので、開発環境に合った[コーディング規約を設定](http://pear.php.net/manual/ja/package.php.php-codesniffer.usage.php)してください。

ちなみに今のプロジェクトではフレームワークにFuelPHPを使っているので、FuelPHPを設定しています。

#phpcsの問題
phpcsを使ったことがある方ならわかると思いますが、
phpcsをそのまま下記の様に実行したとすると、

```
phpcs --standard=FuelPHP --extensions=php /home/USER/fuel/app/
```
「めちゃくちゃ時間がかかる」
そして
「エラーやワーニングの数が多すぎて修正する気が起きない。」
といった問題に突き当たります。。。

普通に実行すると数千件とかエラーが出ていました。。。

ということで、これを解決するために、ごにょごにょしてみました。

#phpcsの実行対象ファイルを減らす
そもそも、phpcsの実行対象のファイルが多すぎるので、必要なディレクトリのみ指定しましょう。（当たり前ですが。）
また、オプションに --ignore を付けることでディレクトリやファイルを除外することができます。カンマ区切りで複数指定可能でした。

```
# 例）
PATHS="PATH_A PATH_B PATH_C"

for PATH in ${PATHS}
do
    phpcs --standard=FuelPHP --ignore=HOGE,FUGA,HOGEHOGE.php --extensions=php /home/USER/fuel/app/${PATH}
done
```

これでだいぶ実行時間が縮小され、余計？なファイルやディレクトリからのエラーをけすことができたかなと思います。

がしかし、実行結果を見てみると、
このエラーは、ルール厳しすぎない？
とか、このメソッド名はエラーと判定したくない。
みたいなのがまだまだ残ります。

↑これもなんとかしたい。

#Jenkinsのプラグイン「Log Parser Plugin」
上の問題を解決するためには、phpcsのコーディング規約をカスタマイズする方法があるのですが、
なかなか面倒なので、Log Parser Pluginを使ってみました。

 [Log Parser Plugin](https://wiki.jenkins-ci.org/display/JENKINS/Log+Parser+Plugin) を簡単に説明すると、出力結果を行単位で正規表現で判定して ok, info, warning, error に振り分けて、それによってビルドを失敗に分類できるプラグインです。

例えば、ジョブをビルドして下記のような出力結果が出て、ビルドが成功したとしましょう。

```
Hello world.
Hello tokyo.
```

だけど、どうしても出力結果に tokyo が入っている場合はエラーと見なしたい！
って時に、この行に書いてある tokyo を正規表現で指定して error に振り分けてしまえば、
このJenkinsのジョブを失敗と判断してくれるというわけです。

#ジョブの成功失敗を Log Parser Plugin で判定
ジョブの成功失敗を Log Parser Plugin にまかせるために、
phpcsが失敗したとしてもジョブを成功させる必要があります。

```
# 例）
PATHS="PATH_A PATH_B PATH_C"

for PATH in ${PATHS}
do
    phpcs --standard=FuelPHP --ignore=HOGE,FUGA,HOGEHOGE.php --extensions=php /home/USER/fuel/app/${PATH} || true
done
```

phpcs の後ろに || true が付きました。

これでphpcsでエラーと判定されても、上記スクリプト自体はエラーを返さなくなるため、phpcsの実行結果をLog Parser Pluginで判定して、ジョブを失敗か成功か判別できるって段取りです。

#Log Parser Pluginの使い方
■ まず、JenkinsにLog Parser Plugin をインストールします。
*Jenkinsの管理 > プラグインの管理 >  利用可能*
から Log Parser Plugin を選択してインストールします。

■ 次に、正規表現を記述するファイルを作成します。
今回は、log-parserプラグインのディレクトリの下に下記の様に作成しました。

```
/var/lib/jenkins/plugins/log-parser/parsing_rules/phpcs.txt
```

phpcs.txtファイルには

```
info /methodName/
info /hoge/
info /fuga/
...
error /Error/
```

とします。

１行目のように記述することによって、methodName でphpcsがコーディング規約エラーと判定しても、Log Parser Plugin が info とみなすので、それが原因でジョブが失敗することはありません。

■ そして、*Jenkinsの管理 > システムの設定* から Console Output Parsing の項目を入力します。

![スクリーンショット 2014-12-17 23.11.45.png](https://qiita-image-store.s3.amazonaws.com/0/61883/e9bc38c6-0fe8-7f8a-437d-eca77fe5c06a.png)

■ 最後に、ジョブを作成します。
ビルドのジョブをこんな感じでつくり、

![スクリーンショット 2014-12-18 15.13.43.png](https://qiita-image-store.s3.amazonaws.com/0/61883/e4426a0a-4bc4-56c5-1639-22c0e141f6bf.png)

ビルド後の処理の項目を下記のように設定してビルドしてみます。

![スクリーンショット 2014-12-17 23.18.47.png](https://qiita-image-store.s3.amazonaws.com/0/61883/f7553eaa-8079-02d7-d26e-02971c002635.png)

■結果確認
![スクリーンショット 2014-12-18 13.27.27.png](https://qiita-image-store.s3.amazonaws.com/0/61883/fdc9864f-9bc0-d47f-7714-1241148da7bf.png)

するとこんな感じで表示されます。
青いところが、phpcsではエラーと判定されたけど、Log Parser Plugin では info と見なしたところ、
赤いところが、エラーと判定されたところ、です！

#まとめ
phpcsとJenkinsとLog Parser Pluginを組み合わせると、コーディング規約チェックがある程度自動化することができました。レビューの際に、レビュアーがコーディング規約を意識しなくてもよい環境がつくれたかなーと思います。

phpcsのコーディング規約をカスタマイズする方法もあるですが、規約からの引き算だけなら、こちらの方が楽かなと思います。除外したいルールを探すのが手間だったりするので。。。

あと、この方法は、phpmdとかにも応用できます。

だいぶ長々書いてしまいましたが、誰かの参考になれば幸いです。

#おわり
明日は、Cybirdのカビゴン[＠MiuraKatsu](http://qiita.com/MiuraKatsu)さんです！
どんな内容なのでしょうか？まだ決まってないのでしょうか？？お楽しみに！