この記事をシェアする

rubocopによる静的コード解析でRubyのコード品質を保つ

rubocopはRubyの静的コード解析ツールです。このコード解析を通すことによって、一定のRubyの書き方に統一することができます。また、不要な変数やメソッド名が長すぎるなど、一般的にRubyとして読みやすいコードにするための警告もされます。

こういった警告はRuby coding style and best practicesとしてRuby coding style guideにまとめられおり、Rubyを書くのであれば基本的にはRuby coding style guideを一読しておくことをおすすめします。英語が苦手であれば、翻訳された日本語版も存在します。

スポンサーリンク

なぜ静的コード解析をするのか?

静的コード解析し一定の読みやすいコードに統一することによって、人間が誤読する確率を下げることにより、バグなどの混入させる確率を下げる効果があります。また昨今ではGitHubでコードレビューをするようなチームだと、レビューする側の負荷を下げる効果も期待できます。読みやすいコードは、レビューもしやすいのです。

静的コード解析を使わないで、コードレビューの際にツールが指摘してくれるようなコードの書き方を指摘し続けるのは非常に苦痛であり、本来レビューでは設計・仕様・実装など、もっと大切な点にフォーカスしたいものです。

テストを自動化する、インフラを自動化する、デプロイを自動化する、コードに対する指摘も自動化しましょう。

Rubyを使っているのであれば、rubocopを活用しましょう。

rubocopのインストール

$ gem install rubocop

などをしてインストールしておきましょう。

$ rubocop

と実行すれば、そのディレクトリ以下の解析が実施されます。

既にある程度開発が進んだプロジェクトに対して、解析を実施すると多くの警告が表示されると思います。

bundle exec rubocop
Inspecting 42 files
CCCWCC.WWWWC..CCCCCC...CCCCCCCCCCCCCCCCCCW

Offenses:

app/controllers/api/v1/parcels_controller.rb:3:5: C: Missing top-level class documentation comment.
    class ParcelsController < ApplicationController
    ^^^^^
app/controllers/application_controller.rb:1:1: C: Missing top-level class documentation comment.
class ApplicationController < ActionController::Base
^^^^^
app/helpers/application_helper.rb:1:1: C: Missing top-level module documentation comment.
module ApplicationHelper
^^^^^^
app/models/kuroneko.rb:2:1: C: Missing top-level class documentation comment.
class Kuroneko < Parcel
^^^^^
... 省略 ...

42 files inspected, 156 offenses detected

今回はそのような状況で、どのような手順でコードを改修していくべきかガイドします。

警告をTODOファイルに落とす

現在表示される警告をTODOとしてYAML形式のファイルに出力する機能がrubocopには存在します。

$ rubocop –auto-gen-config

を実行すると.rubocop_todo.ymlファイルが作成されます。

ファイルの中身にはrubocopで現在の警告をしないための設定が記述されています。

# This configuration was generated by `rubocop --auto-gen-config`
# on 2014-07-26 22:40:55 +0900 using RuboCop version 0.24.1.
# The point is for the user to remove these configuration records
# one by one as the offenses are removed from the code base.
# Note that changes in the inspected code, or installation of new
# versions of RuboCop, may require this file to be generated again.

# Offense count: 1
# Configuration parameters: AllowSafeAssignment.
Lint/AssignmentInCondition:
  Enabled: false

# Offense count: 3
Lint/HandleExceptions:
  Enabled: false

# Offense count: 1
# Cop supports --auto-correct.
Lint/StringConversionInInterpolation:
  Enabled: false

... 省略 ...

「Offense count」と記述されている数字は警告数が記述されています。数が多いほど修正するべき箇所が多い状態です。

.rubocop.ymlを作成する

rubocopの設定ファイルである.rubocop.ymlで、先ほど作成した.rubocop_todo.ymlの設定を引き継ぐ設定をし、作成します。

$ echo 'inherit_from: rubocop-todo.yml' >> .rubocop.yml

.rubocop.yml作成後に再度、rubocopを実行すると全ての警告が表示されなくなっていることを確認してください。

$ rubocop
Inspecting 42 files
..........................................

42 files inspected, no offenses detected

これで、初期設定が完了しました。

静的コード解析の結果を反映していく方法

設定が一通り終了したので、これからどのようにコードを修正していくのかについて解説します。

.rubocop_todo.ymlを対応してゆく

基本は.rubocop_todo.ymlに記述されている設定を一つ一つ対応していくことです。

例えば

# Offense count: 2
 Style/AsciiComments:
   Enabled: false

というのが記述されていた場合を考えてみます。

この設定はコメントにASCII以外の文字コードが使われているという警告をしない設定です。
日本語でコメントが書かれているため、この警告が2カ所に出ています。
rubocop-todo.ymlから削除やコメントアウトをしてrubocopを実行すると警告されている場所が確認できます。

こういった設定の対応は下記の2種類にわかれます。

  • 警告を元にコードを修正する
  • 警告を許容し、今後警告しないようにする

警告を元にコードを修正する

.rubocop_todo.ymlの設定を削除し、rubocopを実行して警告される部分のコードを修正していくだけです。

rubocop-todo.ymlの設定に

# Offense count: 1
# Cop supports --auto-correct.
Style/BlockComments:
  Enabled: false

「Cop supports –auto-correct.」と記述されたものはrubocopで自動的に修正することをサポートしています。rubocop-todo.ymlの設定を削除して

$ rubocop -a

を実行すると自動的にコードを警告の出ない形に修正してくれます。auto-correctをサポートしていないものは手動で変更していくしかありません。

警告は理解出るものの具体的にどのように修正していいかわからない場合は、警告をRuby coding style guideで検索してみるとわかるかと思います。

警告を許容し、今後警告しないようにする

rubocop-todo.ymlの設定を削除して.rubocop.ymlに同様の設定を記述するだけです。.rubocop.ymlに設定を書いておけば以後、警告されることはありません。

さきほど紹介したコメントにASCII以外の文字コードを利用している場合に警告する

Style/AsciiComments:
  Enabled: false

などは代表例ではないでしょうか。

以上のような方法で警告の対応をしていけば、統一されたスタイルでRubyのコードになります。

警告をこれ以上増やさないようにするために

警告されるような悪いコードをこれ以上増やさないようにするために、JenkinsなどのCIでrubocopによる解析を実施することを推奨します。

Jenkinsであればrubocop-checkstyle_formatterを利用すればJenkinsのViolations pluginにCheckStyle形式でのレポートを読み込ますことができます。

これにより、一定の警告数を超えた場合にビルドが失敗した結果を返すことが可能になります。

スポンサーリンク

この記事をシェアする

著者をフォローする