Tech Racho エンジニアの「?」を「!」に。
  • 開発

静的解析ツールgem RuboCop

こんにちは、ikedaです。

社内で、ソースコードレビューが活発になってきており、その私感を社内のミニプレゼンで発表しました。
ミニプレゼンの中で、ソースコードのコーディングルールを守って記述していたり、事前にチェックしておくと
レビューする側の人の負担が、減りますよね。という話でした。

発表資料については、社内のコードやコメントを含めていたので、techrachoに記事は載せないつもりです。

コーディングルールを細かく指摘することは、コードを書く際のルールや決まり事を知ることができますし、一般的に読みづらくないコードを書く癖を付ける機会にはなります。
とはいえ、インデントや、モジュール、クラス、メソッド、変数、などの命名規則のチェック、誤字脱字レベルの誤りのチェックなどを、目grepで探すことは、レビュアーに負担を与えることになってしまいますし、レビューを依頼する人にとっても、こういった指摘が、多くでるのは嬉しくないはずです。(特に私)

こういったチェックを事前にしておくことで、レビュアーにビジネスロジックのチェック、設計に関する確認に集中してもらうことができるようになると思いますし、細かい内容の指摘が、減ることになりますから不快にならずにすみます。

ただ、さすがにテキストエディタなどでコーディングルールを守りながら記述したり、目で確認したりするのでは、非常に労力が、かかってしまいます。

そこで、静的解析ツールというgem RuboCopを紹介します。
Ruby以外でも、静的解析ツールはありますが、今回とりあげるのはRuboCopのみです。

RuboCop

RuboCopは、Rubyのコーディングルールをチェックしてくれるgemです。アップデートも頻繁に行われているようです。
hashの記述方法や、各インデントの有無、コメントの記法など様々な内容をチェックしてくれます。
デフォルトのまま利用することができますし、設定ファイルにコーディングルールの各項目を有効にしたり、変更したりすることができます。 

今回は、Railsのプロジェクトで利用すること想定しています。
続いて、RuboCopの導入方法とRuboCopの設定ファイル書いていきます。

RuboCopの導入 

$ rails new rails_app
$ cd rails_app
$ vi Gemfile

# ...
gem 'rubocop', require: false
# ...

$ bundle install

$ rubocop -R  # .rubocop.ymlにRunRailsCopsオプションを有効にすることでRオプションが不要になります

この状態で, RuboCopを実行するとRailsが自動生成したコードがコーディングルールが守られていないと言われてしまいます。
rubocopの実行結果

設定ファイル(.rubocop.yml)の作成

採用するコーディングルールは、下記を参考にすることにします。
ruby_on_rails#Follow the Coding Converntions

  1. 行の始めのインデントはスペース2文字
  2. 空行にはスペースを入れない
  3. hashの記述は、Ruby 1.9から採用されている記述を利用する{ a: :b }
  4. private/protectedの後はインデントを入れる
  5. &&/||ではなく、and/or
  6. 等号の前後にはスペースを入れる(a = b)
  7. メソッド引数を囲む括弧にはスペースを付けない
  8. { do_stuff }の前後にスペースを含める

Railsのrootディレクトリに作成するか、homeディレクトリに.rubocop.ymlファイルを作成します

  $ vi .rubocop.yml

READMEにも記載されていますが、 
RuboCopが採用しているデフォルトのコーディングルールは、Ruby Style Guideです。
そのため、デフォルトで、適用されるルールについては、.rubocop.ymlには記述せずにいきます。

パラメータについては、config/default.yml, config/disabled.yml, config/enabled.ymlで確認してください。

Defaultsを参考

ソースを見ると、パラメータによっては、ruby-style-guideのリンクが張られていたりするので、どのコーディング規約に対応するのかがわかるようになっています。

AllCops:
  RunRailsCops: true 

Encoding:
  EnforcedStyle: when_needed

AccessModifierIndentation:
  EnforcedStyle: outdent

# 上記のルールにはないんですが、class Hogeの上にコメントを記述するのbest practiceとしてされていますが、
# ApplicationControllerとか記述したくなかったので、適用しないようにしました。
Documetation:
  Enabled: false

.rubocop.ymlの作成が完了したので、rubocopコマンドを実行します。

  $ rubocop

Railsから自動生成されるコードを一旦チェックから外す

RuboCopを調べているとこういった記事を読みました。.rubocop.ymlの設定例の記事も参考になりますが、コメントがついていて、それが良い情報だなと思いましたので、こちらもご紹介します。私は英語ができないので、非常に参考になりました。

rails new app_projectコマンドで、新規にプロジェクトを作成したときや、プロジェクトの途中からRuboCopを導入して、
ファイルを指定せずに、プロジェクト全体に対してrubocopコマンドを実行すると、自動生成されたコードや、既存のコードに対してもコーディングルールが守られているかをチェックします。ただ、自動生成のコードや既存のコードについては、すぐに確認したり、修正したりすることが、必要ない場合もあります。

その際に、rubocopコマンドに --auto-gen-configオプションを加えることで、.rubocop_todo.ymlが生成され、その時点で、コーディングルールが守られていなかった項目については、.rubocop_todo.ymlに入力されて、Enabled: falseで該当する項目は、無効化されるように記述されます。
これをrubocop.ymlでinherit_from: .rubocop_todo.ymlとして呼び出すと、項目が無視されるようになります。
ただ、Enabled: falseにして、項目を無効化していますから、既存コードを修正しなければ、新規に追加したコードについてもコーディングルールをチェックすることができなくなります。

$ rubocop --auto-gen-config
$ vi .rubocop.yml

# .rubocop.yml
inherit_from: .rubocop_todo.yml

これで、.rubocop_todo.ymlに記載されている内容については、回避します。
時間があるときに、随時todoを消化して、プロジェクトのソースをコーディングルールに沿う形に進めていきましょう。
とはいえ、新規に追加していくコードについても、todoに記載されているコーディングルールを無視してしまうので、どこかで一気に直すか。rubocopで、チェックするファイルを指定できるので、そちらでコントロールするかにしたほうが良さそうです。この辺りは調べていないのでちょっとよく知りません。

  $ rubocop

これで実行してみるとこんな感じになります。

todoファイル追加後

vimからRuboCopを実行

コマンドから実行するのではなく、各テキストエディタやIDEなどでプラグインが作られているようなのでプラグインを利用して、エディタからチェックするのもいいと思います。毎回ファイルを保存してから、コマンドからrubocopと打つのは大変ですよね。
vimなら、vim-rubocopというプラグインがあるのでそちらを利用することで、エディタ内でチェックできます。

詳しくは、vim-rubocop

ちなみに、作成したrubocop.ymlを読み込みことができます。

$ vi .vimrc
# .vimrc
let g:vimrubocop_config = '/path/to/rubocop.yml'

そのほかのエディタでも利用できるようになっているようです。

Guardを利用した自動チェック

利用するかは、好みですが、ファイルを保存した際にrubocopコマンドを実行したい場合は、guardを利用することで実現します。 

gem guard-rubocop
を参考にしてもらえればすぐ利用することができようになります。

  $ vi Gemfile

  group :development
    gem 'guard-rubocop'
  end

  $ bundle install
  $ guard init rubocop # Guardfileを新規に作成させる場合

以上になります。

参考


CONTACT

TechRachoでは、パートナーシップをご検討いただける方からの
ご連絡をお待ちしております。ぜひお気軽にご意見・ご相談ください。