こんにちは。メディアサービス開発部 Webアプリケーション開発課のシゲタです。
以前このブログでRuboCopのカスタムルールを作成する方法についての記事を書きました。 https://developers.bookwalker.jp/entry/2023/03/31/174906
カスタムルールとは個別のプロジェクトやチームのコーディングスタイルに合わせたRuboCopの拡張ルールのことです。 この記事を書いてから約一年程が経ち、私が参画しているプロジェクトでも実際にカスタムルールを運用し始めました。
今回は実際にカスタムルールを導入して得られた効果について紹介したいと思います。
カスタムルールの導入効果
実際に導入して得られた効果は下記のとおりです。
- コーディング規約をコード化できる
- コードレビューの一部をRuboCopに移譲できる
- 規約に反するコードを手動で直す手間が省ける
それぞれの効果について具体的なメリットを記載していきます。
コーディング規約をコード化できる
チーム開発をする中で、チーム独自のコーディング規約ができました。しかしその多くは口頭ベースでやり取りされていたので文書化にまで至らなかった、あるいはPullリクエストのコメントに書いたけど古すぎて埋もれてしまった、といったものでした。そういった経緯もあり、コーディング規約を決めても「これどうすんだっけ?」となったり、レビューで同じような指摘が繰り返されることが何度か起きていました。
こうした口頭ベースで生まれるコーディング規約をカスタムルールとしてコード化することで、RuboCopが規約に違反しているかどうかをチェックしてくれるようになり、Pullリクエストを出す前に規約違反に気づけるようになりました。
コードレビューの一部をRuboCopに移譲できる
コードレビューもRuboCopが行ってくれるため、カスタムルールとしてコード化できている規約については、レビューから漏れたコードがmainブランチにマージされてしまうこともなくなりました。 コードレビューの一部をRuboCopに移譲することで、レビューコストも削減されるというのもカスタムルール作成のメリットです。
規約に反するコードを手動で直す手間が省ける
規約に違反するコードをちまちま手動で直していくこともできますが、修正量がそれなりに多いと腰が重くて作業も億劫になります。
「ハッシュの要素はキーのABC順に並べることにしよう」という話をチームでした際も、ABC順に並んでいないハッシュが100ファイル以上に及んで存在していたので、まず手動修正は諦めました。 そこで、ハッシュの要素を並び替えてくれるルールを実装して指摘箇所を修正することにしました。
対応としては、要素の並び替えによって処理の挙動が変わりテストが落ちるケースがあったので、指摘箇所にrubocop:todo
コメントを追加し、範囲を絞って自動修正することにしました。すべてのハッシュを手動で直していくより遥かに作業負担を軽減させることができたと思います。
違反を指摘するルールは手間要らず
導入効果というより感想ですが、違反を指摘するだけのルールに関しては(あくまで私が観測できた範囲では)手間をかけずに実装できるものが多いと感じました。たとえば、デフォルト引数にTime.zone.now
を使えないようにするルールは以下のようになります。
module RuboCop module CustomCop class DetectTimeInDefaultArgs < RuboCop::Cop::Base MSG = '`Time.zone.now` is detected in a default argument.' def on_optarg(node) check_for_time_zone_now(node) end def on_kwoptarg(node) check_for_time_zone_now(node) end private def check_for_time_zone_now(node) return if node.default_value.source != 'Time.zone.now' add_offense(node.default_value) end end end end
on_optarg
とon_kwoptarg
がそれぞれ、デフォルト引数とキーワード引数に対して呼ばれるフックです。
それぞれの中で、デフォルト引数であるnode.default_value.source
がTime.zone.now
だったら指摘するシンプルな実装です。
これが自動修正に対応したルールだと勝手が変わるのですが、特定のケースにおいてメソッドや定数の使用を指摘するルールであれば手間をかけずに作成できていることも規約のコード化を行う上で大変助かっています。
おまけ
カスタムルールを導入する際に活用したtipsです。本筋と離れますが個人的に有益だったので共有します。
rubocop:todo
コメントを活用する
RuboCopによる指摘箇所をすぐに修正できない場合はrubocop {-a|-A} --disable-uncorrectable
コマンドを活用しました。
--disable-uncorrectable
オプションは-a
や-A
と一緒に使うことで、RuboCopの指摘箇所すべてにrubocop:todo
をコメントしてくれるものです。
rubocop:todo
をコメントすることでRuboCopのルールに違反する指摘を無視させることができます。
https://docs.rubocop.org/rubocop/usage/auto_correct.html#generating-comments
注意点として--disable-uncorrectable
オプションは、自動修正に対応していないルールにのみ有効ということです。
なので、自動修正に対応したカスタムルールの指摘箇所にrubocop:todo
をコメントしたい場合は、ルールから自動修正に該当する処理を削除した状態でコマンドを実行する必要があります。
InternalAffairsを有効化する
InternalAffairs
はカスタムルール開発のためのルール群です。カスタムルール実装時のショートハンドなどを提案してくれるので有効化しました。
RuboCop本体より提供されているので、以下のように.rubocop.yml
にてrubocop/cop/internal_affairs
をrequireするとルールを有効化できます。
require: - rubocop/cop/internal_affairs
終わりに
本記事ではRuboCopカスタムルールを導入して得られた効果について紹介しました。 これからカスタムルールを作成してみようか検討されている方の参考になれば幸いです。
最後に、ブックウォーカーではエンジニアを募集しています。興味がありましたらぜひ、ブックウォーカーの採用情報ページからご応募ください