Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog/new_rails_env_allowed_predicates_config.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* [#1617](https://github.com/rubocop/rubocop-rails/pull/1617): Add `AllowedPredicates` configuration option to `Rails/Env`. Users can now customize which predicate methods on `Rails.env` are exempt from the cop (e.g. to allow `Rails.env.local?` or a custom monkey-patched predicate). ([@dduugg][])
17 changes: 17 additions & 0 deletions config/default.yml
Original file line number Diff line number Diff line change
Expand Up @@ -472,6 +472,23 @@ Rails/Env:
Description: 'Use Feature Flags or config instead of `Rails.env`.'
Enabled: false
VersionAdded: '2.34'
VersionChanged: "<<next>>"
AllowedPredicates:
- acts_like_string?
- ascii_only?
- between?
- casecmp?
- empty?
- end_with?
- ends_with?
- exclude?
- include?
- is_utf8?
- match?
- start_with?
- starts_with?
- unicode_normalized?
- valid_encoding?

Rails/EnvLocal:
Description: 'Use `Rails.env.local?` instead of `Rails.env.development? || Rails.env.test?`.'
Expand Down
49 changes: 25 additions & 24 deletions lib/rubocop/cop/rails/env.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,24 @@
module RuboCop
module Cop
module Rails
# Checks for usage of `Rails.env` which can be replaced with Feature Flags
# Checks for usage of `Rails.env` which can be replaced with Feature Flags.
#
# Predicate methods listed in `AllowedPredicates` are not flagged. The default
# list covers the `String` / `StringInquirer` predicates that aren't
# environment-specific (e.g. `empty?`, `match?`, `between?`). The configured
# value fully replaces the default — to exempt an additional predicate
# such as `Rails.env.local?` (or a custom predicate monkey-patched onto
# the environment inquirer) while preserving the defaults, list them all
# together. Merge semantics can be opted into via RuboCop's `inherit_mode`.
#
# [source,yaml]
# ----
# Rails/Env:
# AllowedPredicates:
# - empty?
# - match?
# - local?
# ----
#
# @example
#
Expand All @@ -18,39 +35,23 @@ module Rails
class Env < Base
MSG = 'Use Feature Flags or config instead of `Rails.env`.'
RESTRICT_ON_SEND = %i[env].freeze
# This allow list is derived from:
# (Rails.env.methods - Object.instance_methods).select { |m| m.to_s.end_with?('?') }
# and then removing the environment specific methods like development?, test?, production?, local?
ALLOWED_LIST = Set.new(
%i[
unicode_normalized?
exclude?
empty?
acts_like_string?
include?
is_utf8?
casecmp?
match?
starts_with?
ends_with?
start_with?
end_with?
valid_encoding?
ascii_only?
between?
]
).freeze

def on_send(node)
return unless node.receiver&.const_name == 'Rails'

parent = node.parent
return unless parent.respond_to?(:predicate_method?) && parent.predicate_method?

return if ALLOWED_LIST.include?(parent.method_name)
return if allowed_predicates.include?(parent.method_name)

add_offense(parent)
end

private

def allowed_predicates
@allowed_predicates ||= Array(cop_config['AllowedPredicates']).to_set(&:to_sym)
end
end
end
end
Expand Down
22 changes: 22 additions & 0 deletions spec/rubocop/cop/rails/env_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,31 @@
RUBY
end

it 'registers an offense for `Rails.env.local?` under the default `AllowedPredicates`' do
expect_offense(<<~RUBY)
Rails.env.local?
^^^^^^^^^^^^^^^^ Use Feature Flags or config instead of `Rails.env`.
RUBY
end

it 'does not register an offense for unrelated config' do
expect_no_offenses(<<~RUBY)
Rails.environment
RUBY
end

context 'with `AllowedPredicates` overridden' do
let(:cop_config) { { 'AllowedPredicates' => ['local?'] } }

it 'does not register an offense for a predicate listed in the config' do
expect_no_offenses('raise unless Rails.env.local?')
end

it 'registers an offense for a predicate omitted from the config' do
expect_offense(<<~RUBY)
Rails.env.empty?
^^^^^^^^^^^^^^^^ Use Feature Flags or config instead of `Rails.env`.
RUBY
end
end
end