rubocop 0.77.0 → 0.81.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/LICENSE.txt +1 -1
- data/README.md +3 -3
- data/config/default.yml +136 -60
- data/lib/rubocop.rb +20 -4
- data/lib/rubocop/ast/builder.rb +45 -42
- data/lib/rubocop/ast/node.rb +11 -18
- data/lib/rubocop/ast/node/block_node.rb +5 -1
- data/lib/rubocop/ast/node/case_match_node.rb +56 -0
- data/lib/rubocop/ast/node/def_node.rb +11 -0
- data/lib/rubocop/ast/node/forward_args_node.rb +18 -0
- data/lib/rubocop/ast/node/regexp_node.rb +2 -4
- data/lib/rubocop/ast/traversal.rb +29 -10
- data/lib/rubocop/cli/command/auto_genenerate_config.rb +7 -7
- data/lib/rubocop/cli/command/show_cops.rb +11 -4
- data/lib/rubocop/comment_config.rb +6 -1
- data/lib/rubocop/config.rb +28 -10
- data/lib/rubocop/config_loader.rb +19 -19
- data/lib/rubocop/config_obsoletion.rb +6 -4
- data/lib/rubocop/config_validator.rb +55 -95
- data/lib/rubocop/cop/autocorrect_logic.rb +7 -4
- data/lib/rubocop/cop/bundler/insecure_protocol_source.rb +2 -2
- data/lib/rubocop/cop/cop.rb +3 -1
- data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +1 -1
- data/lib/rubocop/cop/generator.rb +3 -4
- data/lib/rubocop/cop/generator/configuration_injector.rb +1 -1
- data/lib/rubocop/cop/layout/array_alignment.rb +53 -10
- data/lib/rubocop/cop/layout/block_end_newline.rb +5 -3
- data/lib/rubocop/cop/layout/else_alignment.rb +8 -0
- data/lib/rubocop/cop/layout/empty_line_between_defs.rb +2 -1
- data/lib/rubocop/cop/layout/first_argument_indentation.rb +2 -2
- data/lib/rubocop/cop/layout/hash_alignment.rb +8 -4
- data/lib/rubocop/cop/layout/heredoc_indentation.rb +4 -4
- data/lib/rubocop/cop/layout/leading_comment_space.rb +33 -2
- data/lib/rubocop/cop/{metrics → layout}/line_length.rb +35 -79
- data/lib/rubocop/cop/layout/multiline_block_layout.rb +14 -5
- data/lib/rubocop/cop/layout/multiline_hash_brace_layout.rb +0 -4
- data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +1 -1
- data/lib/rubocop/cop/layout/space_around_operators.rb +49 -6
- data/lib/rubocop/cop/layout/space_before_block_braces.rb +17 -0
- data/lib/rubocop/cop/layout/space_before_first_arg.rb +8 -0
- data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +2 -9
- data/lib/rubocop/cop/lint/boolean_symbol.rb +12 -0
- data/lib/rubocop/cop/lint/debugger.rb +1 -1
- data/lib/rubocop/cop/lint/each_with_object_argument.rb +1 -1
- data/lib/rubocop/cop/lint/erb_new_arguments.rb +1 -1
- data/lib/rubocop/cop/lint/loop.rb +6 -4
- data/lib/rubocop/cop/lint/nested_method_definition.rb +2 -2
- data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +89 -0
- data/lib/rubocop/cop/lint/raise_exception.rb +39 -0
- data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +3 -3
- data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +13 -8
- data/lib/rubocop/cop/lint/safe_navigation_chain.rb +1 -1
- data/lib/rubocop/cop/lint/struct_new_override.rb +58 -0
- data/lib/rubocop/cop/lint/suppressed_exception.rb +12 -22
- data/lib/rubocop/cop/lint/unused_method_argument.rb +32 -6
- data/lib/rubocop/cop/lint/useless_setter_call.rb +4 -0
- data/lib/rubocop/cop/migration/department_name.rb +47 -6
- data/lib/rubocop/cop/mixin/alignment.rb +1 -1
- data/lib/rubocop/cop/mixin/configurable_enforced_style.rb +4 -0
- data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +6 -1
- data/lib/rubocop/cop/mixin/frozen_string_literal.rb +7 -7
- data/lib/rubocop/cop/mixin/hash_transform_method.rb +171 -0
- data/lib/rubocop/cop/mixin/line_length_help.rb +88 -0
- data/lib/rubocop/cop/mixin/method_complexity.rb +5 -0
- data/lib/rubocop/cop/mixin/rational_literal.rb +18 -0
- data/lib/rubocop/cop/mixin/statement_modifier.rb +2 -2
- data/lib/rubocop/cop/mixin/trailing_comma.rb +8 -12
- data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +1 -1
- data/lib/rubocop/cop/naming/method_name.rb +30 -0
- data/lib/rubocop/cop/naming/method_parameter_name.rb +1 -1
- data/lib/rubocop/cop/offense.rb +11 -0
- data/lib/rubocop/cop/registry.rb +7 -2
- data/lib/rubocop/cop/style/access_modifier_declarations.rb +26 -6
- data/lib/rubocop/cop/style/attr.rb +8 -0
- data/lib/rubocop/cop/style/block_delimiters.rb +60 -1
- data/lib/rubocop/cop/style/collection_methods.rb +2 -0
- data/lib/rubocop/cop/style/conditional_assignment.rb +2 -2
- data/lib/rubocop/cop/style/documentation.rb +43 -5
- data/lib/rubocop/cop/style/end_block.rb +6 -0
- data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +89 -11
- data/lib/rubocop/cop/style/guard_clause.rb +3 -2
- data/lib/rubocop/cop/style/hash_each_methods.rb +89 -0
- data/lib/rubocop/cop/style/hash_transform_keys.rb +83 -0
- data/lib/rubocop/cop/style/hash_transform_values.rb +83 -0
- data/lib/rubocop/cop/style/if_unless_modifier.rb +38 -3
- data/lib/rubocop/cop/style/infinite_loop.rb +1 -1
- data/lib/rubocop/cop/style/inverse_methods.rb +9 -5
- data/lib/rubocop/cop/style/lambda.rb +1 -0
- data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +7 -205
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +169 -0
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/require_parentheses.rb +54 -0
- data/lib/rubocop/cop/style/module_function.rb +56 -10
- data/lib/rubocop/cop/style/multiline_method_signature.rb +1 -1
- data/lib/rubocop/cop/style/multiline_when_then.rb +5 -1
- data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +4 -4
- data/lib/rubocop/cop/style/numeric_predicate.rb +4 -3
- data/lib/rubocop/cop/style/one_line_conditional.rb +3 -2
- data/lib/rubocop/cop/style/or_assignment.rb +3 -2
- data/lib/rubocop/cop/style/percent_literal_delimiters.rb +7 -7
- data/lib/rubocop/cop/style/redundant_condition.rb +17 -4
- data/lib/rubocop/cop/style/redundant_sort.rb +2 -2
- data/lib/rubocop/cop/style/symbol_array.rb +2 -2
- data/lib/rubocop/cop/style/ternary_parentheses.rb +1 -1
- data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +34 -22
- data/lib/rubocop/cop/style/trailing_comma_in_array_literal.rb +41 -0
- data/lib/rubocop/cop/style/trailing_comma_in_block_args.rb +85 -0
- data/lib/rubocop/cop/style/trailing_comma_in_hash_literal.rb +44 -0
- data/lib/rubocop/cop/style/trailing_underscore_variable.rb +7 -1
- data/lib/rubocop/cop/style/while_until_modifier.rb +1 -1
- data/lib/rubocop/cop/style/yoda_condition.rb +16 -1
- data/lib/rubocop/cop/variable_force.rb +4 -1
- data/lib/rubocop/formatter/base_formatter.rb +2 -2
- data/lib/rubocop/formatter/clang_style_formatter.rb +1 -1
- data/lib/rubocop/formatter/formatter_set.rb +1 -0
- data/lib/rubocop/formatter/json_formatter.rb +6 -5
- data/lib/rubocop/formatter/junit_formatter.rb +74 -0
- data/lib/rubocop/formatter/tap_formatter.rb +1 -1
- data/lib/rubocop/node_pattern.rb +97 -11
- data/lib/rubocop/options.rb +8 -8
- data/lib/rubocop/processed_source.rb +1 -1
- data/lib/rubocop/result_cache.rb +2 -0
- data/lib/rubocop/rspec/shared_contexts.rb +5 -0
- data/lib/rubocop/runner.rb +5 -1
- data/lib/rubocop/target_ruby.rb +151 -0
- data/lib/rubocop/version.rb +1 -1
- metadata +38 -10
- data/lib/rubocop/cop/lint/end_in_method.rb +0 -40
- data/lib/rubocop/cop/style/braces_around_hash_parameters.rb +0 -209
@@ -1,5 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# rubocop:disable Metrics/ModuleLength
|
3
4
|
module RuboCop
|
4
5
|
module AST
|
5
6
|
# Provides methods for traversing an AST.
|
@@ -18,15 +19,21 @@ module RuboCop
|
|
18
19
|
rational str sym regopt self lvar
|
19
20
|
ivar cvar gvar nth_ref back_ref cbase
|
20
21
|
arg restarg blockarg shadowarg
|
21
|
-
kwrestarg zsuper lambda redo retry
|
22
|
+
kwrestarg zsuper lambda redo retry
|
23
|
+
forward_args forwarded_args
|
24
|
+
match_var match_nil_pattern empty_else].freeze
|
22
25
|
ONE_CHILD_NODE = %i[splat kwsplat block_pass not break next
|
23
26
|
preexe postexe match_current_line defined?
|
24
|
-
arg_expr
|
27
|
+
arg_expr pin match_rest if_guard unless_guard
|
28
|
+
match_with_trailing_comma].freeze
|
25
29
|
MANY_CHILD_NODES = %i[dstr dsym xstr regexp array hash pair
|
26
30
|
mlhs masgn or_asgn and_asgn
|
27
31
|
undef alias args super yield or and
|
28
32
|
while_post until_post iflipflop eflipflop
|
29
|
-
match_with_lvasgn begin kwbegin return
|
33
|
+
match_with_lvasgn begin kwbegin return
|
34
|
+
in_match match_alt
|
35
|
+
match_as array_pattern array_pattern_with_tail
|
36
|
+
hash_pattern const_pattern].freeze
|
30
37
|
SECOND_CHILD_ONLY = %i[lvasgn ivasgn cvasgn gvasgn optarg kwarg
|
31
38
|
kwoptarg].freeze
|
32
39
|
|
@@ -171,13 +178,25 @@ module RuboCop
|
|
171
178
|
nil
|
172
179
|
end
|
173
180
|
|
174
|
-
alias on_rescue
|
175
|
-
alias on_resbody
|
176
|
-
alias on_ensure
|
177
|
-
alias on_for
|
178
|
-
alias on_when
|
179
|
-
alias
|
180
|
-
alias
|
181
|
+
alias on_rescue on_case
|
182
|
+
alias on_resbody on_case
|
183
|
+
alias on_ensure on_case
|
184
|
+
alias on_for on_case
|
185
|
+
alias on_when on_case
|
186
|
+
alias on_case_match on_case
|
187
|
+
alias on_in_pattern on_case
|
188
|
+
alias on_irange on_case
|
189
|
+
alias on_erange on_case
|
190
|
+
|
191
|
+
def on_numblock(node)
|
192
|
+
children = node.children
|
193
|
+
child = children[0]
|
194
|
+
send(:"on_#{child.type}", child)
|
195
|
+
return unless (child = children[2])
|
196
|
+
|
197
|
+
send(:"on_#{child.type}", child)
|
198
|
+
end
|
181
199
|
end
|
182
200
|
end
|
183
201
|
end
|
202
|
+
# rubocop:enable Metrics/ModuleLength
|
@@ -7,13 +7,13 @@ module RuboCop
|
|
7
7
|
class AutoGenerateConfig < Base
|
8
8
|
self.command_name = :auto_gen_config
|
9
9
|
|
10
|
-
PHASE_1 = 'Phase 1 of 2: run
|
10
|
+
PHASE_1 = 'Phase 1 of 2: run Layout/LineLength cop'
|
11
11
|
PHASE_2 = 'Phase 2 of 2: run all cops'
|
12
12
|
|
13
13
|
PHASE_1_OVERRIDDEN =
|
14
|
-
'(skipped because the default
|
14
|
+
'(skipped because the default Layout/LineLength:Max is overridden)'
|
15
15
|
PHASE_1_DISABLED =
|
16
|
-
'(skipped because
|
16
|
+
'(skipped because Layout/LineLength is disabled)'
|
17
17
|
|
18
18
|
def run
|
19
19
|
add_formatter
|
@@ -54,15 +54,15 @@ module RuboCop
|
|
54
54
|
end
|
55
55
|
|
56
56
|
def line_length_cop(config)
|
57
|
-
config.for_cop('
|
57
|
+
config.for_cop('Layout/LineLength')
|
58
58
|
end
|
59
59
|
|
60
|
-
# Do an initial run with only
|
61
|
-
# depend on
|
60
|
+
# Do an initial run with only Layout/LineLength so that cops that
|
61
|
+
# depend on Layout/LineLength:Max get the correct value for that
|
62
62
|
# parameter.
|
63
63
|
def run_line_length_cop
|
64
64
|
puts Rainbow(PHASE_1).yellow
|
65
|
-
@options[:only] = ['
|
65
|
+
@options[:only] = ['Layout/LineLength']
|
66
66
|
execute_runner
|
67
67
|
@options.delete(:only)
|
68
68
|
@config_store = ConfigStore.new
|
@@ -8,6 +8,13 @@ module RuboCop
|
|
8
8
|
class ShowCops < Base
|
9
9
|
self.command_name = :show_cops
|
10
10
|
|
11
|
+
def initialize(env)
|
12
|
+
super
|
13
|
+
|
14
|
+
# Load the configs so the require()s are done for custom cops
|
15
|
+
@config = @config_store.for(Dir.pwd)
|
16
|
+
end
|
17
|
+
|
11
18
|
def run
|
12
19
|
print_available_cops
|
13
20
|
end
|
@@ -15,8 +22,6 @@ module RuboCop
|
|
15
22
|
private
|
16
23
|
|
17
24
|
def print_available_cops
|
18
|
-
# Load the configs so the require()s are done for custom cops
|
19
|
-
@config_store.for(Dir.pwd)
|
20
25
|
registry = Cop::Cop.registry
|
21
26
|
show_all = @options[:show_cops].empty?
|
22
27
|
|
@@ -46,7 +51,9 @@ module RuboCop
|
|
46
51
|
|
47
52
|
def print_cop_details(cops)
|
48
53
|
cops.each do |cop|
|
49
|
-
|
54
|
+
if cop.new(@config).support_autocorrect?
|
55
|
+
puts '# Supports --auto-correct'
|
56
|
+
end
|
50
57
|
puts "#{cop.cop_name}:"
|
51
58
|
puts config_lines(cop)
|
52
59
|
puts
|
@@ -64,7 +71,7 @@ module RuboCop
|
|
64
71
|
end
|
65
72
|
|
66
73
|
def config_lines(cop)
|
67
|
-
cnf = @
|
74
|
+
cnf = @config.for_cop(cop)
|
68
75
|
cnf.to_yaml.lines.to_a.drop(1).map { |line| ' ' + line }
|
69
76
|
end
|
70
77
|
end
|
@@ -113,7 +113,8 @@ module RuboCop
|
|
113
113
|
def each_mentioned_cop
|
114
114
|
each_directive do |comment, cop_names, disabled|
|
115
115
|
comment_line_number = comment.loc.expression.line
|
116
|
-
single_line = !comment_only_line?(comment_line_number)
|
116
|
+
single_line = !comment_only_line?(comment_line_number) ||
|
117
|
+
directive_on_comment_line?(comment)
|
117
118
|
|
118
119
|
cop_names.each do |cop_name|
|
119
120
|
yield qualified_cop_name(cop_name), disabled, comment_line_number,
|
@@ -122,6 +123,10 @@ module RuboCop
|
|
122
123
|
end
|
123
124
|
end
|
124
125
|
|
126
|
+
def directive_on_comment_line?(comment)
|
127
|
+
comment.text[1..-1].match(COMMENT_DIRECTIVE_REGEXP)
|
128
|
+
end
|
129
|
+
|
125
130
|
def each_directive
|
126
131
|
return if processed_source.comments.nil?
|
127
132
|
|
data/lib/rubocop/config.rb
CHANGED
@@ -2,6 +2,9 @@
|
|
2
2
|
|
3
3
|
require 'pathname'
|
4
4
|
|
5
|
+
# FIXME: Moving Rails department code to RuboCop Rails will remove
|
6
|
+
# the following rubocop:disable comment.
|
7
|
+
# rubocop:disable Metrics/ClassLength
|
5
8
|
module RuboCop
|
6
9
|
# This class represents the configuration of the RuboCop application
|
7
10
|
# and all its cops. A Config is associated with a YAML configuration
|
@@ -13,6 +16,8 @@ module RuboCop
|
|
13
16
|
include FileFinder
|
14
17
|
extend Forwardable
|
15
18
|
|
19
|
+
CopConfig = Struct.new(:name, :metadata)
|
20
|
+
|
16
21
|
DEFAULT_RAILS_VERSION = 5.0
|
17
22
|
attr_reader :loaded_path
|
18
23
|
|
@@ -115,7 +120,7 @@ module RuboCop
|
|
115
120
|
relative_file_path = path_relative_to_config(file)
|
116
121
|
|
117
122
|
# Optimization to quickly decide if the given file is hidden (on the top
|
118
|
-
# level) and
|
123
|
+
# level) and cannot be matched by any pattern.
|
119
124
|
is_hidden = relative_file_path.start_with?('.') &&
|
120
125
|
!relative_file_path.start_with?('..')
|
121
126
|
return false if is_hidden && !possibly_include_hidden?
|
@@ -215,6 +220,18 @@ module RuboCop
|
|
215
220
|
nil
|
216
221
|
end
|
217
222
|
|
223
|
+
def pending_cops
|
224
|
+
keys.each_with_object([]) do |qualified_cop_name, pending_cops|
|
225
|
+
department = department_of(qualified_cop_name)
|
226
|
+
next if department && department['Enabled'] == false
|
227
|
+
|
228
|
+
cop_metadata = self[qualified_cop_name]
|
229
|
+
next unless cop_metadata['Enabled'] == 'pending'
|
230
|
+
|
231
|
+
pending_cops << CopConfig.new(qualified_cop_name, cop_metadata)
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
218
235
|
private
|
219
236
|
|
220
237
|
def target_rails_version_from_bundler_lock_file
|
@@ -235,17 +252,18 @@ module RuboCop
|
|
235
252
|
end
|
236
253
|
|
237
254
|
def enable_cop?(qualified_cop_name, cop_options)
|
238
|
-
|
239
|
-
department
|
240
|
-
|
241
|
-
unless department
|
242
|
-
department_options = self[cop_department]
|
243
|
-
if department_options && department_options['Enabled'] == false
|
244
|
-
return false
|
245
|
-
end
|
246
|
-
end
|
255
|
+
department = department_of(qualified_cop_name)
|
256
|
+
return false if department && department['Enabled'] == false
|
247
257
|
|
248
258
|
cop_options.fetch('Enabled') { !for_all_cops['DisabledByDefault'] }
|
249
259
|
end
|
260
|
+
|
261
|
+
def department_of(qualified_cop_name)
|
262
|
+
cop_department, cop_name = qualified_cop_name.split('/')
|
263
|
+
return nil if cop_name.nil?
|
264
|
+
|
265
|
+
self[cop_department]
|
266
|
+
end
|
250
267
|
end
|
251
268
|
end
|
269
|
+
# rubocop:enable Metrics/ClassLength
|
@@ -91,7 +91,9 @@ module RuboCop
|
|
91
91
|
else
|
92
92
|
add_excludes_from_files(config, config_file)
|
93
93
|
end
|
94
|
-
merge_with_default(config, config_file)
|
94
|
+
merge_with_default(config, config_file).tap do |merged_config|
|
95
|
+
warn_on_pending_cops(merged_config.pending_cops)
|
96
|
+
end
|
95
97
|
end
|
96
98
|
|
97
99
|
def add_excludes_from_files(config, config_file)
|
@@ -114,6 +116,22 @@ module RuboCop
|
|
114
116
|
end
|
115
117
|
end
|
116
118
|
|
119
|
+
def warn_on_pending_cops(pending_cops)
|
120
|
+
return if pending_cops.empty?
|
121
|
+
|
122
|
+
warn Rainbow('The following cops were added to RuboCop, but are not ' \
|
123
|
+
'configured. Please set Enabled to either `true` or ' \
|
124
|
+
'`false` in your `.rubocop.yml` file:').yellow
|
125
|
+
|
126
|
+
pending_cops.each do |cop|
|
127
|
+
warn Rainbow(
|
128
|
+
" - #{cop.name} (#{cop.metadata['VersionAdded']})"
|
129
|
+
).yellow
|
130
|
+
end
|
131
|
+
|
132
|
+
warn Rainbow('For more information: https://docs.rubocop.org/en/latest/versioning/').yellow
|
133
|
+
end
|
134
|
+
|
117
135
|
# Merges the given configuration with the default one. If
|
118
136
|
# AllCops:DisabledByDefault is true, it changes the Enabled params so
|
119
137
|
# that only cops from user configuration are enabled.
|
@@ -199,8 +217,6 @@ module RuboCop
|
|
199
217
|
raise(TypeError, "Malformed configuration in #{absolute_path}")
|
200
218
|
end
|
201
219
|
|
202
|
-
check_cop_config_value(hash)
|
203
|
-
|
204
220
|
hash
|
205
221
|
end
|
206
222
|
|
@@ -222,22 +238,6 @@ module RuboCop
|
|
222
238
|
end
|
223
239
|
end
|
224
240
|
|
225
|
-
def check_cop_config_value(hash, parent = nil)
|
226
|
-
hash.each do |key, value|
|
227
|
-
check_cop_config_value(value, key) if value.is_a?(Hash)
|
228
|
-
|
229
|
-
next unless %w[Enabled
|
230
|
-
Safe
|
231
|
-
SafeAutoCorrect
|
232
|
-
AutoCorrect].include?(key) && value.is_a?(String)
|
233
|
-
|
234
|
-
abort(
|
235
|
-
"Property #{Rainbow(key).yellow} of cop #{Rainbow(parent).yellow}" \
|
236
|
-
" is supposed to be a boolean and #{Rainbow(value).yellow} is not."
|
237
|
-
)
|
238
|
-
end
|
239
|
-
end
|
240
|
-
|
241
241
|
# Read the specified file, or exit with a friendly, concise message on
|
242
242
|
# stderr. Care is taken to use the standard OS exit code for a "file not
|
243
243
|
# found" error.
|
@@ -19,6 +19,7 @@ module RuboCop
|
|
19
19
|
'Layout/LeadingBlankLines' => 'Layout/LeadingEmptyLines',
|
20
20
|
'Layout/TrailingBlankLines' => 'Layout/TrailingEmptyLines',
|
21
21
|
'Lint/DuplicatedKey' => 'Lint/DuplicateHashKey',
|
22
|
+
'Lint/EndInMethod' => 'Style/EndBlock',
|
22
23
|
'Lint/HandleExceptions' => 'Lint/SuppressedException',
|
23
24
|
'Lint/MultipleCompare' => 'Lint/MultipleComparison',
|
24
25
|
'Lint/StringConversionInInterpolation' => 'Lint/RedundantStringCoercion',
|
@@ -48,7 +49,7 @@ module RuboCop
|
|
48
49
|
Style/VariableName Style/VariableNumber
|
49
50
|
Style/AccessorMethodName Style/AsciiIdentifiers],
|
50
51
|
'Layout' => %w[Lint/BlockAlignment Lint/EndAlignment
|
51
|
-
Lint/DefEndAlignment],
|
52
|
+
Lint/DefEndAlignment Metrics/LineLength],
|
52
53
|
'Lint' => 'Style/FlipFlop'
|
53
54
|
}.map do |new_department, old_names|
|
54
55
|
Array(old_names).map do |old_name|
|
@@ -69,7 +70,8 @@ module RuboCop
|
|
69
70
|
'Style/TrailingCommaInHashLiteral',
|
70
71
|
'Style/TrailingCommaInLiteral' => 'Style/TrailingCommaInArrayLiteral ' \
|
71
72
|
'and/or ' \
|
72
|
-
'Style/TrailingCommaInHashLiteral'
|
73
|
+
'Style/TrailingCommaInHashLiteral',
|
74
|
+
'Style/BracesAroundHashParameters' => nil
|
73
75
|
}.map do |old_name, other_cops|
|
74
76
|
if other_cops
|
75
77
|
more = ". Please use #{other_cops} instead".gsub(%r{[A-Z]\w+/\w+},
|
@@ -114,13 +116,13 @@ module RuboCop
|
|
114
116
|
cops: 'Style/IfUnlessModifier',
|
115
117
|
parameters: 'MaxLineLength',
|
116
118
|
alternative: '`Style/IfUnlessModifier: MaxLineLength` has been ' \
|
117
|
-
'removed. Use `
|
119
|
+
'removed. Use `Layout/LineLength: Max` instead'
|
118
120
|
},
|
119
121
|
{
|
120
122
|
cops: 'Style/WhileUntilModifier',
|
121
123
|
parameters: 'MaxLineLength',
|
122
124
|
alternative: '`Style/WhileUntilModifier: MaxLineLength` has been ' \
|
123
|
-
'removed. Use `
|
125
|
+
'removed. Use `Layout/LineLength: Max` instead'
|
124
126
|
},
|
125
127
|
{
|
126
128
|
cops: 'AllCops',
|
@@ -14,25 +14,19 @@ module RuboCop
|
|
14
14
|
VersionAdded VersionChanged VersionRemoved
|
15
15
|
Reference Safe SafeAutoCorrect].freeze
|
16
16
|
|
17
|
-
|
18
|
-
DEFAULT_RUBY_VERSION = 2.3
|
19
|
-
KNOWN_RUBIES = [2.3, 2.4, 2.5, 2.6, 2.7].freeze
|
20
|
-
OBSOLETE_RUBIES = {
|
21
|
-
1.9 => '0.50', 2.0 => '0.50', 2.1 => '0.58', 2.2 => '0.69'
|
22
|
-
}.freeze
|
23
|
-
RUBY_VERSION_FILENAME = '.ruby-version'
|
24
|
-
|
25
|
-
def_delegators :@config,
|
26
|
-
:smart_loaded_path, :for_all_cops, :find_file_upwards,
|
27
|
-
:base_dir_for_path_parameters, :bundler_lock_file_path
|
17
|
+
def_delegators :@config, :smart_loaded_path, :for_all_cops
|
28
18
|
|
29
19
|
def initialize(config)
|
30
20
|
@config = config
|
31
21
|
@config_obsoletion = ConfigObsoletion.new(config)
|
22
|
+
@target_ruby = TargetRuby.new(config)
|
32
23
|
end
|
33
24
|
|
34
25
|
def validate
|
35
|
-
|
26
|
+
check_cop_config_value(@config)
|
27
|
+
reject_conflicting_safe_settings
|
28
|
+
|
29
|
+
# Don't validate RuboCop's own files further. Avoids infinite recursion.
|
36
30
|
return if @config.internal?
|
37
31
|
|
38
32
|
valid_cop_names, invalid_cop_names = @config.keys.partition do |key|
|
@@ -41,7 +35,7 @@ module RuboCop
|
|
41
35
|
|
42
36
|
@config_obsoletion.reject_obsolete_cops_and_parameters
|
43
37
|
|
44
|
-
|
38
|
+
alert_about_unrecognized_cops(invalid_cop_names)
|
45
39
|
check_target_ruby
|
46
40
|
validate_parameter_names(valid_cop_names)
|
47
41
|
validate_enforced_styles(valid_cop_names)
|
@@ -50,23 +44,7 @@ module RuboCop
|
|
50
44
|
end
|
51
45
|
|
52
46
|
def target_ruby_version
|
53
|
-
|
54
|
-
if for_all_cops['TargetRubyVersion']
|
55
|
-
@target_ruby_version_source = :rubocop_yml
|
56
|
-
|
57
|
-
for_all_cops['TargetRubyVersion'].to_f
|
58
|
-
elsif target_ruby_version_from_version_file
|
59
|
-
@target_ruby_version_source = :ruby_version_file
|
60
|
-
|
61
|
-
target_ruby_version_from_version_file
|
62
|
-
elsif target_ruby_version_from_bundler_lock_file
|
63
|
-
@target_ruby_version_source = :bundler_lock_file
|
64
|
-
|
65
|
-
target_ruby_version_from_bundler_lock_file
|
66
|
-
else
|
67
|
-
DEFAULT_RUBY_VERSION
|
68
|
-
end
|
69
|
-
end
|
47
|
+
target_ruby.version
|
70
48
|
end
|
71
49
|
|
72
50
|
def validate_section_presence(name)
|
@@ -78,25 +56,30 @@ module RuboCop
|
|
78
56
|
|
79
57
|
private
|
80
58
|
|
59
|
+
attr_reader :target_ruby
|
60
|
+
|
81
61
|
def check_target_ruby
|
82
|
-
return if
|
62
|
+
return if target_ruby.supported?
|
83
63
|
|
84
|
-
|
64
|
+
source = target_ruby.source
|
65
|
+
last_version = target_ruby.rubocop_version_with_support
|
66
|
+
|
67
|
+
msg = if last_version
|
85
68
|
"RuboCop found unsupported Ruby version #{target_ruby_version} " \
|
86
|
-
"in #{
|
87
|
-
|
88
|
-
"#{OBSOLETE_RUBIES[target_ruby_version]}."
|
69
|
+
"in #{source}. #{target_ruby_version}-compatible " \
|
70
|
+
"analysis was dropped after version #{last_version}."
|
89
71
|
else
|
90
72
|
'RuboCop found unknown Ruby version ' \
|
91
|
-
"#{target_ruby_version.inspect} in #{
|
73
|
+
"#{target_ruby_version.inspect} in #{source}."
|
92
74
|
end
|
93
75
|
|
94
|
-
msg += "\nSupported versions: #{
|
76
|
+
msg += "\nSupported versions: #{TargetRuby.supported_versions.join(', ')}"
|
95
77
|
|
96
78
|
raise ValidationError, msg
|
97
79
|
end
|
98
80
|
|
99
|
-
def
|
81
|
+
def alert_about_unrecognized_cops(invalid_cop_names)
|
82
|
+
unknown_cops = []
|
100
83
|
invalid_cop_names.each do |name|
|
101
84
|
# There could be a custom cop with this name. If so, don't warn
|
102
85
|
next if Cop::Cop.registry.contains_cop_matching?([name])
|
@@ -106,9 +89,10 @@ module RuboCop
|
|
106
89
|
# to do so than to pass the value around to various methods.
|
107
90
|
next if name == 'inherit_mode'
|
108
91
|
|
109
|
-
|
110
|
-
|
92
|
+
unknown_cops << "unrecognized cop #{name} found in " \
|
93
|
+
"#{smart_loaded_path}"
|
111
94
|
end
|
95
|
+
raise ValidationError, unknown_cops.join(', ') if unknown_cops.any?
|
112
96
|
end
|
113
97
|
|
114
98
|
def validate_syntax_cop
|
@@ -176,71 +160,47 @@ module RuboCop
|
|
176
160
|
formats.all? { |format| valid.include?(format) }
|
177
161
|
end
|
178
162
|
|
179
|
-
def
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
when :bundler_lock_file
|
184
|
-
"`#{bundler_lock_file_path}`"
|
185
|
-
when :rubocop_yml
|
186
|
-
"`TargetRubyVersion` parameter (in #{smart_loaded_path})"
|
187
|
-
end
|
188
|
-
end
|
163
|
+
def reject_mutually_exclusive_defaults
|
164
|
+
disabled_by_default = for_all_cops['DisabledByDefault']
|
165
|
+
enabled_by_default = for_all_cops['EnabledByDefault']
|
166
|
+
return unless disabled_by_default && enabled_by_default
|
189
167
|
|
190
|
-
|
191
|
-
|
192
|
-
find_file_upwards(RUBY_VERSION_FILENAME, base_dir_for_path_parameters)
|
168
|
+
msg = 'Cops cannot be both enabled by default and disabled by default'
|
169
|
+
raise ValidationError, msg
|
193
170
|
end
|
194
171
|
|
195
|
-
def
|
196
|
-
|
197
|
-
|
172
|
+
def reject_conflicting_safe_settings
|
173
|
+
@config.each do |name, cop_config|
|
174
|
+
next unless cop_config.is_a?(Hash)
|
175
|
+
next unless cop_config['Safe'] == false &&
|
176
|
+
cop_config['SafeAutoCorrect'] == true
|
198
177
|
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
178
|
+
msg = 'Unsafe cops cannot have a safe auto-correction ' \
|
179
|
+
"(section #{name} in #{smart_loaded_path})"
|
180
|
+
raise ValidationError, msg
|
181
|
+
end
|
203
182
|
end
|
204
183
|
|
205
|
-
def
|
206
|
-
|
207
|
-
|
208
|
-
|
184
|
+
def check_cop_config_value(hash, parent = nil)
|
185
|
+
hash.each do |key, value|
|
186
|
+
check_cop_config_value(value, key) if value.is_a?(Hash)
|
187
|
+
|
188
|
+
next unless %w[Enabled
|
189
|
+
Safe
|
190
|
+
SafeAutoCorrect
|
191
|
+
AutoCorrect].include?(key) && value.is_a?(String)
|
192
|
+
|
193
|
+
next if key == 'Enabled' && value == 'pending'
|
209
194
|
|
210
|
-
|
211
|
-
lock_file_path = bundler_lock_file_path
|
212
|
-
return nil unless lock_file_path
|
213
|
-
|
214
|
-
in_ruby_section = false
|
215
|
-
File.foreach(lock_file_path) do |line|
|
216
|
-
# If ruby is in Gemfile.lock or gems.lock, there should be two lines
|
217
|
-
# towards the bottom of the file that look like:
|
218
|
-
# RUBY VERSION
|
219
|
-
# ruby W.X.YpZ
|
220
|
-
# We ultimately want to match the "ruby W.X.Y.pZ" line, but there's
|
221
|
-
# extra logic to make sure we only start looking once we've seen the
|
222
|
-
# "RUBY VERSION" line.
|
223
|
-
in_ruby_section ||= line.match(/^\s*RUBY\s*VERSION\s*$/)
|
224
|
-
next unless in_ruby_section
|
225
|
-
|
226
|
-
# We currently only allow this feature to work with MRI ruby. If jruby
|
227
|
-
# (or something else) is used by the project, it's lock file will have a
|
228
|
-
# line that looks like:
|
229
|
-
# RUBY VERSION
|
230
|
-
# ruby W.X.YpZ (jruby x.x.x.x)
|
231
|
-
# The regex won't match in this situation.
|
232
|
-
result = line.match(/^\s*ruby\s+(\d+\.\d+)[p.\d]*\s*$/)
|
233
|
-
return result.captures.first.to_f if result
|
195
|
+
raise ValidationError, msg_not_boolean(parent, key, value)
|
234
196
|
end
|
235
197
|
end
|
236
198
|
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
msg = 'Cops cannot be both enabled by default and disabled by default'
|
243
|
-
raise ValidationError, msg
|
199
|
+
# FIXME: Handling colors in exception messages like this is ugly.
|
200
|
+
def msg_not_boolean(parent, key, value)
|
201
|
+
"#{Rainbow('').reset}" \
|
202
|
+
"Property #{Rainbow(key).yellow} of cop #{Rainbow(parent).yellow}" \
|
203
|
+
" is supposed to be a boolean and #{Rainbow(value).yellow} is not."
|
244
204
|
end
|
245
205
|
end
|
246
206
|
end
|