RuboCop導入後の設定カスタマイズ方法

Ruby

前回、RuboCopのインストール手順と具体的な使い方でRuboCopのインストール手順について紹介しました。

RuboCopは導入して終わりではなく、プロジェクトのコーディングスタイルに適した形へカスタマイズする必要があります。

今回はRubuCopのカスタマイズ方法についてシチュエーション別で紹介します。

Copを無効にしたい場合

Copを無効にしたい場合については『恒久対応として扱う場合』と『暫定対応として扱う場合』の2つのケースを紹介します。

恒久対応として扱う場合

RuboCopで指摘されたが直す必要がない・直したくないケースです。

恒久対応としてCopを無効にする設定は以下の通りです。

.rubocop.yml

[Cop名]:
  Enabled: false

具体例を紹介します。
rubocop実行後、以下のようにStyle/Documentationに関する指摘が複数表示されたとします。
Style/Documentationはクラスの説明がコメントで書かれているかチェックするCopです。

$ rubocop
Inspecting 30 files
.......C.C.................C..

Offenses:

app/models/application_record.rb:3:1: C: Style/Documentation: Missing top-level class documentation comment.
class ApplicationRecord < ActiveRecord::Base
^^^^^
config/application.rb:24:1: C: Style/Documentation: Missing top-level class documentation comment.
class Rails6ApiMysql8::Application < Rails::Application
^^^^^
lib/example/hoge.rb:3:1: C: Style/Documentation: Missing top-level class documentation comment.
class Example::Hoge
^^^^^

30 files inspected, 3 offenses detected

Style/Documentationを無効にする設定は以下の通りです。

.rubocop.yml

Style/Documentation:
  Enabled: false

上記の設定を追加後、再度rubocopを実行するとStyle/Documentationが表示されなくなります。

$ rubocop
Inspecting 30 files
..............................

30 files inspected, no offenses detected

暫定対応として扱う場合

いずれ直す必要はあるがいったんCopの対応を保留にしておきたいケースです。

暫定対応として扱う場合は.rubocop_todo.ymlに設定を記述します。
暫定対応としてCopを無効にする設定は以下の通りです。

.rubocop.yml

inherit_from: .rubocop_todo.yml

.rubocop_todo.yml

[Cop名]:
  Enabled: false

具体例については設定ファイルの変更箇所のみ違うだけでそのほかは恒久対応の場合と同じなので省略します。

Copの設定を編集したい場合

Cop自体は必要だが現在適用されている設定がアプリケーションのコーディングスタイルにあっていないためカスタマイズしたいというケースです。

Copの設定を編集する場合は以下のように記述します。

.rubocop.yml

[Cop名]:
  [オプション名]: [値]

具体例を紹介します。
rubocop lib/example/hoge.rb実行後、以下のようにStyle/ClassAndModuleChildrenに関する指摘が表示されたとします。
Style/ClassAndModuleChildrenはクラス内クラスの記述方法をチェックするCopです。

$ rubocop lib/example/hoge.rb
Inspecting 1 file
C

Offenses:

lib/example/hoge.rb:3:7: C: [Correctable] Style/ClassAndModuleChildren: Use nested module/class definitions instead of compact style.
class Example::Hoge
      ^^^^^^^^^^^^^

1 file inspected, 1 offense detected, 1 offense auto-correctable

上記の指摘はStyle/ClassAndModuleChildrenEnforcedStyleオプションをcompactにすることで解決します。

Style/ClassAndModuleChildrenの設定を編集する方法は以下の通りです。

.rubocop.yml

Style/ClassAndModuleChildren:
  EnforcedStyle: compact

上記の設定を追加後、再度rubocop lib/example/hoge.rbを実行するとStyle/ClassAndModuleChildrenに関する指摘が表示されなくなります。

$ rubocop lib/example/hoge.rb
Inspecting 1 file
.

1 file inspected, no offenses detected

ファイルをRuboCopの対象外にしたい場合

ファイルをRuboCopの対象外にしたい場合については『恒久対応として扱う場合』と『暫定対応として扱う場合』の2つのケースを紹介します。

恒久対応として扱う場合

そもそもコーディングスタイルをチェックするようなファイルではないというケースです。

恒久対応としてファイルをRuboCopの対象外にする設定は以下の通りです。

.rubocop.yml

AllCops:
  Exclude:
    - [ファイル名] # 特定のファイルを除外したい場合
    - [ディレクトリ名] # 特定のディレクトリを除外したい場合

具体例を紹介します。

rubocop実行後、以下のようにlib/example/hoge.rbに対して複数のCopが表示されたとします。

$ rubocop
Inspecting 30 files
...........................C..

Offenses:

lib/example/hoge.rb:3:1: C: Style/Documentation: Missing top-level class documentation comment.
class Example::Hoge
^^^^^
lib/example/hoge.rb:3:7: C: [Correctable] Style/ClassAndModuleChildren: Use nested module/class definitions instead of compact style.
class Example::Hoge
      ^^^^^^^^^^^^^

30 files inspected, 2 offenses detected, 1 offense auto-correctable

lib/example/hoge.rbをRuboCopの対象外にする設定は以下の通りです。

AllCops:
  Exclude:
    - 'lib/example/hoge.rb'

