rubocop + pre-commitで規約違反のコードをコミットできないようにする


rubocopはrubyの静的コード解析を実行してくれる便利なgem。例えば、ソースコード内の残念なメソッド名を発見してくれたり、1メソッドの行数を制限できたりする。解析内容は多岐にわたるので、ぜひ公式ドキュメントを参照あれ。

一方pre-commitとは、gitコミットをフックして何らかのアクションを実行してくれるgem。末尾の空白を検知したり、Javascriptの console.logや、pryの binding.pryがソース内に残っていないかなどチェックできる。こいつが標準でrubocopもサポートしているので、これらを組み合わせると、規約違反のコードが含まれている場合に git commitできないようにすることができる。

セットアップ

bundle + railsという環境を想定すると、Gemfileは以下のようになる。

bundle installした後に、pre-commitをインストールする必要がある。

git-hookは新しいshプロセスで動くので、pre-commitはbundler経由で実行させるよう、gitの設定を施してやる必要があります。

これにて導入は完了。

pre-commit

pre-commit listコマンドで各checkの利用状況が確認できる。

Available checksが利用できるチェックの一覧。Enabledが現在利用しているチェックである。上記ではcommonとrailsというチェックがなされている。この2つのチェックに含まれる個々のチェックはEvaluated checksに記述されている。要するに、これらが実際に実行されるチェック。このあたりは公式サイトとかこのあたりを参考にしてほしい。

デフォルトではrubocopを利用するようにはなっていないので、設定を変更しよう。

yamlと指定しているのは、設定をyamlファイルに書き出すということ。railsディレクトリ内で実行すると、config/pre_commit.ymlというファイルが出来上がっているはずだ。

今後はこのファイルを直接編集してもよい。ちなみに、先の yamlと指定を git にするとgitのグルーバル設定にすることができる。プロジェクトで配布する場合はyamlにしておいた方がよい。またrubocopチェックに引っ掛かってもエラーではなく警告にとどめておきたい場合は、 checksではなく warningsを指定する。

rubocop

rubocopでチェックできる内容は多岐に渡り、中には「こんなんもんいらねー」的なチェックもある。何をどうチェックするかの設定をyamlファイルに記述しておくことができる。ルートディレクトリに.rubocop.ymlというファイルを作成すればよい。以下は私が使用している設定。

どんなチェックがあって何を意味しているのかはenabled.ymlのソースを見ればよい。ruby-style-guideへのリンクも記述されているので辞書として利用できる。

手動でrubocopを実行するにはコマンドを叩けばよい。-Dオプションを付けると、引っ掛かったチェック名を表示してくれるのでお勧め。

これにてgit commitする度にチェックが走り、エラーがあったらコミットさせてくれないという理想的自虐的環境ができあがった。

既存のプロジェクトに適用させる場合

おそらくデフォルトのルールでrubocopを実行するとエラーまみれになると思う。rubocopでは、必要なチェックなのか吟味しながら少しずつエラーを無くしていくというアプローチが取れるようになっている。このサイトが詳しい。

zsh + rbenvな環境でpre-commitが動かない場合

2016/07/19 追記:現在では公式githubに載っているように、次のコマンドを実行すれば動くようになっています。

-----

pre-commit installした際に自動生成される.git/hooks/pre-commitではzsh+rbenvという環境上では動かない(少なくとも私の環境ではgit commit時にエラーになった)。思いっきり書き換えてしまうことにする。

参考

関連する記事


コメントを残す

メールアドレスが公開されることはありません。

CAPTCHA


このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください