👮
RuboCopのカスタムルールで、Time.currentに促す
はじめに
Railsアプリのレビューで、「ここではTime.current(またはTime.zone.now)をよく使ってます」というコメントをもらったことはありませんか?
新しい案件に参画したとき、空気を読まないといけない部分かな思っていましたが、RuboCopのカスタムルールを追加して解決できないかやってみました。
(個人的にはTime.current
Time.zone.now
のどちらでもいいかなと思ってます)
試した環境
- Ruby 3.1.2
- Rails 7.0.3
- RuboCop 1.30.1
- RuboCop Rails 2.14.2
カスタムルールの追加
Time.zone.now
をNGとし、Time.current
にする例です。
カスタムルールのファイルを作成
lib/custom_cops/no_time_zone_now.rb
return unless defined?(::RuboCop)
module CustomCops
class NoTimeZoneNow < ::RuboCop::Cop::Base
extend RuboCop::Cop::AutoCorrector
def_node_matcher :time_zone_now_call?, '(send (send (const nil :Time) :zone) :now)'
MSG = '`Time.zone.now`ではなく`Time.current`でお願いします。'
RESTRICT_ON_SEND = [:now].freeze
def on_send(node)
return if time_zone_now_call?(node)
add_offense(node) do |rewriter|
rewriter.replace(node, 'Time.current')
end
end
end
end
カスタムルールを有効にする
.rubocop.yml
require:
- rubocop-rails
+ - ./lib/custom_cops/no_time_zone_now.rb
+CustomCops/NoTimeZoneNow:
+ Enabled: true
実行結果
$ bundle exec rubocop custom_cop_test.rb
Inspecting 1 file
C
Offenses:
custom_cop_test.rb:3:7: C: [Correctable] CustomCops/NoTimeZoneNow: Time.zone.nowではなくTime.currentでお願いします。
now = Time.zone.now
^^^^^^^^^^^^^
1 file inspected, 1 offense detected, 1 offense autocorrectable
$ bundle exec rubocop -a custom_cop_test.rb
Inspecting 1 file
C
Offenses:
custom_cop_test.rb:3:7: C: [Corrected] CustomCops/NoTimeZoneNow: Time.zone.nowではなくTime.currentでお願いします。
now = Time.zone.now
^^^^^^^^^^^^^
1 file inspected, 1 offense detected, 1 offense corrected
まとめ
RuboCopのカスタムルールを追加することで、Time.zone.now
をNGとし、Time.current
にすることができました。
今回のように仕組みで解決できる方法が思いついたとき、試しにやって改善できればいいですね。
Discussion