rubocop-rails-omakaseとは何か?

Rails 7.2 で rails new した際に搭載される rubocop-rails-omakase について、それがどのようなもので、どのように使うことを期待されているかを書き記しておきます。

github.com

rubocop-rails-omakase は DHH が著者となる Ruby コーディングスタイルルールです。

一次情報はあくまで作者である DHH 発信のものとしてもらいたいですが、私自身も rubocop-rails-omakase や Rails 7.2 の RuboCop 関連機能のコントリビュータであり、比較的オリジンに近いことを述べることができると思います。また RuboCop のコミッターをしているため、たぶん RuboCop の世界にはちょっと詳しい方でしょう。

とはいえ、いろいろな考え方がある領域であることも承知しているため、ひとつの考え方としてご参考ください。

なぜこの記事を書くに至ったか

Rails 7.2 で rubocop-rails-omakase が標準搭載されたことにあたり、これまでプロジェクトで育てた .rubocop.yml を rubocop-rails-omakase に置き換えるというものをいくつか見てきています。妥当な理由もあれば、そうでない理由もあるため考え方を整理しておく意味で書いておこうと思い至りました。

rubocop-rails-omakaseはgofmtのようなものではない

まず rubocop-rails-omakase の特徴は、軽量な Ruby コーディングルールになっています。RuboCop のデフォルトルールが重量級であることと対比的です。

RuboCop の構成にはコインの表と裏のような切り離せないものがあり、軽量ルールはうるさくない反面、検知してもらいたかった問題を発見したりオートコレクトできません。その反対も然りで、見つけたい問題以外の余計な提案までされうるのが RuboCop のデフォルトルールです。

つまり rubocop-rails-omakase は銀の弾丸というわけでも、万能というものでもありません。

rubocop-rails-omakaseはスタート地点

もしこれまで自前で自分たちにフィットする .rubocop.yml をメンテナンスしてきたプロジェクトであれば、基本的にはその .rubocop.yml をメンテナンスするのがおすすめです。

rubocop-rails-omakase は Rails が提供する Linter, Formatter のスタート地点の構成であり、すでにスタート地点の先に行っているルールを使っていれば、それを使い続ければ良いためです。

Rails 7.2 へのアップグレードによって、スタートからやり直しというのは理にかなったアプローチにはならないでしょう。

rubocop-rails-omakaseに置き換えできないの?

もし、これまで自分たちで育ててきた既存の .rubocop.yml よりも rubocop-rails-omakase の方がクールだぜ。という場合は置き換えるのはひとつのアプローチです。ちょっと悲しい気がしますが。

その場合は、もちろんこれまで検知できていたものやオートコレクトできるものは rubocop-rails-omakase ベースに強制されなおされるのと、おそらく大量のスタイル変更 diff が入った Pull Request と向き合うことになります。そのため自分たちで既にルールを組み上げている場合は、個人的にはあまりお勧めしないコースです。

逆にこれから Linter, Formatter を導入しようという場合は、スタート地点のひとつになると思います (rubocop-rails-omakase で気に入らないルールはカスタマイズできます) 。

rails/railsリポジトリとの関係性

rubocop-rails-omakase は rails/rails リポジトリの .rubocop.yml と異なるコーディングルールです。Rails フレームワークRails アプリケーションが地繋がりという考えがあるとすると、コーディングスタイルのルールという側面でこれらは繋がっていません。

rubocop-rails-omkase のルールは固定されていますが、rails/rails の .rubocop.yml 設定は折に触れて更新されます。

フレームワークとアプリケーションでルールを揃えたい場合は、rails/rails リポジトリのルールをトレースしている rubocop-rails_config の利用などを検討してください。

github.com

また、このような理由から rubocop-rails-omakase は rubocop-rails_config (とそれを継承したスタイル) を置き換えるものでもありません。

結局rubocop-rails-omakaseとどう向き合えばいいの?

rails new の後の bin/rubocop の実行に対して、何らかの .rubocop.yml の設定が必要ですが、自分たちがルールを持っていない場合のスタートラインとして、軽量なルールセットとして使えます (さすがに RuboCop のデフォルトルールを Rails アプリケーションユーザー全体のデフォルト とするのは重量感あると思います) 。rubocop-rails-omakase のルールセットとして、気に入ればそのまま使い続けることもできますし、この設定を元に更新していくこともできます。このあたりの向き合い方については rubocop-rails-omakase の README に詳しいです。

またコーディングルールの更新はユーザーのプロジェクトサイドでのみ行われることが期待されています。rubocop-rails-omakase は現時点でルールが固定されており、ユーザーからのコーディングルールのフィードバックが期待されていません

例えば、配列リテラルについて [ foo, bar, baz ] といったブレースの内側にスペースを強要する設定で、私が見る限り Ruby では現状マイノリティのコーディングルールですが、これは意図的な設定です。気に入らなければユーザー側でルールを更新しましょう。

また既に自分たちのルールを組み上げていればそれを使い続ければ良く、スタート地点のrubocop-rails-omakseへの切り替えは基本的に考えなくて良いと思っています (お仕事では他に考えるべきことがいっぱいある) 。

rubocop-rails-omakaseとは何か?

端的にいうと、standard, rubocop-rails_config, rubocop-github, rubocop-airbnb など数あるカスタムルールセットのひとつです。Ruby のコーディングルールは gofmt のように大統一できるものではないという哲学が RuboCop にあるように、多様性のひとつとして捉えるのが良いと思います。

rubocop-rails-omakase は、軽量な開始地点をデフォルトとして提供されているというあたりが、とても DHH らしい感じです。また Ruby の Linter, Formatter として、どのようなルールセットとして育てていくかユーザーサイドに omakase されているあたりも The Rails Doctrine みあるなあと思っています。

このあたりの話は先日の Ruby セミナー 東京でも触れておりますので、よければあわせてご参照ください。

そんな感じで今日はここまで。ハックを続けましょう。