Guardとは
Guardとはファイルの変更を検知して、自動的にさまざまな処理を実行してくれるRubyのGemです。
これ単体で使うよりも、他のツールと連携し、自動的に処理を行い開発効率を上げるために使います。
メジャーどころとしては、次の3つだと思います。
- guard-livereload - Viewファイルの変更したときに自動的にブラウザをリロードする
- guard-rspec - specファイルを変更したときに自動的に
RSpec
を実行する - guard-rubocop - ファイルを修正したときに
RuboCop
を実行する
本記事では、Railsへguard-rubocop
の導入方法を記載します。
また、rubocop
は自動で動くので、失敗したときに、Mac OS X の通知センターの機能を使って通知するようにします。
対象読者
- Railsの開発効率を上げたい方
確認バージョン
- Mac OSX 10.9
- Ruby 2.0
- Rails 4.1
- guard 2.6.1
- rubocop 0.26.1
- guard-rubocop 1.1.0
- terminal-notifier-guard 1.5.3
目次
1. Railsプロジェクトの作成
まず、Guardを実行させるベースとなるRailsのプロジェクトを作成します。
rails new guard_test
次に、簡単なProductのScaffoldを作成します。
cd guard_test rails g scaffold Product name:string price:integer discontinued:boolean
マイグレートします。
rake db:migrate
2. guard-rubocopの導入
Gemfile
のdevelopemnt
グループ内に必要なgemを追加します。
# Gemfile group :development do gem 'rubocop' gem 'guard-rubocop' gem 'terminal-notifier-guard' end
Bundlerを実行して、インストールします。
bundle install
Guard定義が記載されたGuardfile
(Guardの設定ファイル)を作成します。
guard init rubocop
コマンドが上手くいかない場合は、下記を実行して下さい。
gem install rubocop gem install guard-rubocop gem install terminal-notifier-guard
作成されたGuardfile
の中身を確認してみます。
rubocop
のブロック内に監視対象が記載されています。
watch
メソッドで監視するファイルを正規表現で記載します。
# Guardfile guard :rubocop do watch(%r{.+\.rb$}) watch(%r{(?:.+/)?\.rubocop\.yml$}) { |m| File.dirname(m[0]) } end
次のように修正します。
# Guardfile # guard :rubocop do guard :rubocop, all_on_start: false, cli: ['--format', 'clang', '--rails'] do watch(%r{.+\.rb$}) watch(%r{.+\.rake$}) # .rakeファイルも監視対象にする watch(%r{(?:.+/)?\.rubocop\.yml$}) { |m| File.dirname(m[0]) } end
上記の設定でguard起動時にrubocopを実行させず、失敗時に通知センターに通知がされます。
rubocopの詳細なオプションについては、本記事下記の「guard-rubocopのオプション」を参照して下さい。
では、Guard
を実行します。
bundle exec guard
※Railsプロジェクトの配置パスに日本語が入っていると、「E, [2014-10-16T00:43:38.055423 #28197] ERROR -- : run() in thread failed: inspected result must be ASCII only or use the same encoding with default external:/Users/nipe0324/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/listen-2.7.9/lib/listen/listener.rb:329:in `inspect'」のようなエラーが発生するのでご注意ください。
.rb
のファイルを編集することで、自動でrubocopが動き、(デフォルトのrubocopの規約が厳しすぎて)失敗するので、右上で通知がされます。
これで、自動でrubocopを起動する環境を構築することができました。
rubocopの設定については、bbatsov/rubocop · GitHub を参照して下さい。
3. guard-rubocopのオプション
次のようにguard-rubocop
にオプションを指定することが可能です。
# Guardfile guard :rubocop, all_on_start: false, cli: ['--format', 'clang', '--rails'] do watch(%r{.+\.rb$}) watch(%r{(?:.+/)?\.rubocop\.yml$}) { |m| File.dirname(m[0]) } end
指定できるオプションは次のようになっています。
all_on_start: true # Guard起動時にすべてのファイルをチェックする(デフォルト値:true) cli: '--rails' # RuboCopへのオプションをを文字列か配列で指定する(デフォルト値:nil) keep_failed: true # Keep failed files until they pass. (default: true) notification: :failed # 実行後に通知センターに通知をする(デフォルト値:failed - 失敗時) # true - 毎回通知する # false - 通知をしない # :failed - 失敗時のみ通知する
guard-rubocopとguard-rspecの混合
TDDで実装しているときに、RedとGreenの段階では、「RSpecが失敗したら、RuboCopの実行をしない」ように制御したい場合があるかもしれません。
そのようなときに、次のようにGuardfile
を修正するとよいです。
# Guardfile # RSpecが失敗したら、RuboCopをスキップする group :red_green_refactor, halt_on_fail: true do guard :rspec do ... end guard :rubocop do ... end end * 参考文献 - [https://github.com/guard/guard:title]