Rubocopを使ってRubyのコードを規約に基づいて修正できるようにする

Rubyを書いていてRuboCopというツールを使う必要がでてきたので、調べたことをまとめます。

RuboCopとは

Rubyのコードの静的解析ツール。RuboCopのコマンドを実行することで、間違った書き方や非推奨な書き方に対して警告を出してくれる。また自動で修正を行うこともできる。 RuboCopのルールを共有することで、コードの可読性や品質を保ち、書き方を統一できる。

公式サイト

RuboCopの使い方

RuboCopは以下の流れで使う。

  1. RuboCopをインストールする
  2. 解析したいファイルが存在するディレクトリでRuboCopのコマンドを実行する
  3. 警告が表示されたコードを修正する
  4. 2と3を警告が表示されなくなるまで繰り返す(もしくは自動修正)

RuboCopのインストール

RubocopはGemのライブラリなので、Gemfileに記述してインストールする。

group :development do
  gem 'rubocop', require: false
end

RuboCopは開発環境だけで使うので、group :development do ~ endの中にライブラリを記述する。

ライブラリの後ろのrequire: falseというのは、アプリ起動時に読み込む必要がないものに指定して、自動読み込みしないようにするオプション。


Gemfileに記述できたら、bundlerを使ってインストールする。

bundle install

RuboCopの実行方法

RuboCopを通すときは、ターミナルでrubocopコマンドを実行する。

# 今いるディレクトリのファイルと、ディレクトリ配下のファイル全てにRuboCopを通す
rubocop

# 指定したファイルにRuboCopを通す
rubocop sample.rb

# ディレクトリ配下のファイルにRuboCopを通す
rubocop directory/

RuboCopの出力の見方

RuboCopを実行すると、主に以下のようなメッセージが出力される。

Inspecting 7 files
CCC.CCW

juice.rb:8:3: C: [Correctable] Style/TrivialAccessors: Use attr_reader to define trivial reader methods.
  def name
  ^^^
juice.rb:12:3: C: [Correctable] Style/TrivialAccessors: Use attr_reader to define trivial reader methods.
  def price
  ^^^
step1.rb:22:19: C: [Correctable] Layout/TrailingEmptyLines: Final newline missing.
puts suica.balance

~

7 files inspected, 17 offenses detected, 13 offenses autocorrectable


以下の最初の部分は、1行目がRuboCopを通したファイルの数で、2行目が違反のレベルを表示する。

Inspecting 7 files
CCC.CCW

違反のレベルは以下の通りで、下にいくほど厳しく、Warning以降は修正すべき違反である。

.Clean(問題なし)
RRefactor
CConvention
WWarning
EError
FFatal


ファイル名やメッセージ、^^^などが書かれているかたまりの行が1つの警告にあたる。


最後の行では、RuboCopを通した結果が表示される。

7 files inspected, 17 offenses detected, 13 offenses autocorrectable

ここでは、7つのファイルをチェックして、17個の警告が検出され、13個の警告が自動で修正可能であると表示されている。


最終的に以下のメッセージが出力される状態を目指す。

7 files inspected, no offenses detected

RuboCopの設定

.rubocop.yml

独自でRubocopの設定をしたい場合は.rubocop.ymlに記述する。rubocop --initでコマンドを実行したディレクトリにファイルを生成できる。.rubocop.ymlを使わない場合はデフォルトのルールが使用される。デフォルトだとルールが厳しく、大量の警告が出力されるので基本はプロジェクトによるが、変更したほうがいい。

rubocop --init

.rubocop.ymlに記述する主なルールは以下の記事。

修正する

.rubocop_todo.ymlを使う方法

RuboCopを実行して出力された警告に基づいて1つずつ修正していってもいいが、大量の警告が表示された時はかなり見づらい。

そこで以下の流れで修正を行う。

  1. rubocop --auto-gen-configを実行する
  2. 1のコマンドで作られた.rubocop_todo.ymlに警告が記述される。
  3. .rubocop_todo.ymlの警告をコメントアウトして1つずつ修正する


ターミナルでrubocop --auto-gen-configを実行すると、.rubocop_todo.yml.rubocop.ymlが生成される。

rubocop --auto-gen-config

.rubocop_todo.ymlは出力される警告が自動的に記述される。 このファイルに警告が記述されている状態の時にrubocopコマンドを実行しても警告が出力されないので、警告をコメントにすることで1つずつ警告を出力することができる。 最終的にはこのファイルの中身を空にする。


この方法を使うときは、.rubocop.ymlの一番上に以下のコードを記述しておく。この記述はrubocop --auto-gen-configを実行したときに自動的に記述されている。

inherit_from: .rubocop_todo.yml

自動修正

いちいち警告を出力して修正を行うのが面倒な時は、自動修正を行う。 自動修正を行うときは-aまたは-Aのオプションをつけてrubocopコマンドを実行する。

rubocop -a

rubocop -A

-aは安全に自動修正してくれるオプションで、-Aは自動修正で挙動が変わってしまう可能性もあるオプション。

自動修正を避けたい場合は.rubocop.ymlExclude配下にファイル名またはディレクトリ名を記述しておく。

使ってみた感想

コードが統一されるのは便利だし、推奨されている書き方を知れるのでありがたい。 自動修正は便利だけど、どこが変更されているか、どのように変更されているかを把握しておく必要があるので使い慣れる前は1つずつ修正していくようにする。

参考

https://kitsune.blog/rails-rubocop#RuboCop%E3%81%A7%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%92%E8%87%AA%E5%8B%95%E4%BF%AE%E6%AD%A3

https://techtechmedia.com/auto-correct-rubocop/