こんにちは、ウェブエンジニアの荷出です。
プログラマの美徳の一つに、全体の労力を減らすために手間を惜しまないというものがありますが、コードレビューもできるだけ楽してクオリティがアップできれば素敵ですよね?
ということで、この記事では「コーディング規約に準拠させてね」や「Doc コメント書いてくださーい」という指摘はツールに任せて、肝心なロジックに対してフォーカスできるように Git フックを使った例を紹介します。
PHP のツールを使用していますが、お使いの言語に読み替えてもらえますと幸いです。
はじめに
ところで、みなさん Git フックを、お使いでしょうか?
具体例をあまり見かけないのでご存知ない方もいらっしゃるかもしれません。
Git フックとは Git の特定のアクションが発生したタイミングでスクリプトを実行する機能です。いくつか種類があって任意のタイミンングでコミット対象ファイルに対してスクリプトを実行したり、コマンドを実行したりできます。
インストール方法はマニュアルを参照していただくとわかりますが、git init 時にサンプルスクリプトごと .git/hooks/ ディレクトリ以下に生成されるので難しいことはありません。
pre-commit を使ってコードレビューを効率化
コードレビューのためには pre-commit フックという Git フックを使います。
pre-commit フックは git commit コマンドを実行した直後、コミットメッセージを入力する前に実行されるので、コミット対象コードをチェックするために利用できます。
このフックのスクリプトが 0 以外の値を返すとコミットを中止しますので、構文エラーやコーディングスタイルチェック、ユニットテストによるデグレの検知などを commit 前にできます。
使用例
コーディング規約に沿ったコードにフォーマット
PHP_CodeSniffer を使って、PSR-2 に準拠したコードに書き換えます。
vendor/bin/phpcbf --standard=PSR2 $PHP_FILE
これで「インデントサイズが統一されてませんよ」とか「コーディング規約に準拠させてね」なんて言わなくてよくなりますね。
Doc コメントのないコードのチェック
PHP_CodeSniffer で Doc コメント無しをチェックできます。
vendor/bin/phpcs --standard=Squiz --sniffs=Squiz.Commenting.FunctionComment $PHP_FILE
これで「Doc コメント書いてくださーい」と言わなくてよくなりました。
未使用コードのチェック
PHPMD で未使用コードをチェックします。
vendor/bin/phpmd $PHP_FILE text unusedcode
PHPMD は循環的複雑度の測定などほかにも色々できるので、チームメンバーと相談しながらルールを追加していくといいと思います。
ユニットテストの実行
PHPUnit を実行してコミット前にユニットテストを通っているかのチェックができます。
vendor/bin/phpunit -c phpunit.xml
全体のコード
次のコードを .git/hooks/pre-commit ファイルの下部に追加して使用します。
VENDOR_BIN=$(git rev-parse --show-toplevel)/vendor/bin RESULT=0 for PHP_FILE in $(git diff --cached --name-only | grep -E '\.php$') do # PHP シンタックスチェック if ! php -l $PHP_FILE; then RESULT=1 else # PHPMDで未使用コードなどをチェック if ! "$VENDOR_BIN"/phpmd $PHP_FILE text unusedcode; then RESULT=1 fi # PHP_CodeSniffer で Doc Comment 無しをチェック if ! "$VENDOR_BIN"/phpcs --standard=Squiz --sniffs=Squiz.Commenting.FunctionComment $PHP_FILE; then RESULT=1 fi # PHP_CodeSniffer で PSR2準拠などでコードを書き換える "$VENDOR_BIN"/phpcbf --standard=PSR2 $PHP_FILE git add $PHP_FILE fi done if ! "$VENDOR_BIN"/phpunit -c $(git rev-parse --show-toplevel)/phpunit.xml; then RESULT=1 fi exit $RESULT
おまけ
ライブラリが追加された場合は git pull 時に post-merge フックで検知できるので、composer update を手動で実行しなくてよくなります。
.git/hooks/post-merge
#!/bin/sh for FILE in $(git diff-tree -r --name-only --no-commit-id ORIG_HEAD HEAD) do if test $FILE = "composer.json"; then composer update fi done
最後に
いかがでしたでしょうか。Git には今回ご紹介した、pre-commit や post-merge 以外にもいろんなフックが用意されています。こんな使い方をしているといったフィードバックをいただければ幸いです。ありがとうございました。
フェンリルのオフィシャル Twitter アカウントでは、フェンリルプロダクトの最新情報などをつぶやいています。よろしければフォローしてください!
フェンリルの Facebook ページでは、最新トピックをお知らせしています。よろしければいいね!してください!