Developer's Blog

コードレビューを捗らせる Git フック

こんにちは、ウェブエンジニアの荷出です。

プログラマの美徳の一つに、全体の労力を減らすために手間を惜しまないというものがありますが、コードレビューもできるだけ楽してクオリティがアップできれば素敵ですよね?

ということで、この記事では「コーディング規約に準拠させてね」や「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 ページでは、最新トピックをお知らせしています。よろしければいいね!してください!

 

Copyright © 2019 Fenrir Inc. All rights reserved.