上記の設定を追加後、再度rubocopを実行するとlib/example/hoge.rbが表示されなくなります。

$ rubocop
Inspecting 30 files
..............................

30 files inspected, no offenses detected
rubocopコマンドの引数にファイルを指定した場合、当該設定をしていてもRuboCopによるチェックが実行されます。強制的にファイルをRuboCop対象外にしたい場合はrubocopコマンドの『–force-exclusion』オプションを利用します。

暫定対応として扱う場合

コーディングスタイルをチェックすべきファイルだが指摘箇所が多すぎるなどの理由で修正は保留にしておきたいケースです。

暫定対応として扱う場合は.rubocop_todo.ymlに設定を記述します。
暫定対応としてファイルをRuboCopの対象外にする設定は以下の通りです。

.rubocop.yml

inherit_from: .rubocop_todo.yml

.rubocop_todo.yml

AllCops:
  Exclude:
    - [ファイル名] # 特定のファイルを除外したい場合
    - [ディレクトリ名] # 特定のディレクトリを除外したい場合

具体例については設定ファイルの変更箇所のみ違うだけでそのほかは恒久対応の場合と同じなので省略します。

ファイルをCopの対象外にしたい場合

ファイルをCopの対象外にしたい場合については『恒久対応として扱う場合』と『暫定対応として扱う場合』の2つのケースを紹介します。

恒久対応として扱う場合

有効にしているCopだが特定のファイルでは無効にしたい・無効にしてよいというケースです。

恒久対応としてファイルをCopの対象外にする設定は以下の通りです。

.rubocop.yml

[Cop名]:
  Exclude:
    - [ファイル名] # 特定のファイルを除外したい場合
    - [ディレクトリ名] # 特定のディレクトリを除外したい場合

具体例を紹介します。
rubocop lib/example/hoge.rb実行後、以下のようにStyle/Documentationに関する指摘が複数表示されたとします。

$ rubocop lib/example/hoge.rb
Inspecting 1 file
C

Offenses:

lib/example/hoge.rb:4:3: C: Style/Documentation: Missing top-level class documentation comment.
  class Hoge
  ^^^^^

1 file inspected, 1 offense detected

lib/example/hoge.rbStyle/Documentationを無効にする設定は以下の通りです。

.rubocop.yml

Style/Documentation:
  Exclude:
    - 'lib/example/hoge.rb'

上記の設定を追加後、再度rubocop lib/example/hoge.rbを実行するとStyle/Documentationに関する指摘が表示されなくなります。

$ rubocop lib/example/hoge.rb
Inspecting 1 file
.

1 file inspected, no offenses detected

暫定対応として扱う場合

あるファイルにおいて特定のCopの対応のみいったん保留にしておきたいケースです。

暫定対応として扱う場合は.rubocop_todo.ymlに設定を記述します。
暫定対応としてファイルをCopの対象外にする設定は以下の通りです。

.rubocop.yml

inherit_from: .rubocop_todo.yml

.rubocop_todo.yml

[Cop名]:
  Exclude:
    - [ファイル名] # 特定のファイルを除外したい場合
    - [ディレクトリ名] # 特定のディレクトリを除外したい場合

具体例については設定ファイルの変更箇所のみ違うだけでそのほかは恒久対応の場合と同じなので省略します。

コードの一部をCopの対象外にしたい場合

ファイル自体はCopの対象で問題ないが、特定の部分のみCopを無効化したいケースです。

コードの一部をCopの対象外にする設定は以下の通りです。

# rubocop:disable [Cop名]
#
# 処理
#
# rubocop:enable [Cop名]

具体例を紹介します。
以下のようなコードを含むconfig/environments/development.rbがあるとします。

config/environments/development.rb

(略)
if Rails.root.join('tmp', 'caching-dev.txt').exist?
  config.cache_store = :memory_store
  config.public_file_server.headers = {
    'Cache-Control' => "public, max-age=#{2.days.to_i}"
  }
else
  config.action_controller.perform_caching = false

  config.cache_store = :null_store
end
(略)

rubocop config/environments/development.rbを実行すると以下のようにRails/FilePathに関する指摘が表示されます。

$ rubocop config/environments/development.rb
Inspecting 1 file
C

Offenses:

config/environments/development.rb:19:6: C: Rails/FilePath: Prefer Rails.root.join('path/to').
  if Rails.root.join('tmp', 'caching-dev.txt').exist?
     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

1 file inspected, 1 offense detected

上記の指摘箇所を無効化する方法は以下の通りです。

config/environments/development.rb

# rubocop:disable Rails/FilePath
if Rails.root.join('tmp', 'caching-dev.txt').exist?
  config.cache_store = :memory_store
  config.public_file_server.headers = {
    'Cache-Control' => "public, max-age=#{2.days.to_i}"
  }
else
  config.action_controller.perform_caching = false

  config.cache_store = :null_store
end
# rubocop:enable Rails/FilePath

コメント追加後、再度rubocop config/environments/development.rbを実行するとRails/FilePathに関する指摘が表示されなくなります。

$ rubocop config/environments/development.rb
Inspecting 1 file
.

1 file inspected, no offenses detected

さいごに

Twitter(@nishina555)やってます。フォローしてもらえるとうれしいです!