rubocopはrubyの静的コード解析を実行してくれる便利なgem。例えば、ソースコード内の残念なメソッド名を発見してくれたり、1メソッドの行数を制限できたりする。解析内容は多岐にわたるので、ぜひ公式ドキュメントを参照あれ。
一方pre-commitとは、gitコミットをフックして何らかのアクションを実行してくれるgem。末尾の空白を検知したり、Javascriptのconsole.log
や、pryのbinding.pry
がソース内に残っていないかなどチェックできる。こいつが標準でrubocopもサポートしているので、これらを組み合わせると、規約違反のコードが含まれている場合にgit commit
できないようにすることができる。
目次
セットアップ
bundle + railsという環境を想定すると、Gemfileは以下のようになる。
📄Gemfile
group :development do gem 'rubocop', require: false gem 'pre-commit', require: false end
bundle install
した後に、pre-commitをインストールする必要がある。
📄config/pre_commit.yml
$ bundle exec pre-commit install
git-hookは新しいshプロセスで動くので、pre-commitはbundler経由で実行させるよう、gitの設定を施してやる必要があります。
$ git config pre-commit.ruby "bundle exec ruby"
これにて導入は完了。
pre-commit
pre-commit list
コマンドで各checkの利用状況が確認できる。
$ bundle exec pre-commit list Available providers: default(0) git(10) git_old(11) yaml(20) env(30) Available checks : before_all ci closure coffeelint common console_log csslint debugger gemfile_path go jshint jslint json local merge_conflict migration nb_space pry rails rspec_focus rubocop ruby ruby_symbol_hashrockets scss_lint tabs whitespace yaml Default checks : common rails Enabled checks : common rails Evaluated checks : tabs nb_space whitespace merge_conflict debugger pry local jshint console_log migration Default warnings : Enabled warnings : Evaluated warnings :
Available checksが利用できるチェックの一覧。Enabledが現在利用しているチェックである。上記ではcommonとrailsというチェックがなされている。この2つのチェックに含まれる個々のチェックはEvaluated checksに記述されている。要するに、これらが実際に実行されるチェック。このあたりは公式サイトとかこのあたりを参考にしてほしい。
デフォルトではrubocopを利用するようにはなっていないので、設定を変更しよう。
$ bundle exec pre-commit enable yaml checks rubocop
yamlと指定しているのは、設定をyamlファイルに書き出すということ。railsディレクトリ内で実行すると、config/pre_commit.ymlというファイルが出来上がっているはずだ。
--- :checks_remove: [] :checks_add: - :rubocop
今後はこのファイルを直接編集してもよい。ちなみに、先のyaml
と指定をgit
にするとgitのグルーバル設定にすることができる。プロジェクトで配布する場合はyamlにしておいた方がよい。またrubocopチェックに引っ掛かってもエラーではなく警告にとどめておきたい場合は、checks
ではなくwarnings
を指定する。
rubocop
rubocopでチェックできる内容は多岐に渡り、中には「こんなんもんいらねー」的なチェックもある。何をどうチェックするかの設定をyamlファイルに記述しておくことができる。ルートディレクトリに.rubocop.ymlというファイルを作成すればよい。以下は私が使用している設定。
📄.rubocop.yml
AllCops: RunRailsCops: true Exclude: - bin/**/* - config/boot.rb - db/schema.rb - script/**/* - tmp/**/* - vendor/**/* # 1クラスの行数を200行以下に制限する Metrics/ClassLength: Max: 200 # 1行の文字数を制限しない Metrics/LineLength: Enabled: false # 1メソッドの行数を制限しない Metrics/MethodLength: Enabled: false # 日本語コメントを許す Style/AsciiComments: Enabled: false # ファイル冒頭にコメントを書かなくてもよい Style/Documentation: Enabled: false # class Hoge::Fooのような記述を許す Style/ClassAndModuleChildren: Enabled: false
どんなチェックがあって何を意味しているのかはenabled.ymlのソースを見ればよい。ruby-style-guideへのリンクも記述されているので辞書として利用できる。
手動でrubocopを実行するにはコマンドを叩けばよい。-Dオプションを付けると、引っ掛かったチェック名を表示してくれるのでお勧め。
📄.git/hooks/pre-commit
$ bundle exec rubocop -D
これにてgit commitする度にチェックが走り、エラーがあったらコミットさせてくれないという理想的自虐的環境ができあがった。
既存のプロジェクトに適用させる場合
おそらくデフォルトのルールでrubocopを実行するとエラーまみれになると思う。rubocopでは、必要なチェックなのか吟味しながら少しずつエラーを無くしていくというアプローチが取れるようになっている。このサイトが詳しい。
zsh + rbenvな環境でpre-commitが動かない場合
2016/07/19 追記:現在では公式githubに載っているように、次のコマンドを実行すれば動くようになっています。
$ git config pre-commit.ruby "bundle exec ruby"
—–
pre-commit installした際に自動生成される.git/hooks/pre-commitではzsh+rbenvという環境上では動かない(少なくとも私の環境ではgit commit時にエラーになった)。思いっきり書き換えてしまうことにする。
#!/bin/zsh source ~/.zshrc bundle exec ruby -rrubygems -e ' begin require "pre-commit" true rescue LoadError => e $stderr.puts <<-MESSAGE pre-commit: WARNING: Skipping checks because: #{e} pre-commit: Did you set your Ruby version? MESSAGE false end and PreCommit.run '
参考
関連する記事
- 【Rails】リロード時に特定の処理を実行する
- 久しぶりにRailsで開発して感じたこと
- Railsアプリ内の定数を管理するgem ‘Constantinopolis’
- Rails用のgemを作成する手順 (Rails 4.0以降)
- Ruby on Rails + Bootstrap3 + simple_form チュートリアル