rubocop 0.55.0 → 0.56.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/config/default.yml +45 -0
- data/config/disabled.yml +4 -4
- data/config/enabled.yml +32 -16
- data/lib/rubocop.rb +8 -2
- data/lib/rubocop/cli.rb +4 -0
- data/lib/rubocop/comment_config.rb +36 -9
- data/lib/rubocop/config.rb +8 -1
- data/lib/rubocop/cop/generator.rb +4 -3
- data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +101 -29
- data/lib/rubocop/cop/{style → layout}/empty_line_after_guard_clause.rb +1 -1
- data/lib/rubocop/cop/layout/empty_line_between_defs.rb +5 -5
- data/lib/rubocop/cop/layout/first_parameter_indentation.rb +112 -2
- data/lib/rubocop/cop/layout/space_inside_reference_brackets.rb +8 -4
- data/lib/rubocop/cop/lint/erb_new_arguments.rb +107 -0
- data/lib/rubocop/cop/lint/literal_in_interpolation.rb +4 -0
- data/lib/rubocop/cop/lint/nested_percent_literal.rb +0 -8
- data/lib/rubocop/cop/lint/percent_string_array.rb +1 -1
- data/lib/rubocop/cop/lint/percent_symbol_array.rb +1 -1
- data/lib/rubocop/cop/lint/safe_navigation_chain.rb +3 -0
- data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +16 -3
- data/lib/rubocop/cop/lint/splat_keyword_arguments.rb +36 -0
- data/lib/rubocop/cop/lint/unneeded_cop_enable_directive.rb +20 -2
- data/lib/rubocop/cop/performance/inefficient_hash_search.rb +95 -0
- data/lib/rubocop/cop/performance/unneeded_sort.rb +41 -6
- data/lib/rubocop/cop/rails/assert_not.rb +44 -0
- data/lib/rubocop/cop/rails/blank.rb +34 -28
- data/lib/rubocop/cop/rails/create_table_with_timestamps.rb +1 -1
- data/lib/rubocop/cop/rails/has_many_or_has_one_dependent.rb +12 -2
- data/lib/rubocop/cop/rails/http_positional_arguments.rb +7 -7
- data/lib/rubocop/cop/rails/present.rb +31 -25
- data/lib/rubocop/cop/rails/refute_methods.rb +76 -0
- data/lib/rubocop/cop/rails/reversible_migration.rb +6 -4
- data/lib/rubocop/cop/rails/save_bang.rb +4 -1
- data/lib/rubocop/cop/style/braces_around_hash_parameters.rb +1 -10
- data/lib/rubocop/cop/style/command_literal.rb +15 -3
- data/lib/rubocop/cop/style/comment_annotation.rb +6 -1
- data/lib/rubocop/cop/style/empty_method.rb +6 -3
- data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +12 -2
- data/lib/rubocop/cop/style/method_missing_super.rb +34 -0
- data/lib/rubocop/cop/style/{method_missing.rb → missing_respond_to_missing.rb} +7 -29
- data/lib/rubocop/cop/style/parentheses_around_condition.rb +28 -2
- data/lib/rubocop/node_pattern.rb +1 -1
- data/lib/rubocop/processed_source.rb +12 -6
- data/lib/rubocop/result_cache.rb +9 -4
- data/lib/rubocop/rspec/shared_contexts.rb +4 -0
- data/lib/rubocop/runner.rb +8 -2
- data/lib/rubocop/target_finder.rb +40 -60
- data/lib/rubocop/version.rb +1 -1
- metadata +10 -4
@@ -10,6 +10,8 @@ module RuboCop
|
|
10
10
|
# This cop detects instances of rubocop:enable comments that can be
|
11
11
|
# removed.
|
12
12
|
#
|
13
|
+
# When comment enables all cops at once `rubocop:enable all`
|
14
|
+
# that cop checks whether any cop was actually enabled.
|
13
15
|
# @example
|
14
16
|
# # bad
|
15
17
|
# foo = 1
|
@@ -17,6 +19,19 @@ module RuboCop
|
|
17
19
|
#
|
18
20
|
# # good
|
19
21
|
# foo = 1
|
22
|
+
# @example
|
23
|
+
# # bad
|
24
|
+
# # rubocop:disable Metrics/LineLength
|
25
|
+
# baaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarrrrrrrrrrrrr
|
26
|
+
# # rubocop:enable Metrics/LineLength
|
27
|
+
# baz
|
28
|
+
# # rubocop:enable all
|
29
|
+
#
|
30
|
+
# # good
|
31
|
+
# # rubocop:disable Metrics/LineLength
|
32
|
+
# baaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarrrrrrrrrrrrr
|
33
|
+
# # rubocop:enable all
|
34
|
+
# baz
|
20
35
|
class UnneededCopEnableDirective < Cop
|
21
36
|
include RangeHelp
|
22
37
|
include SurroundingSpace
|
@@ -30,7 +45,7 @@ module RuboCop
|
|
30
45
|
add_offense(
|
31
46
|
[comment, name],
|
32
47
|
location: range_of_offense(comment, name),
|
33
|
-
message: format(MSG, cop: name)
|
48
|
+
message: format(MSG, cop: all_or_name(name))
|
34
49
|
)
|
35
50
|
end
|
36
51
|
end
|
@@ -90,8 +105,11 @@ module RuboCop
|
|
90
105
|
range_class.new(buffer, start, comment.loc.expression.end_pos)
|
91
106
|
end
|
92
107
|
end
|
108
|
+
|
109
|
+
def all_or_name(name)
|
110
|
+
name == 'all' ? 'all cops' : name
|
111
|
+
end
|
93
112
|
end
|
94
113
|
end
|
95
114
|
end
|
96
115
|
end
|
97
|
-
# rubocop:enable Lint/UnneededCopEnableDirective
|
@@ -0,0 +1,95 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Performance
|
6
|
+
# This cop checks for inefficient searching of keys and values within
|
7
|
+
# hashes.
|
8
|
+
#
|
9
|
+
# `Hash#keys.include?` is less efficient than `Hash#key?` because
|
10
|
+
# the former allocates a new array and then performs an O(n) search
|
11
|
+
# through that array, while `Hash#key?` does not allocate any array and
|
12
|
+
# performs a faster O(1) search for the key.
|
13
|
+
#
|
14
|
+
# `Hash#values.include?` is less efficient than `Hash#value?`. While they
|
15
|
+
# both perform an O(n) search through all of the values, calling `values`
|
16
|
+
# allocates a new array while using `value?` does not.
|
17
|
+
#
|
18
|
+
# @example
|
19
|
+
# # bad
|
20
|
+
# { a: 1, b: 2 }.keys.include?(:a)
|
21
|
+
# { a: 1, b: 2 }.keys.include?(:z)
|
22
|
+
# h = { a: 1, b: 2 }; h.keys.include?(100)
|
23
|
+
#
|
24
|
+
# # good
|
25
|
+
# { a: 1, b: 2 }.key?(:a)
|
26
|
+
# { a: 1, b: 2 }.has_key?(:z)
|
27
|
+
# h = { a: 1, b: 2 }; h.key?(100)
|
28
|
+
#
|
29
|
+
# # bad
|
30
|
+
# { a: 1, b: 2 }.values.include?(2)
|
31
|
+
# { a: 1, b: 2 }.values.include?('garbage')
|
32
|
+
# h = { a: 1, b: 2 }; h.values.include?(nil)
|
33
|
+
#
|
34
|
+
# # good
|
35
|
+
# { a: 1, b: 2 }.value?(2)
|
36
|
+
# { a: 1, b: 2 }.has_value?('garbage')
|
37
|
+
# h = { a: 1, b: 2 }; h.value?(nil)
|
38
|
+
#
|
39
|
+
class InefficientHashSearch < Cop
|
40
|
+
def_node_matcher :inefficient_include?, <<-PATTERN
|
41
|
+
(send $(send _ ${:keys :values}) :include? $_)
|
42
|
+
PATTERN
|
43
|
+
|
44
|
+
def on_send(node)
|
45
|
+
add_offense(node, message: msg(node)) if inefficient_include?(node)
|
46
|
+
end
|
47
|
+
|
48
|
+
def autocorrect(node)
|
49
|
+
lambda do |corrector|
|
50
|
+
# Replace `keys.include?` or `values.include?` with the appropriate
|
51
|
+
# `key?`/`value?` method.
|
52
|
+
corrector.replace(
|
53
|
+
node.loc.expression,
|
54
|
+
"#{autocorrect_hash_expression(node)}."\
|
55
|
+
"#{autocorrect_method(node)}(#{autocorrect_argument(node)})"
|
56
|
+
)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
def msg(node)
|
63
|
+
"Use `##{autocorrect_method(node)}` instead of "\
|
64
|
+
"`##{current_method(node)}.include?`."
|
65
|
+
end
|
66
|
+
|
67
|
+
def autocorrect_method(node)
|
68
|
+
case current_method(node)
|
69
|
+
when :keys then use_long_method ? 'has_key?' : 'key?'
|
70
|
+
when :values then use_long_method ? 'has_value?' : 'value?'
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def current_method(node)
|
75
|
+
node.children[0].method_name
|
76
|
+
end
|
77
|
+
|
78
|
+
def use_long_method
|
79
|
+
preferred_config = config.for_all_cops['Style/PreferredHashMethods']
|
80
|
+
preferred_config &&
|
81
|
+
preferred_config['EnforcedStyle'] == 'long' &&
|
82
|
+
preferred_config['Enabled']
|
83
|
+
end
|
84
|
+
|
85
|
+
def autocorrect_argument(node)
|
86
|
+
node.arguments.first.source
|
87
|
+
end
|
88
|
+
|
89
|
+
def autocorrect_hash_expression(node)
|
90
|
+
node.children[0].children[0].loc.expression.source
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
@@ -3,17 +3,52 @@
|
|
3
3
|
module RuboCop
|
4
4
|
module Cop
|
5
5
|
module Performance
|
6
|
-
# This cop is used to identify instances of sorting and then
|
7
|
-
# only the first or last element.
|
6
|
+
# This cop is used to identify instances of sorting and then
|
7
|
+
# taking only the first or last element. The same behavior can
|
8
|
+
# be accomplished without a relatively expensive sort by using
|
9
|
+
# `Enumerable#min` instead of sorting and taking the first
|
10
|
+
# element and `Enumerable#max` instead of sorting and taking the
|
11
|
+
# last element. Similarly, `Enumerable#min_by` and
|
12
|
+
# `Enumerable#max_by` can replace `Enumerable#sort_by` calls
|
13
|
+
# after which only the first or last element is used.
|
8
14
|
#
|
9
15
|
# @example
|
10
16
|
# # bad
|
11
|
-
# [].sort.first
|
12
|
-
# [].
|
17
|
+
# [2, 1, 3].sort.first
|
18
|
+
# [2, 1, 3].sort[0]
|
19
|
+
# [2, 1, 3].sort.at(0)
|
20
|
+
# [2, 1, 3].sort.slice(0)
|
13
21
|
#
|
14
22
|
# # good
|
15
|
-
# [].min
|
16
|
-
#
|
23
|
+
# [2, 1, 3].min
|
24
|
+
#
|
25
|
+
# # bad
|
26
|
+
# [2, 1, 3].sort.last
|
27
|
+
# [2, 1, 3].sort[-1]
|
28
|
+
# [2, 1, 3].sort.at(-1)
|
29
|
+
# [2, 1, 3].sort.slice(-1)
|
30
|
+
#
|
31
|
+
# # good
|
32
|
+
# [2, 1, 3].max
|
33
|
+
#
|
34
|
+
# # bad
|
35
|
+
# arr.sort_by(&:foo).first
|
36
|
+
# arr.sort_by(&:foo)[0]
|
37
|
+
# arr.sort_by(&:foo).at(0)
|
38
|
+
# arr.sort_by(&:foo).slice(0)
|
39
|
+
#
|
40
|
+
# # good
|
41
|
+
# arr.min_by(&:foo)
|
42
|
+
#
|
43
|
+
# # bad
|
44
|
+
# arr.sort_by(&:foo).last
|
45
|
+
# arr.sort_by(&:foo)[-1]
|
46
|
+
# arr.sort_by(&:foo).at(-1)
|
47
|
+
# arr.sort_by(&:foo).slice(-1)
|
48
|
+
#
|
49
|
+
# # good
|
50
|
+
# arr.max_by(&:foo)
|
51
|
+
#
|
17
52
|
class UnneededSort < Cop
|
18
53
|
include RangeHelp
|
19
54
|
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Rails
|
6
|
+
#
|
7
|
+
# Use `assert_not` instead of `assert !`.
|
8
|
+
#
|
9
|
+
# @example
|
10
|
+
# # bad
|
11
|
+
# assert !x
|
12
|
+
#
|
13
|
+
# # good
|
14
|
+
# assert_not x
|
15
|
+
#
|
16
|
+
class AssertNot < RuboCop::Cop::Cop
|
17
|
+
MSG = 'Prefer `assert_not` over `assert !`.'.freeze
|
18
|
+
|
19
|
+
def_node_matcher :offensive?, '(send nil? :assert (send ... :!))'
|
20
|
+
|
21
|
+
def on_send(node)
|
22
|
+
add_offense(node) if offensive?(node)
|
23
|
+
end
|
24
|
+
|
25
|
+
def autocorrect(node)
|
26
|
+
expression = node.loc.expression
|
27
|
+
|
28
|
+
lambda do |corrector|
|
29
|
+
corrector.replace(
|
30
|
+
expression,
|
31
|
+
corrected_source(expression.source)
|
32
|
+
)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def corrected_source(source)
|
39
|
+
source.gsub(/^assert(\(| ) *! */, 'assert_not\\1')
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -3,40 +3,46 @@
|
|
3
3
|
module RuboCop
|
4
4
|
module Cop
|
5
5
|
module Rails
|
6
|
-
# This
|
7
|
-
#
|
8
|
-
# NilOrEmpty: Convert checks for `nil` or `empty?` to `blank?`
|
9
|
-
# NotPresent: Convert usages of not `present?` to `blank?`
|
10
|
-
# UnlessPresent: Convert usages of `unless` `present?` to `blank?`
|
6
|
+
# This cop checks for code that can be written with simpler conditionals
|
7
|
+
# using `Object#blank?` defined by Active Support.
|
11
8
|
#
|
12
|
-
# @example
|
13
|
-
# #
|
14
|
-
# # bad
|
15
|
-
# foo.nil? || foo.empty?
|
16
|
-
# foo == nil || foo.empty?
|
9
|
+
# @example NilOrEmpty: true (default)
|
10
|
+
# # Converts usages of `nil? || empty?` to `blank?`
|
17
11
|
#
|
18
|
-
#
|
19
|
-
#
|
12
|
+
# # bad
|
13
|
+
# foo.nil? || foo.empty?
|
14
|
+
# foo == nil || foo.empty?
|
20
15
|
#
|
21
|
-
# #
|
22
|
-
#
|
23
|
-
# !foo.present?
|
16
|
+
# # good
|
17
|
+
# foo.blank?
|
24
18
|
#
|
25
|
-
#
|
26
|
-
#
|
19
|
+
# @example NotPresent: true (default)
|
20
|
+
# # Converts usages of `!present?` to `blank?`
|
27
21
|
#
|
28
|
-
# #
|
29
|
-
#
|
30
|
-
# something unless foo.present?
|
31
|
-
# unless foo.present?
|
32
|
-
# something
|
33
|
-
# end
|
22
|
+
# # bad
|
23
|
+
# !foo.present?
|
34
24
|
#
|
35
|
-
#
|
36
|
-
#
|
37
|
-
#
|
38
|
-
#
|
39
|
-
#
|
25
|
+
# # good
|
26
|
+
# foo.blank?
|
27
|
+
#
|
28
|
+
# @example UnlessPresent: true (default)
|
29
|
+
# # Converts usages of `unless present?` to `if blank?`
|
30
|
+
#
|
31
|
+
# # bad
|
32
|
+
# something unless foo.present?
|
33
|
+
#
|
34
|
+
# # good
|
35
|
+
# something if foo.blank?
|
36
|
+
#
|
37
|
+
# # bad
|
38
|
+
# unless foo.present?
|
39
|
+
# something
|
40
|
+
# end
|
41
|
+
#
|
42
|
+
# # good
|
43
|
+
# if foo.blank?
|
44
|
+
# something
|
45
|
+
# end
|
40
46
|
class Blank < Cop
|
41
47
|
MSG_NIL_OR_EMPTY = 'Use `%<prefer>s` instead of `%<current>s`.'.freeze
|
42
48
|
MSG_NOT_PRESENT = 'Use `%<prefer>s` instead of `%<current>s`.'.freeze
|
@@ -51,7 +51,7 @@ module RuboCop
|
|
51
51
|
PATTERN
|
52
52
|
|
53
53
|
def_node_matcher :create_table_with_timestamps_proc?, <<-PATTERN
|
54
|
-
(send nil? :create_table (sym _) (block-pass (sym :timestamps)))
|
54
|
+
(send nil? :create_table (sym _) ... (block-pass (sym :timestamps)))
|
55
55
|
PATTERN
|
56
56
|
|
57
57
|
def_node_search :timestamps_included?, <<-PATTERN
|
@@ -63,8 +63,18 @@ module RuboCop
|
|
63
63
|
|
64
64
|
n = node.parent.begin_type? ? node.parent.parent : node.parent
|
65
65
|
|
66
|
-
|
67
|
-
|
66
|
+
contain_valid_options_in_with_options_block?(n)
|
67
|
+
end
|
68
|
+
|
69
|
+
def contain_valid_options_in_with_options_block?(node)
|
70
|
+
if with_options_block(node)
|
71
|
+
return true if valid_options?(with_options_block(node))
|
72
|
+
|
73
|
+
return false unless node.parent
|
74
|
+
|
75
|
+
return true if contain_valid_options_in_with_options_block?(
|
76
|
+
node.parent.parent
|
77
|
+
)
|
68
78
|
end
|
69
79
|
|
70
80
|
false
|
@@ -22,7 +22,7 @@ module RuboCop
|
|
22
22
|
MSG = 'Use keyword arguments instead of ' \
|
23
23
|
'positional arguments for http call: `%<verb>s`.'.freeze
|
24
24
|
KEYWORD_ARGS = %i[
|
25
|
-
|
25
|
+
method params session body flash xhr as
|
26
26
|
].freeze
|
27
27
|
HTTP_METHODS = %i[get post put patch delete head].freeze
|
28
28
|
|
@@ -41,11 +41,11 @@ module RuboCop
|
|
41
41
|
end
|
42
42
|
end
|
43
43
|
|
44
|
-
# given a pre Rails 5 method: get :new, user_id: @user.id, {}
|
44
|
+
# given a pre Rails 5 method: get :new, {user_id: @user.id}, {}
|
45
45
|
#
|
46
46
|
# @return lambda of auto correct procedure
|
47
47
|
# the result should look like:
|
48
|
-
# get :new, params: { user_id: @user.id },
|
48
|
+
# get :new, params: { user_id: @user.id }, session: {}
|
49
49
|
# the http_method is the method used to call the controller
|
50
50
|
# the controller node can be a symbol, method, object or string
|
51
51
|
# that represents the path/action on the Rails controller
|
@@ -56,14 +56,14 @@ module RuboCop
|
|
56
56
|
|
57
57
|
controller_action = http_path.source
|
58
58
|
params = convert_hash_data(data.first, 'params')
|
59
|
-
|
59
|
+
session = convert_hash_data(data.last, 'session') if data.size > 1
|
60
60
|
# the range of the text to replace, which is the whole line
|
61
61
|
code_to_replace = node.loc.expression
|
62
62
|
# what to replace with
|
63
63
|
format = parentheses_format(node)
|
64
64
|
new_code = format(format, name: node.method_name,
|
65
65
|
action: controller_action,
|
66
|
-
params: params,
|
66
|
+
params: params, session: session)
|
67
67
|
->(corrector) { corrector.replace(code_to_replace, new_code) }
|
68
68
|
end
|
69
69
|
|
@@ -103,9 +103,9 @@ module RuboCop
|
|
103
103
|
|
104
104
|
def parentheses_format(node)
|
105
105
|
if parentheses?(node)
|
106
|
-
'%<name>s(%<action>s%<params>s%<
|
106
|
+
'%<name>s(%<action>s%<params>s%<session>s)'
|
107
107
|
else
|
108
|
-
'%<name>s %<action>s%<params>s%<
|
108
|
+
'%<name>s %<action>s%<params>s%<session>s'
|
109
109
|
end
|
110
110
|
end
|
111
111
|
end
|
@@ -3,37 +3,43 @@
|
|
3
3
|
module RuboCop
|
4
4
|
module Cop
|
5
5
|
module Rails
|
6
|
-
# This
|
7
|
-
#
|
8
|
-
# NotNilAndNotEmpty: Convert checks for not `nil` and `not empty?`
|
9
|
-
# to `present?`
|
10
|
-
# NotBlank: Convert usages of not `blank?` to `present?`
|
11
|
-
# UnlessBlank: Convert usages of `unless` `blank?` to `if` `present?`
|
6
|
+
# This cop checks for code that can be written with simpler conditionals
|
7
|
+
# using `Object#present?` defined by Active Support.
|
12
8
|
#
|
13
|
-
#
|
14
|
-
# # NotNilAndNotEmpty: true
|
15
|
-
# # bad
|
16
|
-
# !foo.nil? && !foo.empty?
|
17
|
-
# foo != nil && !foo.empty?
|
18
|
-
# !foo.blank?
|
9
|
+
# simpler conditionals.
|
19
10
|
#
|
20
|
-
#
|
21
|
-
#
|
11
|
+
# @example NotNilAndNotEmpty: true (default)
|
12
|
+
# # Converts usages of `!nil? && !empty?` to `present?`
|
22
13
|
#
|
23
|
-
# #
|
24
|
-
#
|
25
|
-
# !foo.blank?
|
26
|
-
# not foo.blank?
|
14
|
+
# # bad
|
15
|
+
# !foo.nil? && !foo.empty?
|
27
16
|
#
|
28
|
-
#
|
29
|
-
#
|
17
|
+
# # bad
|
18
|
+
# foo != nil && !foo.empty?
|
30
19
|
#
|
31
|
-
# #
|
32
|
-
#
|
33
|
-
# something unless foo.blank?
|
20
|
+
# # good
|
21
|
+
# foo.present?
|
34
22
|
#
|
35
|
-
#
|
36
|
-
#
|
23
|
+
# @example NotBlank: true (default)
|
24
|
+
# # Converts usages of `!blank?` to `present?`
|
25
|
+
#
|
26
|
+
# # bad
|
27
|
+
# !foo.blank?
|
28
|
+
#
|
29
|
+
# # bad
|
30
|
+
# not foo.blank?
|
31
|
+
#
|
32
|
+
# # good
|
33
|
+
# foo.present?
|
34
|
+
#
|
35
|
+
# @example UnlessBlank: true (default)
|
36
|
+
# # Converts usages of `unless blank?` to `if present?`
|
37
|
+
#
|
38
|
+
# # bad
|
39
|
+
# something unless foo.blank?
|
40
|
+
#
|
41
|
+
# # good
|
42
|
+
# something if foo.present?
|
37
43
|
class Present < Cop
|
38
44
|
MSG_NOT_BLANK = 'Use `%<prefer>s` instead of `%<current>s`.'.freeze
|
39
45
|
MSG_EXISTS_AND_NOT_EMPTY = 'Use `%<prefer>s` instead of ' \
|