Skip to content

Commit

Permalink
[FIX #1376] Add new Rails/Env cop
Browse files Browse the repository at this point in the history
  • Loading branch information
cdudas17 committed Oct 21, 2024
1 parent 2e619f3 commit 8c683bc
Show file tree
Hide file tree
Showing 5 changed files with 101 additions and 0 deletions.
1 change: 1 addition & 0 deletions changelog/new_env_cop.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* [#1376](https://github.com/rubocop/rubocop-rails/issues/1376): Add new `Rails/Env` cop. ([@cdudas17][])
5 changes: 5 additions & 0 deletions config/default.yml
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,11 @@ Rails/EnumUniqueness:
Include:
- app/models/**/*.rb

Rails/Env:
Description: 'Use Feature Flags or config instead of `Rails.env`.'
Enabled: false
VersionAdded: '<<next>>'

Rails/EnvLocal:
Description: 'Use `Rails.env.local?` instead of `Rails.env.development? || Rails.env.test?`.'
Enabled: pending
Expand Down
57 changes: 57 additions & 0 deletions lib/rubocop/cop/rails/env.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# frozen_string_literal: true

module RuboCop
module Cop
module Rails
# Checks for usage of `Rails.env` which can be replaced with Feature Flags
#
# @example
#
# # bad
# Rails.env.production? || Rails.env.local?
#
# # good
# if FeatureFlag.enabled?(:new_feature)
# # new feature code
# end
#
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&.predicate_method?

return if ALLOWED_LIST.include?(parent.method_name)

add_offense(parent)
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 @@ -48,6 +48,7 @@
require_relative 'rails/enum_hash'
require_relative 'rails/enum_syntax'
require_relative 'rails/enum_uniqueness'
require_relative 'rails/env'
require_relative 'rails/env_local'
require_relative 'rails/environment_comparison'
require_relative 'rails/environment_variable_access'
Expand Down
37 changes: 37 additions & 0 deletions spec/rubocop/cop/rails/env_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# frozen_string_literal: true

RSpec.describe RuboCop::Cop::Rails::Env, :config do
it 'registers an offense for `Rails.env.development? || Rails.env.test?`' do
expect_offense(<<~RUBY)
Rails.env.development? || Rails.env.test?
^^^^^^^^^^^^^^^ Use Feature Flags or config instead of `Rails.env`.
^^^^^^^^^^^^^^^^^^^^^^ Use Feature Flags or config instead of `Rails.env`.
RUBY
end

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

it 'does not register an offense for `Rails.env`' do
expect_no_offenses(<<~RUBY)
Rails.env
RUBY
end

it 'does not register an offense for valid Rails.env methods' do
expect_no_offenses(<<~RUBY)
Rails.env.capitalize
Rails.env.empty?
RUBY
end

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

0 comments on commit 8c683bc

Please sign in to comment.