forked from rubocop/rubocop-rails
-
Notifications
You must be signed in to change notification settings - Fork 0
/
unknown_env.rb
96 lines (82 loc) · 2.88 KB
/
unknown_env.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# frozen_string_literal: true
module RuboCop
module Cop
module Rails
# This cop checks that environments called with `Rails.env` predicates
# exist.
# By default the cop allows three environments which Rails ships with:
# `development`, `test`, and `production`.
# More can be added to the `Environments` config parameter.
#
# @example
# # bad
# Rails.env.proudction?
# Rails.env == 'proudction'
#
# # good
# Rails.env.production?
# Rails.env == 'production'
class UnknownEnv < Base
MSG = 'Unknown environment `%<name>s`.'
MSG_SIMILAR = 'Unknown environment `%<name>s`. ' \
'Did you mean `%<similar>s`?'
def_node_matcher :rails_env?, <<~PATTERN
(send
{(const nil? :Rails) (const (cbase) :Rails)}
:env)
PATTERN
def_node_matcher :unknown_environment_predicate?, <<~PATTERN
(send #rails_env? $#unknown_env_predicate?)
PATTERN
def_node_matcher :unknown_environment_equal?, <<~PATTERN
{
(send #rails_env? {:== :===} $(str #unknown_env_name?))
(send $(str #unknown_env_name?) {:== :===} #rails_env?)
}
PATTERN
def on_send(node)
unknown_environment_predicate?(node) do |name|
add_offense(node.loc.selector, message: message(name))
end
unknown_environment_equal?(node) do |str_node|
name = str_node.value
add_offense(str_node, message: message(name))
end
end
private
def collect_variable_like_names(_scope)
environments
end
def message(name)
name = name.to_s.chomp('?')
# DidYouMean::SpellChecker is not available in all versions of Ruby,
# and even on versions where it *is* available (>= 2.3), it is not
# always required correctly. So we do a feature check first. See:
# https://github.com/rubocop/rubocop/issues/7979
similar_names = if defined?(DidYouMean::SpellChecker)
spell_checker = DidYouMean::SpellChecker.new(dictionary: environments)
spell_checker.correct(name)
else
[]
end
if similar_names.empty?
format(MSG, name: name)
else
format(MSG_SIMILAR, name: name, similar: similar_names.join(', '))
end
end
def unknown_env_predicate?(name)
name = name.to_s
name.end_with?('?') &&
!environments.include?(name[0..-2])
end
def unknown_env_name?(name)
!environments.include?(name)
end
def environments
cop_config['Environments']
end
end
end
end
end