Skip to content

Commit

Permalink
Add Rails/EnvLocal cop
Browse files Browse the repository at this point in the history
Enforces the use of `Rails.env.local?` instead of
`Rails.env.development? || Rails.env.test?`, as of Rails 7.1.
  • Loading branch information
sambostock committed Oct 2, 2023
1 parent c111a29 commit 3b894ec
Show file tree
Hide file tree
Showing 5 changed files with 116 additions and 0 deletions.
1 change: 1 addition & 0 deletions changelog/new_add_railsenvlocal_cop.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* [#906](https://github.com/rubocop/rubocop-rails/pull/906): Add `Rails/EnvLocal` cop. ([@sambostock][])
5 changes: 5 additions & 0 deletions config/default.yml
Original file line number Diff line number Diff line change
Expand Up @@ -430,6 +430,11 @@ Rails/EnumUniqueness:
Include:
- app/models/**/*.rb

Rails/EnvLocal:
Description: 'Use `Rails.env.local?` instead of `Rails.env.development? || Rails.env.test?`.'
Enabled: pending
VersionAdded: '<<next>>'

Rails/EnvironmentComparison:
Description: "Favor `Rails.env.production?` over `Rails.env == 'production'`."
Enabled: true
Expand Down
46 changes: 46 additions & 0 deletions lib/rubocop/cop/rails/env_local.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# frozen_string_literal: true

module RuboCop
module Cop
module Rails
# Checks for usage of `Rails.env.development? || Rails.env.test?` which
# can be replaced with `Rails.env.local?`, introduced in Rails 7.1.
#
# @example
#
# # bad
# Rails.env.development? || Rails.env.test?
#
# # good
# Rails.env.local?
#
class EnvLocal < Base
extend AutoCorrector
extend TargetRailsVersion

MSG = 'Use `Rails.env.local?` instead.'
LOCAL_ENVIRONMENTS = %i[development? test?].to_set.freeze

minimum_target_rails_version 7.1

# @!method rails_env_local_candidate?(node)
def_node_matcher :rails_env_local_candidate?, <<~PATTERN
(or
(send (send (const {cbase nil? } :Rails) :env) $%LOCAL_ENVIRONMENTS)
(send (send (const {cbase nil? } :Rails) :env) $%LOCAL_ENVIRONMENTS)
)
PATTERN

def on_or(node)
rails_env_local_candidate?(node) do |*environments|
next unless LOCAL_ENVIRONMENTS == environments.to_set

add_offense(node) do |corrector|
corrector.replace(node, 'Rails.env.local?')
end
end
end
end
end
end
end
1 change: 1 addition & 0 deletions lib/rubocop/cop/rails_cops.rb
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
require_relative 'rails/eager_evaluation_log_message'
require_relative 'rails/enum_hash'
require_relative 'rails/enum_uniqueness'
require_relative 'rails/env_local'
require_relative 'rails/environment_comparison'
require_relative 'rails/environment_variable_access'
require_relative 'rails/exit'
Expand Down
63 changes: 63 additions & 0 deletions spec/rubocop/cop/rails/env_local_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# frozen_string_literal: true

RSpec.describe RuboCop::Cop::Rails::EnvLocal, :config do
shared_examples 'non-local candidates' do
it 'registers no offenses for non-local `Rails.env._? || Rails.env._?`' do
expect_no_offenses(<<~RUBY)
Rails.env.development? || Rails.env.production?
Rails.env.test? || Rails.env.production?
Rails.env.production? || Rails.env.other?
RUBY
end

it 'registers no offenses for single `Rails.env._?`' do
expect_no_offenses(<<~RUBY)
Rails.env.development?
Rails.env.test?
Rails.env.production?
Rails.env.other?
RUBY
end
end

context 'In Rails >= 7.1', :rails71 do
it 'registers an offense for `Rails.env.development? || Rails.env.test?`' do
expect_offense(<<~RUBY)
Rails.env.development? || Rails.env.test?
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Use `Rails.env.local?` instead.
Rails.env.test? || Rails.env.development?
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Use `Rails.env.local?` instead.
RUBY

expect_correction(<<~RUBY)
Rails.env.local?
Rails.env.local?
RUBY
end

it 'registers no offenses for `Rails.env.local?`' do
expect_no_offenses(<<~RUBY)
Rails.env.local?
RUBY
end

include_examples 'non-local candidates'
end

context 'In Rails < 7.1', :rails70 do
it 'registers no offenses for `Rails.env.development? || Rails.env.test?`' do
expect_no_offenses(<<~RUBY)
Rails.env.development? || Rails.env.test?
Rails.env.test? || Rails.env.development?
RUBY
end

it 'registers no offenses for `Rails.env.local?`' do
expect_no_offenses(<<~RUBY)
Rails.env.local?
RUBY
end

include_examples 'non-local candidates'
end
end

0 comments on commit 3b894ec

Please sign in to comment.