rubocop 1.39.0 → 1.44.1
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 +2 -2
- data/config/default.yml +149 -11
- data/exe/rubocop +1 -1
- data/lib/rubocop/cli.rb +1 -1
- data/lib/rubocop/comment_config.rb +5 -0
- data/lib/rubocop/config.rb +39 -15
- data/lib/rubocop/config_loader.rb +26 -20
- data/lib/rubocop/config_loader_resolver.rb +6 -2
- data/lib/rubocop/config_validator.rb +1 -1
- data/lib/rubocop/cop/badge.rb +9 -4
- data/lib/rubocop/cop/base.rb +84 -74
- data/lib/rubocop/cop/commissioner.rb +8 -3
- data/lib/rubocop/cop/cop.rb +29 -29
- data/lib/rubocop/cop/corrector.rb +30 -10
- data/lib/rubocop/cop/correctors/multiline_literal_brace_corrector.rb +22 -6
- data/lib/rubocop/cop/correctors/ordered_gem_corrector.rb +1 -6
- data/lib/rubocop/cop/gemspec/dependency_version.rb +16 -18
- data/lib/rubocop/cop/gemspec/development_dependencies.rb +107 -0
- data/lib/rubocop/cop/internal_affairs/cop_description.rb +3 -1
- data/lib/rubocop/cop/internal_affairs/lambda_or_proc.rb +46 -0
- data/lib/rubocop/cop/internal_affairs/redundant_let_rubocop_config_new.rb +11 -3
- data/lib/rubocop/cop/internal_affairs.rb +1 -0
- data/lib/rubocop/cop/layout/block_end_newline.rb +7 -1
- data/lib/rubocop/cop/layout/class_structure.rb +32 -11
- data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +2 -6
- data/lib/rubocop/cop/layout/comment_indentation.rb +3 -1
- data/lib/rubocop/cop/layout/empty_lines.rb +2 -0
- data/lib/rubocop/cop/layout/extra_spacing.rb +10 -6
- data/lib/rubocop/cop/layout/first_array_element_line_break.rb +38 -2
- data/lib/rubocop/cop/layout/first_hash_element_line_break.rb +49 -2
- data/lib/rubocop/cop/layout/first_method_argument_line_break.rb +61 -2
- data/lib/rubocop/cop/layout/first_method_parameter_line_break.rb +52 -2
- data/lib/rubocop/cop/layout/heredoc_indentation.rb +6 -9
- data/lib/rubocop/cop/layout/indentation_style.rb +7 -2
- data/lib/rubocop/cop/layout/line_continuation_leading_space.rb +5 -0
- data/lib/rubocop/cop/layout/line_continuation_spacing.rb +11 -5
- data/lib/rubocop/cop/layout/line_length.rb +2 -0
- data/lib/rubocop/cop/layout/multiline_array_line_breaks.rb +51 -2
- data/lib/rubocop/cop/layout/multiline_block_layout.rb +1 -1
- data/lib/rubocop/cop/layout/multiline_hash_key_line_breaks.rb +49 -2
- data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +53 -2
- data/lib/rubocop/cop/layout/multiline_method_parameter_line_breaks.rb +58 -2
- data/lib/rubocop/cop/layout/redundant_line_break.rb +2 -2
- data/lib/rubocop/cop/layout/space_around_keyword.rb +1 -1
- data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +0 -2
- data/lib/rubocop/cop/layout/trailing_empty_lines.rb +1 -1
- data/lib/rubocop/cop/layout/trailing_whitespace.rb +11 -4
- data/lib/rubocop/cop/lint/ambiguous_block_association.rb +1 -1
- data/lib/rubocop/cop/lint/ambiguous_operator.rb +4 -0
- data/lib/rubocop/cop/lint/assignment_in_condition.rb +11 -1
- data/lib/rubocop/cop/lint/constant_resolution.rb +4 -0
- data/lib/rubocop/cop/lint/debugger.rb +3 -1
- data/lib/rubocop/cop/lint/deprecated_class_methods.rb +62 -112
- data/lib/rubocop/cop/lint/deprecated_constants.rb +8 -1
- data/lib/rubocop/cop/lint/duplicate_branch.rb +0 -2
- data/lib/rubocop/cop/lint/duplicate_methods.rb +19 -8
- data/lib/rubocop/cop/lint/else_layout.rb +2 -6
- data/lib/rubocop/cop/lint/empty_block.rb +1 -5
- data/lib/rubocop/cop/lint/empty_conditional_body.rb +1 -1
- data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +11 -7
- data/lib/rubocop/cop/lint/heredoc_method_call_position.rb +15 -17
- data/lib/rubocop/cop/lint/interpolation_check.rb +4 -3
- data/lib/rubocop/cop/lint/mixed_regexp_capture_types.rb +1 -0
- data/lib/rubocop/cop/lint/non_atomic_file_operation.rb +10 -5
- data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +19 -0
- data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +5 -0
- data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +15 -3
- data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +1 -1
- data/lib/rubocop/cop/lint/redundant_require_statement.rb +11 -1
- data/lib/rubocop/cop/lint/regexp_as_condition.rb +6 -0
- data/lib/rubocop/cop/lint/require_parentheses.rb +3 -1
- data/lib/rubocop/cop/lint/safe_navigation_chain.rb +10 -12
- data/lib/rubocop/cop/lint/send_with_mixin_argument.rb +5 -4
- data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +4 -3
- data/lib/rubocop/cop/lint/unused_method_argument.rb +2 -1
- data/lib/rubocop/cop/lint/useless_method_definition.rb +3 -3
- data/lib/rubocop/cop/lint/useless_rescue.rb +85 -0
- data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +14 -4
- data/lib/rubocop/cop/lint/void.rb +25 -16
- data/lib/rubocop/cop/metrics/block_length.rb +9 -4
- data/lib/rubocop/cop/metrics/block_nesting.rb +1 -1
- data/lib/rubocop/cop/metrics/class_length.rb +10 -5
- data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +1 -1
- data/lib/rubocop/cop/metrics/method_length.rb +9 -4
- data/lib/rubocop/cop/metrics/module_length.rb +10 -5
- data/lib/rubocop/cop/metrics/parameter_lists.rb +27 -0
- data/lib/rubocop/cop/metrics/perceived_complexity.rb +1 -1
- data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +3 -6
- data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +6 -3
- data/lib/rubocop/cop/mixin/alignment.rb +2 -2
- data/lib/rubocop/cop/mixin/allowed_identifiers.rb +2 -2
- data/lib/rubocop/cop/mixin/annotation_comment.rb +13 -6
- data/lib/rubocop/cop/mixin/configurable_enforced_style.rb +21 -9
- data/lib/rubocop/cop/mixin/first_element_line_break.rb +11 -7
- data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +59 -6
- data/lib/rubocop/cop/mixin/line_length_help.rb +11 -2
- data/lib/rubocop/cop/mixin/method_complexity.rb +5 -3
- data/lib/rubocop/cop/mixin/multiline_element_line_breaks.rb +5 -3
- data/lib/rubocop/cop/mixin/percent_array.rb +3 -5
- data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +1 -1
- data/lib/rubocop/cop/mixin/require_library.rb +2 -0
- data/lib/rubocop/cop/mixin/rescue_node.rb +3 -3
- data/lib/rubocop/cop/mixin/statement_modifier.rb +16 -1
- data/lib/rubocop/cop/naming/block_forwarding.rb +5 -1
- data/lib/rubocop/cop/naming/class_and_module_camel_case.rb +2 -0
- data/lib/rubocop/cop/naming/inclusive_language.rb +4 -1
- data/lib/rubocop/cop/registry.rb +63 -43
- data/lib/rubocop/cop/security/compound_hash.rb +2 -1
- data/lib/rubocop/cop/style/access_modifier_declarations.rb +18 -10
- data/lib/rubocop/cop/style/alias.rb +9 -1
- data/lib/rubocop/cop/style/array_intersect.rb +111 -0
- data/lib/rubocop/cop/style/block_comments.rb +1 -1
- data/lib/rubocop/cop/style/block_delimiters.rb +8 -2
- data/lib/rubocop/cop/style/class_and_module_children.rb +2 -9
- data/lib/rubocop/cop/style/comparable_clamp.rb +125 -0
- data/lib/rubocop/cop/style/concat_array_literals.rb +86 -0
- data/lib/rubocop/cop/style/conditional_assignment.rb +0 -6
- data/lib/rubocop/cop/style/documentation.rb +11 -5
- data/lib/rubocop/cop/style/guard_clause.rb +44 -9
- data/lib/rubocop/cop/style/hash_each_methods.rb +13 -1
- data/lib/rubocop/cop/style/hash_syntax.rb +11 -7
- data/lib/rubocop/cop/style/identical_conditional_branches.rb +15 -0
- data/lib/rubocop/cop/style/if_with_semicolon.rb +4 -4
- data/lib/rubocop/cop/style/infinite_loop.rb +2 -5
- data/lib/rubocop/cop/style/inverse_methods.rb +2 -0
- data/lib/rubocop/cop/style/invertible_unless_condition.rb +114 -0
- data/lib/rubocop/cop/style/line_end_concatenation.rb +4 -1
- data/lib/rubocop/cop/style/map_to_set.rb +61 -0
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +23 -14
- data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +2 -0
- data/lib/rubocop/cop/style/method_def_parentheses.rb +11 -4
- data/lib/rubocop/cop/style/min_max_comparison.rb +83 -0
- data/lib/rubocop/cop/style/missing_else.rb +13 -1
- data/lib/rubocop/cop/style/multiline_if_modifier.rb +0 -4
- data/lib/rubocop/cop/style/multiline_memoization.rb +2 -2
- data/lib/rubocop/cop/style/negated_if_else_condition.rb +1 -5
- data/lib/rubocop/cop/style/nil_lambda.rb +1 -1
- data/lib/rubocop/cop/style/one_line_conditional.rb +3 -6
- data/lib/rubocop/cop/style/operator_method_call.rb +15 -1
- data/lib/rubocop/cop/style/parallel_assignment.rb +3 -1
- data/lib/rubocop/cop/style/redundant_argument.rb +3 -0
- data/lib/rubocop/cop/style/redundant_conditional.rb +0 -4
- data/lib/rubocop/cop/style/redundant_constant_base.rb +85 -0
- data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +45 -0
- data/lib/rubocop/cop/style/redundant_regexp_escape.rb +2 -1
- data/lib/rubocop/cop/style/redundant_return.rb +7 -0
- data/lib/rubocop/cop/style/redundant_sort.rb +1 -1
- data/lib/rubocop/cop/style/redundant_string_escape.rb +6 -3
- data/lib/rubocop/cop/style/require_order.rb +135 -0
- data/lib/rubocop/cop/style/safe_navigation.rb +35 -6
- data/lib/rubocop/cop/style/select_by_regexp.rb +13 -5
- data/lib/rubocop/cop/style/self_assignment.rb +2 -2
- data/lib/rubocop/cop/style/semicolon.rb +26 -3
- data/lib/rubocop/cop/style/signal_exception.rb +8 -6
- data/lib/rubocop/cop/style/string_hash_keys.rb +4 -1
- data/lib/rubocop/cop/style/string_literals.rb +1 -5
- data/lib/rubocop/cop/style/symbol_proc.rb +2 -4
- data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +4 -4
- data/lib/rubocop/cop/style/word_array.rb +41 -0
- data/lib/rubocop/cop/style/yoda_expression.rb +81 -0
- data/lib/rubocop/cop/style/zero_length_predicate.rb +31 -14
- data/lib/rubocop/cop/team.rb +30 -30
- data/lib/rubocop/cop/util.rb +32 -5
- data/lib/rubocop/cop/variable_force/assignment.rb +1 -1
- data/lib/rubocop/cop/variable_force/variable_table.rb +3 -1
- data/lib/rubocop/cop/variable_force.rb +18 -30
- data/lib/rubocop/cops_documentation_generator.rb +33 -11
- data/lib/rubocop/directive_comment.rb +1 -1
- data/lib/rubocop/file_patterns.rb +43 -0
- data/lib/rubocop/formatter/disabled_config_formatter.rb +17 -6
- data/lib/rubocop/formatter/html_formatter.rb +1 -1
- data/lib/rubocop/formatter.rb +4 -1
- data/lib/rubocop/options.rb +8 -0
- data/lib/rubocop/path_util.rb +50 -22
- data/lib/rubocop/result_cache.rb +2 -2
- data/lib/rubocop/rspec/cop_helper.rb +4 -1
- data/lib/rubocop/rspec/expect_offense.rb +6 -4
- data/lib/rubocop/rspec/support.rb +2 -2
- data/lib/rubocop/runner.rb +10 -3
- data/lib/rubocop/server/cache.rb +3 -1
- data/lib/rubocop/server/core.rb +1 -1
- data/lib/rubocop/target_finder.rb +1 -1
- data/lib/rubocop/target_ruby.rb +1 -2
- data/lib/rubocop/version.rb +1 -1
- data/lib/rubocop.rb +23 -6
- metadata +23 -9
data/lib/rubocop/cop/util.rb
CHANGED
@@ -52,6 +52,21 @@ module RuboCop
|
|
52
52
|
end
|
53
53
|
# rubocop:enable Metrics/AbcSize, Metrics/MethodLength
|
54
54
|
|
55
|
+
def any_descendant?(node, *types)
|
56
|
+
if block_given?
|
57
|
+
node.each_descendant(*types) do |descendant|
|
58
|
+
return true if yield(descendant)
|
59
|
+
end
|
60
|
+
else
|
61
|
+
# Use a block version to avoid allocating enumerators.
|
62
|
+
node.each_descendant do # rubocop:disable Lint/UnreachableLoop
|
63
|
+
return true
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
false
|
68
|
+
end
|
69
|
+
|
55
70
|
def args_begin(node)
|
56
71
|
loc = node.loc
|
57
72
|
selector = if node.super_type? || node.yield_type?
|
@@ -71,14 +86,19 @@ module RuboCop
|
|
71
86
|
def on_node(syms, sexp, excludes = [], &block)
|
72
87
|
return to_enum(:on_node, syms, sexp, excludes) unless block
|
73
88
|
|
74
|
-
yield sexp if
|
75
|
-
return if
|
89
|
+
yield sexp if include_or_equal?(syms, sexp.type)
|
90
|
+
return if include_or_equal?(excludes, sexp.type)
|
76
91
|
|
77
92
|
sexp.each_child_node { |elem| on_node(syms, elem, excludes, &block) }
|
78
93
|
end
|
79
94
|
|
95
|
+
LINE_BEGINS_REGEX_CACHE = Hash.new do |hash, index|
|
96
|
+
hash[index] = /^\s{#{index}}\S/
|
97
|
+
end
|
98
|
+
private_constant :LINE_BEGINS_REGEX_CACHE
|
99
|
+
|
80
100
|
def begins_its_line?(range)
|
81
|
-
range.source_line.
|
101
|
+
range.source_line.match?(LINE_BEGINS_REGEX_CACHE[range.column])
|
82
102
|
end
|
83
103
|
|
84
104
|
# Returns, for example, a bare `if` node if the given node is an `if`
|
@@ -152,16 +172,23 @@ module RuboCop
|
|
152
172
|
' ' * (node.loc.column + offset)
|
153
173
|
end
|
154
174
|
|
175
|
+
@to_supported_styles_cache = {}
|
176
|
+
|
155
177
|
def to_supported_styles(enforced_style)
|
156
|
-
enforced_style
|
178
|
+
@to_supported_styles_cache[enforced_style] ||=
|
179
|
+
enforced_style.sub(/^Enforced/, 'Supported').sub('Style', 'Styles')
|
157
180
|
end
|
158
181
|
|
159
182
|
private
|
160
183
|
|
161
184
|
def compatible_external_encoding_for?(src)
|
162
|
-
src = src.dup if
|
185
|
+
src = src.dup if RUBY_ENGINE == 'jruby'
|
163
186
|
src.force_encoding(Encoding.default_external).valid_encoding?
|
164
187
|
end
|
188
|
+
|
189
|
+
def include_or_equal?(source, target)
|
190
|
+
source == target || (source.is_a?(Array) && source.include?(target))
|
191
|
+
end
|
165
192
|
end
|
166
193
|
end
|
167
194
|
end
|
@@ -83,7 +83,7 @@ module RuboCop
|
|
83
83
|
end
|
84
84
|
|
85
85
|
def multiple_assignment_node
|
86
|
-
grandparent_node = node.parent
|
86
|
+
grandparent_node = node.parent&.parent
|
87
87
|
return nil unless grandparent_node
|
88
88
|
return nil unless grandparent_node.type == MULTIPLE_ASSIGNMENT_TYPE
|
89
89
|
return nil unless node.parent.type == MULTIPLE_LEFT_HAND_SIDE_TYPE
|
@@ -97,8 +97,10 @@ module RuboCop
|
|
97
97
|
scope_stack.reverse_each do |scope|
|
98
98
|
variable = scope.variables[name]
|
99
99
|
return variable if variable
|
100
|
+
|
100
101
|
# Only block scope allows referencing outer scope variables.
|
101
|
-
|
102
|
+
node = scope.node
|
103
|
+
return nil unless node.block_type? || node.numblock_type?
|
102
104
|
end
|
103
105
|
|
104
106
|
nil
|
@@ -50,7 +50,7 @@ module RuboCop
|
|
50
50
|
|
51
51
|
ZERO_ARITY_SUPER_TYPE = :zsuper
|
52
52
|
|
53
|
-
TWISTED_SCOPE_TYPES = %i[block class sclass defs module].freeze
|
53
|
+
TWISTED_SCOPE_TYPES = %i[block numblock class sclass defs module].freeze
|
54
54
|
SCOPE_TYPES = (TWISTED_SCOPE_TYPES + [:def]).freeze
|
55
55
|
|
56
56
|
SEND_TYPE = :send
|
@@ -108,34 +108,23 @@ module RuboCop
|
|
108
108
|
:skip_children
|
109
109
|
end
|
110
110
|
|
111
|
-
|
111
|
+
NODE_HANDLER_METHOD_NAMES = [
|
112
|
+
[VARIABLE_ASSIGNMENT_TYPE, :process_variable_assignment],
|
113
|
+
[REGEXP_NAMED_CAPTURE_TYPE, :process_regexp_named_captures],
|
114
|
+
[MULTIPLE_ASSIGNMENT_TYPE, :process_variable_multiple_assignment],
|
115
|
+
[VARIABLE_REFERENCE_TYPE, :process_variable_referencing],
|
116
|
+
[RESCUE_TYPE, :process_rescue],
|
117
|
+
[ZERO_ARITY_SUPER_TYPE, :process_zero_arity_super],
|
118
|
+
[SEND_TYPE, :process_send],
|
119
|
+
*ARGUMENT_DECLARATION_TYPES.product([:process_variable_declaration]),
|
120
|
+
*OPERATOR_ASSIGNMENT_TYPES.product([:process_variable_operator_assignment]),
|
121
|
+
*LOOP_TYPES.product([:process_loop]),
|
122
|
+
*SCOPE_TYPES.product([:process_scope])
|
123
|
+
].to_h.freeze
|
124
|
+
private_constant :NODE_HANDLER_METHOD_NAMES
|
112
125
|
def node_handler_method_name(node)
|
113
|
-
|
114
|
-
when VARIABLE_ASSIGNMENT_TYPE
|
115
|
-
:process_variable_assignment
|
116
|
-
when REGEXP_NAMED_CAPTURE_TYPE
|
117
|
-
:process_regexp_named_captures
|
118
|
-
when MULTIPLE_ASSIGNMENT_TYPE
|
119
|
-
:process_variable_multiple_assignment
|
120
|
-
when VARIABLE_REFERENCE_TYPE
|
121
|
-
:process_variable_referencing
|
122
|
-
when RESCUE_TYPE
|
123
|
-
:process_rescue
|
124
|
-
when ZERO_ARITY_SUPER_TYPE
|
125
|
-
:process_zero_arity_super
|
126
|
-
when SEND_TYPE
|
127
|
-
:process_send
|
128
|
-
when *ARGUMENT_DECLARATION_TYPES
|
129
|
-
:process_variable_declaration
|
130
|
-
when *OPERATOR_ASSIGNMENT_TYPES
|
131
|
-
:process_variable_operator_assignment
|
132
|
-
when *LOOP_TYPES
|
133
|
-
:process_loop
|
134
|
-
when *SCOPE_TYPES
|
135
|
-
:process_scope
|
136
|
-
end
|
126
|
+
NODE_HANDLER_METHOD_NAMES[node.type]
|
137
127
|
end
|
138
|
-
# rubocop:enable Metrics/MethodLength, Metrics/CyclomaticComplexity
|
139
128
|
|
140
129
|
def process_variable_declaration(node)
|
141
130
|
variable_name = node.children.first
|
@@ -358,13 +347,12 @@ module RuboCop
|
|
358
347
|
end
|
359
348
|
end
|
360
349
|
|
361
|
-
# Use Node#equal? for accurate check.
|
362
350
|
def scanned_node?(node)
|
363
|
-
scanned_nodes.
|
351
|
+
scanned_nodes.include?(node)
|
364
352
|
end
|
365
353
|
|
366
354
|
def scanned_nodes
|
367
|
-
@scanned_nodes ||=
|
355
|
+
@scanned_nodes ||= Set.new.compare_by_identity
|
368
356
|
end
|
369
357
|
|
370
358
|
# Hooks invoked by VariableTable.
|
@@ -33,7 +33,7 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
|
|
33
33
|
cops.with_department(department).sort!
|
34
34
|
end
|
35
35
|
|
36
|
-
def cops_body(cop, description, examples_objects, safety_objects, pars) # rubocop:disable Metrics/AbcSize
|
36
|
+
def cops_body(cop, description, examples_objects, safety_objects, see_objects, pars) # rubocop:disable Metrics/AbcSize, Metrics/ParameterLists
|
37
37
|
check_examples_to_have_the_default_enforced_style!(examples_objects, cop)
|
38
38
|
|
39
39
|
content = h2(cop.cop_name)
|
@@ -42,8 +42,8 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
|
|
42
42
|
content << "#{description}\n"
|
43
43
|
content << safety_object(safety_objects) if safety_objects.any? { |s| !s.text.blank? }
|
44
44
|
content << examples(examples_objects) if examples_objects.any?
|
45
|
-
content << configurations(pars)
|
46
|
-
content << references(cop)
|
45
|
+
content << configurations(cop.department, pars)
|
46
|
+
content << references(cop, see_objects)
|
47
47
|
content
|
48
48
|
end
|
49
49
|
|
@@ -136,7 +136,7 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
|
|
136
136
|
content
|
137
137
|
end
|
138
138
|
|
139
|
-
def configurations(pars)
|
139
|
+
def configurations(department, pars)
|
140
140
|
return '' if pars.empty?
|
141
141
|
|
142
142
|
header = ['Name', 'Default value', 'Configurable values']
|
@@ -147,12 +147,20 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
|
|
147
147
|
content = configs.map do |name|
|
148
148
|
configurable = configurable_values(pars, name)
|
149
149
|
default = format_table_value(pars[name])
|
150
|
-
|
150
|
+
|
151
|
+
[configuration_name(department, name), default, configurable]
|
151
152
|
end
|
152
153
|
|
153
154
|
h3('Configurable attributes') + to_table(header, content)
|
154
155
|
end
|
155
156
|
|
157
|
+
def configuration_name(department, name)
|
158
|
+
return name unless name == 'AllowMultilineFinalElement'
|
159
|
+
|
160
|
+
filename = "#{department_to_basename(department)}.adoc"
|
161
|
+
"xref:#{filename}#allowmultilinefinalelement[AllowMultilineFinalElement]"
|
162
|
+
end
|
163
|
+
|
156
164
|
# rubocop:disable Metrics/CyclomaticComplexity,Metrics/MethodLength
|
157
165
|
def configurable_values(pars, name)
|
158
166
|
case name
|
@@ -216,21 +224,34 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
|
|
216
224
|
end
|
217
225
|
end
|
218
226
|
|
219
|
-
def references(cop)
|
227
|
+
def references(cop, see_objects) # rubocop:disable Metrics/AbcSize
|
220
228
|
cop_config = config.for_cop(cop)
|
221
229
|
urls = RuboCop::Cop::MessageAnnotator.new(config, cop.name, cop_config, {}).urls
|
222
|
-
return '' if urls.empty?
|
230
|
+
return '' if urls.empty? && see_objects.empty?
|
223
231
|
|
224
232
|
content = h3('References')
|
225
233
|
content << urls.map { |url| "* #{url}" }.join("\n")
|
226
|
-
content << "\n"
|
234
|
+
content << "\n" unless urls.empty?
|
235
|
+
content << see_objects.map { |see| "* #{see.name}" }.join("\n")
|
236
|
+
content << "\n" unless see_objects.empty?
|
227
237
|
content
|
228
238
|
end
|
229
239
|
|
240
|
+
def footer_for_department(department)
|
241
|
+
return '' unless department == :Layout
|
242
|
+
|
243
|
+
filename = "#{department_to_basename(department)}_footer.adoc"
|
244
|
+
file = "#{Dir.pwd}/docs/modules/ROOT/partials/#{filename}"
|
245
|
+
return '' unless File.exist?(file)
|
246
|
+
|
247
|
+
"\ninclude::../partials/#{filename}[]\n"
|
248
|
+
end
|
249
|
+
|
230
250
|
def print_cops_of_department(department)
|
231
251
|
selected_cops = cops_of_department(department)
|
232
252
|
content = +"= #{department}\n"
|
233
253
|
selected_cops.each { |cop| content << print_cop_with_doc(cop) }
|
254
|
+
content << footer_for_department(department)
|
234
255
|
file_name = "#{Dir.pwd}/docs/modules/ROOT/pages/#{department_to_basename(department)}.adoc"
|
235
256
|
File.open(file_name, 'w') do |file|
|
236
257
|
puts "* generated #{file_name}"
|
@@ -238,7 +259,7 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
|
|
238
259
|
end
|
239
260
|
end
|
240
261
|
|
241
|
-
def print_cop_with_doc(cop)
|
262
|
+
def print_cop_with_doc(cop) # rubocop:todo Metrics/AbcSize, Metrics/MethodLength
|
242
263
|
cop_config = config.for_cop(cop)
|
243
264
|
non_display_keys = %w[
|
244
265
|
Description Enabled StyleGuide Reference Safe SafeAutoCorrect VersionAdded
|
@@ -246,13 +267,14 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
|
|
246
267
|
]
|
247
268
|
pars = cop_config.reject { |k| non_display_keys.include? k }
|
248
269
|
description = 'No documentation'
|
249
|
-
examples_object = safety_object = []
|
270
|
+
examples_object = safety_object = see_object = []
|
250
271
|
cop_code(cop) do |code_object|
|
251
272
|
description = code_object.docstring unless code_object.docstring.blank?
|
252
273
|
examples_object = code_object.tags('example')
|
253
274
|
safety_object = code_object.tags('safety')
|
275
|
+
see_object = code_object.tags('see')
|
254
276
|
end
|
255
|
-
cops_body(cop, description, examples_object, safety_object, pars)
|
277
|
+
cops_body(cop, description, examples_object, safety_object, see_object, pars)
|
256
278
|
end
|
257
279
|
|
258
280
|
def cop_code(cop)
|
@@ -35,7 +35,7 @@ module RuboCop
|
|
35
35
|
|
36
36
|
# Checks if this directive relates to single line
|
37
37
|
def single_line?
|
38
|
-
!
|
38
|
+
!comment.text.start_with?(DIRECTIVE_COMMENT_REGEXP)
|
39
39
|
end
|
40
40
|
|
41
41
|
# Checks if this directive contains all the given cop names
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
# A wrapper around patterns array to perform optimized search.
|
5
|
+
#
|
6
|
+
# For projects with a large set of rubocop todo files, most items in `Exclude`/`Include`
|
7
|
+
# are exact file names. It is wasteful to linearly check the list of patterns over and over
|
8
|
+
# to check if the file is relevant to the cop.
|
9
|
+
#
|
10
|
+
# This class partitions an array of patterns into a set of exact match strings and the rest
|
11
|
+
# of the patterns. This way we can firstly do a cheap check in the set and then proceed via
|
12
|
+
# the costly patterns check, if needed.
|
13
|
+
# @api private
|
14
|
+
class FilePatterns
|
15
|
+
@cache = {}.compare_by_identity
|
16
|
+
|
17
|
+
def self.from(patterns)
|
18
|
+
@cache[patterns] ||= new(patterns)
|
19
|
+
end
|
20
|
+
|
21
|
+
def initialize(patterns)
|
22
|
+
@strings = Set.new
|
23
|
+
@patterns = []
|
24
|
+
partition_patterns(patterns)
|
25
|
+
end
|
26
|
+
|
27
|
+
def match?(path)
|
28
|
+
@strings.include?(path) || @patterns.any? { |pattern| PathUtil.match_path?(pattern, path) }
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def partition_patterns(patterns)
|
34
|
+
patterns.each do |pattern|
|
35
|
+
if pattern.is_a?(String) && !pattern.match?(/[*{\[?]/)
|
36
|
+
@strings << pattern
|
37
|
+
else
|
38
|
+
@patterns << pattern
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -65,6 +65,10 @@ module RuboCop
|
|
65
65
|
@options.fetch(:offense_counts, true)
|
66
66
|
end
|
67
67
|
|
68
|
+
def auto_gen_enforced_style?
|
69
|
+
@options.fetch(:auto_gen_enforced_style, true)
|
70
|
+
end
|
71
|
+
|
68
72
|
def command
|
69
73
|
command = 'rubocop --auto-gen-config'
|
70
74
|
|
@@ -79,6 +83,8 @@ module RuboCop
|
|
79
83
|
|
80
84
|
command += ' --no-auto-gen-timestamp' unless show_timestamp?
|
81
85
|
|
86
|
+
command += ' --no-auto-gen-enforced-style' unless auto_gen_enforced_style?
|
87
|
+
|
82
88
|
command
|
83
89
|
end
|
84
90
|
|
@@ -172,17 +178,22 @@ module RuboCop
|
|
172
178
|
end
|
173
179
|
|
174
180
|
def output_cop_config(output_buffer, cfg, cop_name)
|
175
|
-
|
176
|
-
# limit is exceeded.
|
177
|
-
cfg_without_enabled = cfg.reject { |key| key == 'Enabled' }
|
178
|
-
|
181
|
+
filtered_cfg = filtered_config(cfg)
|
179
182
|
output_buffer.puts "#{cop_name}:"
|
180
|
-
|
183
|
+
filtered_cfg.each do |key, value|
|
181
184
|
value = value[0] if value.is_a?(Array)
|
182
185
|
output_buffer.puts " #{key}: #{value}"
|
183
186
|
end
|
184
187
|
|
185
|
-
output_offending_files(output_buffer,
|
188
|
+
output_offending_files(output_buffer, filtered_cfg, cop_name)
|
189
|
+
end
|
190
|
+
|
191
|
+
def filtered_config(cfg)
|
192
|
+
# 'Enabled' option will be put into file only if exclude
|
193
|
+
# limit is exceeded.
|
194
|
+
rejected_keys = ['Enabled']
|
195
|
+
rejected_keys << 'EnforcedStyle' unless auto_gen_enforced_style?
|
196
|
+
cfg.reject { |key| rejected_keys.include?(key) }
|
186
197
|
end
|
187
198
|
|
188
199
|
def output_offending_files(output_buffer, cfg, cop_name)
|
data/lib/rubocop/formatter.rb
CHANGED
@@ -1,11 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module RuboCop
|
4
|
+
# The bootstrap module for formatter.
|
4
5
|
module Formatter
|
5
6
|
require_relative 'formatter/text_util'
|
6
7
|
|
7
8
|
require_relative 'formatter/base_formatter'
|
8
9
|
require_relative 'formatter/simple_text_formatter'
|
10
|
+
|
9
11
|
# relies on simple text
|
10
12
|
require_relative 'formatter/clang_style_formatter'
|
11
13
|
require_relative 'formatter/disabled_config_formatter'
|
@@ -18,11 +20,12 @@ module RuboCop
|
|
18
20
|
require_relative 'formatter/junit_formatter'
|
19
21
|
require_relative 'formatter/markdown_formatter'
|
20
22
|
require_relative 'formatter/offense_count_formatter'
|
23
|
+
require_relative 'formatter/pacman_formatter'
|
21
24
|
require_relative 'formatter/progress_formatter'
|
22
25
|
require_relative 'formatter/quiet_formatter'
|
23
26
|
require_relative 'formatter/tap_formatter'
|
24
27
|
require_relative 'formatter/worst_offenders_formatter'
|
25
|
-
|
28
|
+
|
26
29
|
# relies on progress formatter
|
27
30
|
require_relative 'formatter/auto_gen_config_formatter'
|
28
31
|
|
data/lib/rubocop/options.rb
CHANGED
@@ -167,6 +167,7 @@ module RuboCop
|
|
167
167
|
option(opts, '--[no-]offense-counts')
|
168
168
|
option(opts, '--[no-]auto-gen-only-exclude')
|
169
169
|
option(opts, '--[no-]auto-gen-timestamp')
|
170
|
+
option(opts, '--[no-]auto-gen-enforced-style')
|
170
171
|
end
|
171
172
|
end
|
172
173
|
|
@@ -486,6 +487,13 @@ module RuboCop
|
|
486
487
|
auto_gen_timestamp:
|
487
488
|
['Include the date and time when the --auto-gen-config',
|
488
489
|
'was run in the file it generates. Default is true.'],
|
490
|
+
auto_gen_enforced_style:
|
491
|
+
['Add a setting to the TODO configuration file to enforce',
|
492
|
+
'the style used, rather than a per-file exclusion',
|
493
|
+
'if one style is used in all files for cop with',
|
494
|
+
'EnforcedStyle as a configurable option',
|
495
|
+
'when the --auto-gen-config was run',
|
496
|
+
'in the file it generates. Default is true.'],
|
489
497
|
auto_gen_only_exclude:
|
490
498
|
['Generate only Exclude parameters and not Max',
|
491
499
|
'when running --auto-gen-config, except if the',
|
data/lib/rubocop/path_util.rb
CHANGED
@@ -3,41 +3,59 @@
|
|
3
3
|
module RuboCop
|
4
4
|
# Common methods and behaviors for dealing with paths.
|
5
5
|
module PathUtil
|
6
|
+
class << self
|
7
|
+
attr_accessor :relative_paths_cache
|
8
|
+
end
|
9
|
+
self.relative_paths_cache = Hash.new { |hash, key| hash[key] = {} }
|
10
|
+
|
6
11
|
module_function
|
7
12
|
|
8
13
|
def relative_path(path, base_dir = Dir.pwd)
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
14
|
+
PathUtil.relative_paths_cache[base_dir][path] ||=
|
15
|
+
# Optimization for the common case where path begins with the base
|
16
|
+
# dir. Just cut off the first part.
|
17
|
+
if path.start_with?(base_dir)
|
18
|
+
base_dir_length = base_dir.length
|
19
|
+
result_length = path.length - base_dir_length - 1
|
20
|
+
path[base_dir_length + 1, result_length]
|
21
|
+
else
|
22
|
+
path_name = Pathname.new(File.expand_path(path))
|
23
|
+
begin
|
24
|
+
path_name.relative_path_from(Pathname.new(base_dir)).to_s
|
25
|
+
rescue ArgumentError
|
26
|
+
path
|
27
|
+
end
|
28
|
+
end
|
23
29
|
end
|
24
30
|
|
31
|
+
SMART_PATH_CACHE = {} # rubocop:disable Style/MutableConstant
|
32
|
+
private_constant :SMART_PATH_CACHE
|
33
|
+
|
25
34
|
def smart_path(path)
|
26
|
-
|
27
|
-
|
35
|
+
SMART_PATH_CACHE[path] ||= begin
|
36
|
+
# Ideally, we calculate this relative to the project root.
|
37
|
+
base_dir = Dir.pwd
|
28
38
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
39
|
+
if path.start_with? base_dir
|
40
|
+
relative_path(path, base_dir)
|
41
|
+
else
|
42
|
+
path
|
43
|
+
end
|
33
44
|
end
|
34
45
|
end
|
35
46
|
|
47
|
+
# rubocop:disable Metrics/MethodLength, Metrics/CyclomaticComplexity
|
36
48
|
def match_path?(pattern, path)
|
37
49
|
case pattern
|
38
50
|
when String
|
39
|
-
|
40
|
-
|
51
|
+
matches =
|
52
|
+
if pattern == path
|
53
|
+
true
|
54
|
+
elsif glob?(pattern)
|
55
|
+
File.fnmatch?(pattern, path, File::FNM_PATHNAME | File::FNM_EXTGLOB)
|
56
|
+
end
|
57
|
+
|
58
|
+
matches || hidden_file_in_not_hidden_dir?(pattern, path)
|
41
59
|
when Regexp
|
42
60
|
begin
|
43
61
|
pattern.match?(path)
|
@@ -48,12 +66,18 @@ module RuboCop
|
|
48
66
|
end
|
49
67
|
end
|
50
68
|
end
|
69
|
+
# rubocop:enable Metrics/MethodLength, Metrics/CyclomaticComplexity
|
51
70
|
|
52
71
|
# Returns true for an absolute Unix or Windows path.
|
53
72
|
def absolute?(path)
|
54
73
|
%r{\A([A-Z]:)?/}i.match?(path)
|
55
74
|
end
|
56
75
|
|
76
|
+
# Returns true for a glob
|
77
|
+
def glob?(path)
|
78
|
+
path.match?(/[*{\[?]/)
|
79
|
+
end
|
80
|
+
|
57
81
|
def hidden_file_in_not_hidden_dir?(pattern, path)
|
58
82
|
hidden_file?(path) &&
|
59
83
|
File.fnmatch?(
|
@@ -67,8 +91,12 @@ module RuboCop
|
|
67
91
|
maybe_hidden_file?(path) && File.basename(path).start_with?('.')
|
68
92
|
end
|
69
93
|
|
94
|
+
HIDDEN_FILE_PATTERN = "#{File::SEPARATOR}."
|
95
|
+
|
70
96
|
# Loose check to reduce memory allocations
|
71
97
|
def maybe_hidden_file?(path)
|
98
|
+
return false unless path.include?(HIDDEN_FILE_PATTERN)
|
99
|
+
|
72
100
|
separator_index = path.rindex(File::SEPARATOR)
|
73
101
|
return false unless separator_index
|
74
102
|
|
data/lib/rubocop/result_cache.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'digest/sha1'
|
4
|
-
require 'find'
|
5
4
|
require 'etc'
|
5
|
+
require 'find'
|
6
6
|
require 'zlib'
|
7
7
|
require_relative 'cache_config'
|
8
8
|
|
@@ -53,7 +53,7 @@ module RuboCop
|
|
53
53
|
def remove_oldest_files(files, dirs, cache_root, verbose)
|
54
54
|
# Add 1 to half the number of files, so that we remove the file if
|
55
55
|
# there's only 1 left.
|
56
|
-
remove_count =
|
56
|
+
remove_count = (files.length / 2) + 1
|
57
57
|
puts "Removing the #{remove_count} oldest files from #{cache_root}" if verbose
|
58
58
|
sorted = files.sort_by { |path| File.mtime(path) }
|
59
59
|
remove_files(sorted, dirs, remove_count)
|
@@ -44,7 +44,10 @@ module CopHelper
|
|
44
44
|
|
45
45
|
def registry
|
46
46
|
@registry ||= begin
|
47
|
-
|
47
|
+
keys = configuration.keys
|
48
|
+
cops =
|
49
|
+
keys.map { |directive| RuboCop::Cop::Registry.global.find_cops_by_directive(directive) }
|
50
|
+
.flatten
|
48
51
|
cops << cop_class if defined?(cop_class) && !cops.include?(cop_class)
|
49
52
|
cops.compact!
|
50
53
|
RuboCop::Cop::Registry.new(cops)
|
@@ -6,7 +6,7 @@ module RuboCop
|
|
6
6
|
#
|
7
7
|
# This mixin makes it easier to specify strict offense expectations
|
8
8
|
# in a declarative and visual fashion. Just type out the code that
|
9
|
-
# should generate
|
9
|
+
# should generate an offense, annotate code by writing '^'s
|
10
10
|
# underneath each character that should be highlighted, and follow
|
11
11
|
# the carets with a string (separated by a space) that is the
|
12
12
|
# message of the offense. You can include multiple offenses in
|
@@ -126,7 +126,7 @@ module RuboCop
|
|
126
126
|
@offenses
|
127
127
|
end
|
128
128
|
|
129
|
-
# rubocop:disable Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity
|
129
|
+
# rubocop:disable Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
130
130
|
def expect_correction(correction, loop: true, source: nil)
|
131
131
|
if source
|
132
132
|
expected_annotations = parse_annotations(source, raise_error: false)
|
@@ -138,6 +138,8 @@ module RuboCop
|
|
138
138
|
|
139
139
|
source = @processed_source.raw_source
|
140
140
|
|
141
|
+
raise 'Use `expect_no_corrections` if the code will not change' if correction == source
|
142
|
+
|
141
143
|
iteration = 0
|
142
144
|
new_source = loop do
|
143
145
|
iteration += 1
|
@@ -157,11 +159,11 @@ module RuboCop
|
|
157
159
|
_investigate(cop, @processed_source)
|
158
160
|
end
|
159
161
|
|
160
|
-
raise '
|
162
|
+
raise 'Expected correction but no corrections were made' if new_source == source
|
161
163
|
|
162
164
|
expect(new_source).to eq(correction)
|
163
165
|
end
|
164
|
-
# rubocop:enable Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity
|
166
|
+
# rubocop:enable Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
165
167
|
|
166
168
|
def expect_no_corrections
|
167
169
|
raise '`expect_no_corrections` must follow `expect_offense`' unless @processed_source
|
@@ -3,10 +3,10 @@
|
|
3
3
|
# Require this file to load code that supports testing using RSpec.
|
4
4
|
|
5
5
|
require_relative 'cop_helper'
|
6
|
-
require_relative 'host_environment_simulation_helper'
|
7
|
-
require_relative 'shared_contexts'
|
8
6
|
require_relative 'expect_offense'
|
7
|
+
require_relative 'host_environment_simulation_helper'
|
9
8
|
require_relative 'parallel_formatter'
|
9
|
+
require_relative 'shared_contexts'
|
10
10
|
|
11
11
|
RSpec.configure do |config|
|
12
12
|
config.include CopHelper
|