Skip to content

Commit 8c683bc

Browse files
committed
[FIX #1376] Add new Rails/Env cop
1 parent 2e619f3 commit 8c683bc

File tree

5 files changed

+101
-0
lines changed

5 files changed

+101
-0
lines changed

changelog/new_env_cop.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
* [#1376](https://github.com/rubocop/rubocop-rails/issues/1376): Add new `Rails/Env` cop. ([@cdudas17][])

config/default.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -441,6 +441,11 @@ Rails/EnumUniqueness:
441441
Include:
442442
- app/models/**/*.rb
443443

444+
Rails/Env:
445+
Description: 'Use Feature Flags or config instead of `Rails.env`.'
446+
Enabled: false
447+
VersionAdded: '<<next>>'
448+
444449
Rails/EnvLocal:
445450
Description: 'Use `Rails.env.local?` instead of `Rails.env.development? || Rails.env.test?`.'
446451
Enabled: pending

lib/rubocop/cop/rails/env.rb

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
# frozen_string_literal: true
2+
3+
module RuboCop
4+
module Cop
5+
module Rails
6+
# Checks for usage of `Rails.env` which can be replaced with Feature Flags
7+
#
8+
# @example
9+
#
10+
# # bad
11+
# Rails.env.production? || Rails.env.local?
12+
#
13+
# # good
14+
# if FeatureFlag.enabled?(:new_feature)
15+
# # new feature code
16+
# end
17+
#
18+
class Env < Base
19+
MSG = 'Use Feature Flags or config instead of `Rails.env`.'
20+
RESTRICT_ON_SEND = %i[env].freeze
21+
# This allow list is derived from:
22+
# (Rails.env.methods - Object.instance_methods).select { |m| m.to_s.end_with?('?') }
23+
# and then removing the environment specific methods like development?, test?, production?, local?
24+
ALLOWED_LIST = Set.new(
25+
%i[
26+
unicode_normalized?
27+
exclude?
28+
empty?
29+
acts_like_string?
30+
include?
31+
is_utf8?
32+
casecmp?
33+
match?
34+
starts_with?
35+
ends_with?
36+
start_with?
37+
end_with?
38+
valid_encoding?
39+
ascii_only?
40+
between?
41+
]
42+
).freeze
43+
44+
def on_send(node)
45+
return unless node.receiver&.const_name == 'Rails'
46+
47+
parent = node.parent
48+
return unless parent&.predicate_method?
49+
50+
return if ALLOWED_LIST.include?(parent.method_name)
51+
52+
add_offense(parent)
53+
end
54+
end
55+
end
56+
end
57+
end

lib/rubocop/cop/rails_cops.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
require_relative 'rails/enum_hash'
4949
require_relative 'rails/enum_syntax'
5050
require_relative 'rails/enum_uniqueness'
51+
require_relative 'rails/env'
5152
require_relative 'rails/env_local'
5253
require_relative 'rails/environment_comparison'
5354
require_relative 'rails/environment_variable_access'

spec/rubocop/cop/rails/env_spec.rb

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# frozen_string_literal: true
2+
3+
RSpec.describe RuboCop::Cop::Rails::Env, :config do
4+
it 'registers an offense for `Rails.env.development? || Rails.env.test?`' do
5+
expect_offense(<<~RUBY)
6+
Rails.env.development? || Rails.env.test?
7+
^^^^^^^^^^^^^^^ Use Feature Flags or config instead of `Rails.env`.
8+
^^^^^^^^^^^^^^^^^^^^^^ Use Feature Flags or config instead of `Rails.env`.
9+
RUBY
10+
end
11+
12+
it 'registers an offense for `Rails.env.production?`' do
13+
expect_offense(<<~RUBY)
14+
Rails.env.production?
15+
^^^^^^^^^^^^^^^^^^^^^ Use Feature Flags or config instead of `Rails.env`.
16+
RUBY
17+
end
18+
19+
it 'does not register an offense for `Rails.env`' do
20+
expect_no_offenses(<<~RUBY)
21+
Rails.env
22+
RUBY
23+
end
24+
25+
it 'does not register an offense for valid Rails.env methods' do
26+
expect_no_offenses(<<~RUBY)
27+
Rails.env.capitalize
28+
Rails.env.empty?
29+
RUBY
30+
end
31+
32+
it 'does not register an offense for unrelated config' do
33+
expect_no_offenses(<<~RUBY)
34+
Rails.environment
35+
RUBY
36+
end
37+
end

0 commit comments

Comments
 (0)