rubocop 0.75.1 → 0.80.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (199) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +4 -4
  4. data/config/default.yml +374 -335
  5. data/lib/rubocop.rb +53 -32
  6. data/lib/rubocop/ast/builder.rb +43 -41
  7. data/lib/rubocop/ast/node.rb +5 -13
  8. data/lib/rubocop/ast/node/block_node.rb +2 -0
  9. data/lib/rubocop/ast/node/def_node.rb +11 -0
  10. data/lib/rubocop/ast/node/forward_args_node.rb +18 -0
  11. data/lib/rubocop/ast/node/regexp_node.rb +2 -4
  12. data/lib/rubocop/ast/node/return_node.rb +24 -0
  13. data/lib/rubocop/ast/traversal.rb +20 -3
  14. data/lib/rubocop/cli.rb +11 -227
  15. data/lib/rubocop/cli/command.rb +21 -0
  16. data/lib/rubocop/cli/command/auto_genenerate_config.rb +105 -0
  17. data/lib/rubocop/cli/command/base.rb +33 -0
  18. data/lib/rubocop/cli/command/execute_runner.rb +76 -0
  19. data/lib/rubocop/cli/command/init_dotfile.rb +45 -0
  20. data/lib/rubocop/cli/command/show_cops.rb +80 -0
  21. data/lib/rubocop/cli/command/version.rb +17 -0
  22. data/lib/rubocop/cli/environment.rb +21 -0
  23. data/lib/rubocop/comment_config.rb +8 -3
  24. data/lib/rubocop/config.rb +8 -1
  25. data/lib/rubocop/config_loader.rb +20 -20
  26. data/lib/rubocop/config_loader_resolver.rb +2 -1
  27. data/lib/rubocop/config_obsoletion.rb +73 -10
  28. data/lib/rubocop/config_validator.rb +77 -110
  29. data/lib/rubocop/cop/autocorrect_logic.rb +7 -4
  30. data/lib/rubocop/cop/bundler/gem_comment.rb +4 -4
  31. data/lib/rubocop/cop/bundler/insecure_protocol_source.rb +2 -2
  32. data/lib/rubocop/cop/commissioner.rb +15 -7
  33. data/lib/rubocop/cop/cop.rb +31 -6
  34. data/lib/rubocop/cop/corrector.rb +8 -7
  35. data/lib/rubocop/cop/correctors/space_corrector.rb +1 -2
  36. data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +1 -1
  37. data/lib/rubocop/cop/generator.rb +3 -4
  38. data/lib/rubocop/cop/generator/configuration_injector.rb +2 -2
  39. data/lib/rubocop/cop/internal_affairs.rb +1 -0
  40. data/lib/rubocop/cop/internal_affairs/method_name_equal.rb +59 -0
  41. data/lib/rubocop/cop/layout/{align_arguments.rb → argument_alignment.rb} +1 -1
  42. data/lib/rubocop/cop/layout/{align_array.rb → array_alignment.rb} +1 -1
  43. data/lib/rubocop/cop/layout/{indent_assignment.rb → assignment_indentation.rb} +1 -1
  44. data/lib/rubocop/cop/layout/comment_indentation.rb +10 -13
  45. data/lib/rubocop/cop/layout/empty_comment.rb +7 -16
  46. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +2 -1
  47. data/lib/rubocop/cop/layout/end_of_line.rb +8 -3
  48. data/lib/rubocop/cop/layout/extra_spacing.rb +1 -1
  49. data/lib/rubocop/cop/layout/{indent_first_argument.rb → first_argument_indentation.rb} +14 -12
  50. data/lib/rubocop/cop/layout/{indent_first_array_element.rb → first_array_element_indentation.rb} +4 -4
  51. data/lib/rubocop/cop/layout/{indent_first_hash_element.rb → first_hash_element_indentation.rb} +4 -4
  52. data/lib/rubocop/cop/layout/{indent_first_parameter.rb → first_parameter_indentation.rb} +3 -3
  53. data/lib/rubocop/cop/layout/{align_hash.rb → hash_alignment.rb} +16 -8
  54. data/lib/rubocop/cop/layout/{indent_heredoc.rb → heredoc_indentation.rb} +5 -5
  55. data/lib/rubocop/cop/layout/leading_comment_space.rb +33 -2
  56. data/lib/rubocop/cop/layout/{leading_blank_lines.rb → leading_empty_lines.rb} +1 -1
  57. data/lib/rubocop/cop/{metrics → layout}/line_length.rb +68 -112
  58. data/lib/rubocop/cop/layout/multiline_assignment_layout.rb +1 -1
  59. data/lib/rubocop/cop/layout/multiline_block_layout.rb +14 -5
  60. data/lib/rubocop/cop/layout/multiline_hash_brace_layout.rb +0 -4
  61. data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +1 -1
  62. data/lib/rubocop/cop/layout/{align_parameters.rb → parameter_alignment.rb} +1 -1
  63. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +2 -0
  64. data/lib/rubocop/cop/layout/space_around_keyword.rb +12 -0
  65. data/lib/rubocop/cop/layout/space_around_operators.rb +50 -7
  66. data/lib/rubocop/cop/layout/space_before_block_braces.rb +17 -0
  67. data/lib/rubocop/cop/layout/space_before_first_arg.rb +8 -0
  68. data/lib/rubocop/cop/layout/space_in_lambda_literal.rb +9 -7
  69. data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +7 -4
  70. data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +2 -9
  71. data/lib/rubocop/cop/layout/space_inside_parens.rb +6 -6
  72. data/lib/rubocop/cop/layout/{trailing_blank_lines.rb → trailing_empty_lines.rb} +1 -1
  73. data/lib/rubocop/cop/layout/trailing_whitespace.rb +18 -2
  74. data/lib/rubocop/cop/lint/debugger.rb +1 -1
  75. data/lib/rubocop/cop/lint/disjunctive_assignment_in_constructor.rb +1 -1
  76. data/lib/rubocop/cop/lint/{duplicated_key.rb → duplicate_hash_key.rb} +1 -1
  77. data/lib/rubocop/cop/lint/each_with_object_argument.rb +1 -1
  78. data/lib/rubocop/cop/lint/erb_new_arguments.rb +9 -8
  79. data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +1 -1
  80. data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +2 -2
  81. data/lib/rubocop/cop/lint/{multiple_compare.rb → multiple_comparison.rb} +1 -1
  82. data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +89 -0
  83. data/lib/rubocop/cop/lint/{unneeded_cop_disable_directive.rb → redundant_cop_disable_directive.rb} +26 -26
  84. data/lib/rubocop/cop/lint/{unneeded_cop_enable_directive.rb → redundant_cop_enable_directive.rb} +18 -15
  85. data/lib/rubocop/cop/lint/{unneeded_require_statement.rb → redundant_require_statement.rb} +1 -1
  86. data/lib/rubocop/cop/lint/{unneeded_splat_expansion.rb → redundant_splat_expansion.rb} +6 -6
  87. data/lib/rubocop/cop/lint/{string_conversion_in_interpolation.rb → redundant_string_coercion.rb} +1 -1
  88. data/lib/rubocop/cop/lint/redundant_with_index.rb +2 -2
  89. data/lib/rubocop/cop/lint/redundant_with_object.rb +2 -2
  90. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +5 -6
  91. data/lib/rubocop/cop/lint/{handle_exceptions.rb → suppressed_exception.rb} +1 -1
  92. data/lib/rubocop/cop/lint/useless_access_modifier.rb +57 -23
  93. data/lib/rubocop/cop/lint/useless_setter_call.rb +5 -1
  94. data/lib/rubocop/cop/lint/void.rb +4 -4
  95. data/lib/rubocop/cop/metrics/abc_size.rb +1 -1
  96. data/lib/rubocop/cop/metrics/method_length.rb +1 -1
  97. data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +23 -6
  98. data/lib/rubocop/cop/migration/department_name.rb +30 -2
  99. data/lib/rubocop/cop/mixin/alignment.rb +1 -1
  100. data/lib/rubocop/cop/mixin/configurable_enforced_style.rb +4 -0
  101. data/lib/rubocop/cop/mixin/frozen_string_literal.rb +7 -7
  102. data/lib/rubocop/cop/mixin/{hash_alignment.rb → hash_alignment_styles.rb} +1 -1
  103. data/lib/rubocop/cop/mixin/hash_transform_method.rb +172 -0
  104. data/lib/rubocop/cop/mixin/line_length_help.rb +88 -0
  105. data/lib/rubocop/cop/mixin/method_complexity.rb +2 -1
  106. data/lib/rubocop/cop/mixin/nil_methods.rb +4 -4
  107. data/lib/rubocop/cop/mixin/rational_literal.rb +18 -0
  108. data/lib/rubocop/cop/mixin/statement_modifier.rb +7 -4
  109. data/lib/rubocop/cop/mixin/trailing_comma.rb +16 -18
  110. data/lib/rubocop/cop/naming/{uncommunicative_block_param_name.rb → block_parameter_name.rb} +3 -3
  111. data/lib/rubocop/cop/naming/file_name.rb +12 -5
  112. data/lib/rubocop/cop/naming/heredoc_delimiter_naming.rb +5 -5
  113. data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +1 -1
  114. data/lib/rubocop/cop/naming/{uncommunicative_method_param_name.rb → method_parameter_name.rb} +4 -4
  115. data/lib/rubocop/cop/naming/predicate_name.rb +6 -6
  116. data/lib/rubocop/cop/offense.rb +11 -0
  117. data/lib/rubocop/cop/registry.rb +8 -3
  118. data/lib/rubocop/cop/style/alias.rb +1 -1
  119. data/lib/rubocop/cop/style/array_join.rb +1 -1
  120. data/lib/rubocop/cop/style/attr.rb +10 -2
  121. data/lib/rubocop/cop/style/block_delimiters.rb +60 -1
  122. data/lib/rubocop/cop/style/comment_annotation.rb +5 -5
  123. data/lib/rubocop/cop/style/conditional_assignment.rb +2 -2
  124. data/lib/rubocop/cop/style/copyright.rb +11 -7
  125. data/lib/rubocop/cop/style/double_cop_disable_directive.rb +2 -2
  126. data/lib/rubocop/cop/style/empty_case_condition.rb +2 -2
  127. data/lib/rubocop/cop/style/empty_literal.rb +2 -2
  128. data/lib/rubocop/cop/style/empty_method.rb +5 -5
  129. data/lib/rubocop/cop/style/eval_with_location.rb +1 -1
  130. data/lib/rubocop/cop/style/even_odd.rb +1 -1
  131. data/lib/rubocop/cop/style/format_string.rb +10 -7
  132. data/lib/rubocop/cop/style/format_string_token.rb +2 -0
  133. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +99 -11
  134. data/lib/rubocop/cop/style/guard_clause.rb +3 -2
  135. data/lib/rubocop/cop/style/hash_each_methods.rb +87 -0
  136. data/lib/rubocop/cop/style/hash_syntax.rb +2 -2
  137. data/lib/rubocop/cop/style/hash_transform_keys.rb +79 -0
  138. data/lib/rubocop/cop/style/hash_transform_values.rb +79 -0
  139. data/lib/rubocop/cop/style/if_unless_modifier.rb +45 -3
  140. data/lib/rubocop/cop/style/infinite_loop.rb +5 -4
  141. data/lib/rubocop/cop/style/inverse_methods.rb +19 -13
  142. data/lib/rubocop/cop/style/ip_addresses.rb +4 -4
  143. data/lib/rubocop/cop/style/line_end_concatenation.rb +14 -10
  144. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +7 -205
  145. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +169 -0
  146. data/lib/rubocop/cop/style/method_call_with_args_parentheses/require_parentheses.rb +54 -0
  147. data/lib/rubocop/cop/style/method_def_parentheses.rb +17 -9
  148. data/lib/rubocop/cop/style/mixin_grouping.rb +1 -1
  149. data/lib/rubocop/cop/style/multiline_method_signature.rb +1 -1
  150. data/lib/rubocop/cop/style/multiline_when_then.rb +6 -2
  151. data/lib/rubocop/cop/style/nested_modifier.rb +4 -2
  152. data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +5 -5
  153. data/lib/rubocop/cop/style/next.rb +5 -5
  154. data/lib/rubocop/cop/style/non_nil_check.rb +21 -9
  155. data/lib/rubocop/cop/style/numeric_literals.rb +7 -3
  156. data/lib/rubocop/cop/style/numeric_predicate.rb +4 -3
  157. data/lib/rubocop/cop/style/option_hash.rb +3 -3
  158. data/lib/rubocop/cop/style/or_assignment.rb +3 -2
  159. data/lib/rubocop/cop/style/percent_literal_delimiters.rb +7 -7
  160. data/lib/rubocop/cop/style/{unneeded_capital_w.rb → redundant_capital_w.rb} +1 -1
  161. data/lib/rubocop/cop/style/{unneeded_condition.rb → redundant_condition.rb} +3 -3
  162. data/lib/rubocop/cop/style/{unneeded_interpolation.rb → redundant_interpolation.rb} +1 -1
  163. data/lib/rubocop/cop/style/redundant_parentheses.rb +3 -3
  164. data/lib/rubocop/cop/style/{unneeded_percent_q.rb → redundant_percent_q.rb} +1 -1
  165. data/lib/rubocop/cop/style/redundant_return.rb +27 -29
  166. data/lib/rubocop/cop/style/{unneeded_sort.rb → redundant_sort.rb} +5 -5
  167. data/lib/rubocop/cop/style/safe_navigation.rb +13 -10
  168. data/lib/rubocop/cop/style/semicolon.rb +2 -2
  169. data/lib/rubocop/cop/style/special_global_vars.rb +5 -7
  170. data/lib/rubocop/cop/style/symbol_array.rb +2 -2
  171. data/lib/rubocop/cop/style/ternary_parentheses.rb +1 -1
  172. data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +0 -22
  173. data/lib/rubocop/cop/style/trailing_underscore_variable.rb +7 -1
  174. data/lib/rubocop/cop/style/trivial_accessors.rb +5 -5
  175. data/lib/rubocop/cop/style/while_until_modifier.rb +1 -1
  176. data/lib/rubocop/cop/style/yoda_condition.rb +16 -1
  177. data/lib/rubocop/cop/team.rb +5 -0
  178. data/lib/rubocop/cop/util.rb +1 -1
  179. data/lib/rubocop/cop/utils/format_string.rb +10 -18
  180. data/lib/rubocop/cop/variable_force.rb +11 -6
  181. data/lib/rubocop/formatter/base_formatter.rb +2 -2
  182. data/lib/rubocop/formatter/clang_style_formatter.rb +1 -3
  183. data/lib/rubocop/formatter/formatter_set.rb +1 -0
  184. data/lib/rubocop/formatter/json_formatter.rb +6 -5
  185. data/lib/rubocop/formatter/junit_formatter.rb +63 -0
  186. data/lib/rubocop/formatter/tap_formatter.rb +1 -3
  187. data/lib/rubocop/node_pattern.rb +100 -12
  188. data/lib/rubocop/options.rb +17 -11
  189. data/lib/rubocop/processed_source.rb +1 -1
  190. data/lib/rubocop/rake_task.rb +1 -0
  191. data/lib/rubocop/result_cache.rb +24 -8
  192. data/lib/rubocop/rspec/shared_contexts.rb +5 -0
  193. data/lib/rubocop/runner.rb +50 -29
  194. data/lib/rubocop/target_finder.rb +12 -6
  195. data/lib/rubocop/target_ruby.rb +151 -0
  196. data/lib/rubocop/version.rb +1 -1
  197. metadata +69 -35
  198. data/lib/rubocop/cop/mixin/safe_mode.rb +0 -24
  199. data/lib/rubocop/cop/style/braces_around_hash_parameters.rb +0 -209
@@ -10,32 +10,24 @@ module RuboCop
10
10
 
11
11
  COMMON_PARAMS = %w[Exclude Include Severity inherit_mode
12
12
  AutoCorrect StyleGuide Details].freeze
13
- INTERNAL_PARAMS = %w[Description StyleGuide VersionAdded
14
- VersionChanged Reference Safe SafeAutoCorrect].freeze
13
+ INTERNAL_PARAMS = %w[Description StyleGuide
14
+ VersionAdded VersionChanged VersionRemoved
15
+ Reference Safe SafeAutoCorrect].freeze
15
16
 
16
- # 2.3 is the oldest officially supported Ruby version.
17
- DEFAULT_RUBY_VERSION = 2.3
18
- KNOWN_RUBIES = [2.3, 2.4, 2.5, 2.6, 2.7].freeze
19
- OBSOLETE_RUBIES = {
20
- 1.9 => '0.50', 2.0 => '0.50', 2.1 => '0.58', 2.2 => '0.69'
21
- }.freeze
22
- RUBY_VERSION_FILENAME = '.ruby-version'
23
-
24
- def_delegators :@config,
25
- :smart_loaded_path, :for_all_cops, :find_file_upwards,
26
- :base_dir_for_path_parameters, :bundler_lock_file_path
17
+ def_delegators :@config, :smart_loaded_path, :for_all_cops
27
18
 
28
19
  def initialize(config)
29
20
  @config = config
30
21
  @config_obsoletion = ConfigObsoletion.new(config)
22
+ @target_ruby = TargetRuby.new(config)
31
23
  end
32
24
 
33
25
  def validate
34
- # Don't validate RuboCop's own files. Avoids infinite recursion.
35
- base_config_path = File.expand_path(File.join(ConfigLoader::RUBOCOP_HOME,
36
- 'config'))
37
- return if File.expand_path(@config.loaded_path)
38
- .start_with?(base_config_path)
26
+ check_cop_config_value(@config)
27
+ reject_conflicting_safe_settings
28
+
29
+ # Don't validate RuboCop's own files further. Avoids infinite recursion.
30
+ return if @config.internal?
39
31
 
40
32
  valid_cop_names, invalid_cop_names = @config.keys.partition do |key|
41
33
  ConfigLoader.default_configuration.key?(key)
@@ -43,7 +35,7 @@ module RuboCop
43
35
 
44
36
  @config_obsoletion.reject_obsolete_cops_and_parameters
45
37
 
46
- warn_about_unrecognized_cops(invalid_cop_names)
38
+ alert_about_unrecognized_cops(invalid_cop_names)
47
39
  check_target_ruby
48
40
  validate_parameter_names(valid_cop_names)
49
41
  validate_enforced_styles(valid_cop_names)
@@ -52,23 +44,7 @@ module RuboCop
52
44
  end
53
45
 
54
46
  def target_ruby_version
55
- @target_ruby_version ||= begin
56
- if for_all_cops['TargetRubyVersion']
57
- @target_ruby_version_source = :rubocop_yml
58
-
59
- for_all_cops['TargetRubyVersion'].to_f
60
- elsif target_ruby_version_from_version_file
61
- @target_ruby_version_source = :ruby_version_file
62
-
63
- target_ruby_version_from_version_file
64
- elsif target_ruby_version_from_bundler_lock_file
65
- @target_ruby_version_source = :bundler_lock_file
66
-
67
- target_ruby_version_from_bundler_lock_file
68
- else
69
- DEFAULT_RUBY_VERSION
70
- end
71
- end
47
+ target_ruby.version
72
48
  end
73
49
 
74
50
  def validate_section_presence(name)
@@ -80,25 +56,30 @@ module RuboCop
80
56
 
81
57
  private
82
58
 
59
+ attr_reader :target_ruby
60
+
83
61
  def check_target_ruby
84
- return if KNOWN_RUBIES.include?(target_ruby_version)
62
+ return if target_ruby.supported?
63
+
64
+ source = target_ruby.source
65
+ last_version = target_ruby.rubocop_version_with_support
85
66
 
86
- msg = if OBSOLETE_RUBIES.include?(target_ruby_version)
67
+ msg = if last_version
87
68
  "RuboCop found unsupported Ruby version #{target_ruby_version} " \
88
- "in #{target_ruby_source}. #{target_ruby_version}-compatible " \
89
- 'analysis was dropped after version ' \
90
- "#{OBSOLETE_RUBIES[target_ruby_version]}."
69
+ "in #{source}. #{target_ruby_version}-compatible " \
70
+ "analysis was dropped after version #{last_version}."
91
71
  else
92
72
  'RuboCop found unknown Ruby version ' \
93
- "#{target_ruby_version.inspect} in #{target_ruby_source}."
73
+ "#{target_ruby_version.inspect} in #{source}."
94
74
  end
95
75
 
96
- msg += "\nSupported versions: #{KNOWN_RUBIES.join(', ')}"
76
+ msg += "\nSupported versions: #{TargetRuby.supported_versions.join(', ')}"
97
77
 
98
78
  raise ValidationError, msg
99
79
  end
100
80
 
101
- def warn_about_unrecognized_cops(invalid_cop_names)
81
+ def alert_about_unrecognized_cops(invalid_cop_names)
82
+ unknown_cops = []
102
83
  invalid_cop_names.each do |name|
103
84
  # There could be a custom cop with this name. If so, don't warn
104
85
  next if Cop::Cop.registry.contains_cop_matching?([name])
@@ -108,9 +89,10 @@ module RuboCop
108
89
  # to do so than to pass the value around to various methods.
109
90
  next if name == 'inherit_mode'
110
91
 
111
- warn Rainbow("Warning: unrecognized cop #{name} found in " \
112
- "#{smart_loaded_path}").yellow
92
+ unknown_cops << "unrecognized cop #{name} found in " \
93
+ "#{smart_loaded_path}"
113
94
  end
95
+ raise ValidationError, unknown_cops.join(', ') if unknown_cops.any?
114
96
  end
115
97
 
116
98
  def validate_syntax_cop
@@ -128,21 +110,30 @@ module RuboCop
128
110
  def validate_parameter_names(valid_cop_names)
129
111
  valid_cop_names.each do |name|
130
112
  validate_section_presence(name)
131
- default_config = ConfigLoader.default_configuration[name]
113
+ each_invalid_parameter(name) do |param, supported_params|
114
+ warn Rainbow(<<~MESSAGE).yellow
115
+ Warning: #{name} does not support #{param} parameter.
132
116
 
133
- @config[name].each_key do |param|
134
- next if COMMON_PARAMS.include?(param) || default_config.key?(param)
117
+ Supported parameters are:
135
118
 
136
- message =
137
- "Warning: #{name} does not support #{param} parameter.\n\n" \
138
- "Supported parameters are:\n\n" \
139
- " - #{(default_config.keys - INTERNAL_PARAMS).join("\n - ")}\n"
140
-
141
- warn Rainbow(message).yellow.to_s
119
+ - #{supported_params.join("\n - ")}
120
+ MESSAGE
142
121
  end
143
122
  end
144
123
  end
145
124
 
125
+ def each_invalid_parameter(cop_name)
126
+ default_config = ConfigLoader.default_configuration[cop_name]
127
+
128
+ @config[cop_name].each_key do |param|
129
+ next if COMMON_PARAMS.include?(param) || default_config.key?(param)
130
+
131
+ supported_params = default_config.keys - INTERNAL_PARAMS
132
+
133
+ yield param, supported_params
134
+ end
135
+ end
136
+
146
137
  def validate_enforced_styles(valid_cop_names)
147
138
  valid_cop_names.each do |name|
148
139
  styles = @config[name].select { |key, _| key.start_with?('Enforced') }
@@ -169,71 +160,47 @@ module RuboCop
169
160
  formats.all? { |format| valid.include?(format) }
170
161
  end
171
162
 
172
- def target_ruby_source
173
- case @target_ruby_version_source
174
- when :ruby_version_file
175
- "`#{RUBY_VERSION_FILENAME}`"
176
- when :bundler_lock_file
177
- "`#{bundler_lock_file_path}`"
178
- when :rubocop_yml
179
- "`TargetRubyVersion` parameter (in #{smart_loaded_path})"
180
- end
181
- 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
182
167
 
183
- def ruby_version_file
184
- @ruby_version_file ||=
185
- 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
186
170
  end
187
171
 
188
- def target_ruby_version_from_version_file
189
- file = ruby_version_file
190
- return unless file && File.file?(file)
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
191
177
 
192
- @target_ruby_version_from_version_file ||=
193
- File.read(file).match(/\A(ruby-)?(?<version>\d+\.\d+)/) do |md|
194
- md[:version].to_f
195
- end
178
+ msg = 'Unsafe cops cannot have a safe auto-correction ' \
179
+ "(section #{name} in #{smart_loaded_path})"
180
+ raise ValidationError, msg
181
+ end
196
182
  end
197
183
 
198
- def target_ruby_version_from_bundler_lock_file
199
- @target_ruby_version_from_bundler_lock_file ||=
200
- read_ruby_version_from_bundler_lock_file
201
- end
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)
202
187
 
203
- def read_ruby_version_from_bundler_lock_file
204
- lock_file_path = bundler_lock_file_path
205
- return nil unless lock_file_path
206
-
207
- in_ruby_section = false
208
- File.foreach(lock_file_path) do |line|
209
- # If ruby is in Gemfile.lock or gems.lock, there should be two lines
210
- # towards the bottom of the file that look like:
211
- # RUBY VERSION
212
- # ruby W.X.YpZ
213
- # We ultimately want to match the "ruby W.X.Y.pZ" line, but there's
214
- # extra logic to make sure we only start looking once we've seen the
215
- # "RUBY VERSION" line.
216
- in_ruby_section ||= line.match(/^\s*RUBY\s*VERSION\s*$/)
217
- next unless in_ruby_section
218
-
219
- # We currently only allow this feature to work with MRI ruby. If jruby
220
- # (or something else) is used by the project, it's lock file will have a
221
- # line that looks like:
222
- # RUBY VERSION
223
- # ruby W.X.YpZ (jruby x.x.x.x)
224
- # The regex won't match in this situation.
225
- result = line.match(/^\s*ruby\s+(\d+\.\d+)[p.\d]*\s*$/)
226
- return result.captures.first.to_f if result
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'
194
+
195
+ raise ValidationError, msg_not_boolean(parent, key, value)
227
196
  end
228
197
  end
229
198
 
230
- def reject_mutually_exclusive_defaults
231
- disabled_by_default = for_all_cops['DisabledByDefault']
232
- enabled_by_default = for_all_cops['EnabledByDefault']
233
- return unless disabled_by_default && enabled_by_default
234
-
235
- msg = 'Cops cannot be both enabled by default and disabled by default'
236
- 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."
237
204
  end
238
205
  end
239
206
  end
@@ -24,15 +24,18 @@ module RuboCop
24
24
  @options[:disable_uncorrectable] == true
25
25
  end
26
26
 
27
+ def safe_autocorrect?
28
+ cop_config.fetch('Safe', true) &&
29
+ cop_config.fetch('SafeAutoCorrect', true)
30
+ end
31
+
27
32
  def autocorrect_enabled?
28
33
  # allow turning off autocorrect on a cop by cop basis
29
34
  return true unless cop_config
30
35
 
31
36
  return false if cop_config['AutoCorrect'] == false
32
37
 
33
- if @options.fetch(:safe_auto_correct, false)
34
- return cop_config.fetch('SafeAutoCorrect', true)
35
- end
38
+ return safe_autocorrect? if @options.fetch(:safe_auto_correct, false)
36
39
 
37
40
  true
38
41
  end
@@ -76,7 +79,7 @@ module RuboCop
76
79
  end
77
80
 
78
81
  def max_line_length
79
- config.for_cop('Metrics/LineLength')['Max'] || 80
82
+ config.for_cop('Layout/LineLength')['Max'] || 80
80
83
  end
81
84
 
82
85
  def disable_offense_at_end_of_line(range, eol_comment)
@@ -24,7 +24,7 @@ module RuboCop
24
24
 
25
25
  def on_send(node)
26
26
  return unless gem_declaration?(node)
27
- return if whitelisted_gem?(node)
27
+ return if ignored_gem?(node)
28
28
  return if commented?(node)
29
29
 
30
30
  add_offense(node)
@@ -54,9 +54,9 @@ module RuboCop
54
54
  comment_line?(node2.loc.expression.source)
55
55
  end
56
56
 
57
- def whitelisted_gem?(node)
58
- whitelist = Array(cop_config['Whitelist'])
59
- whitelist.include?(node.first_argument.value)
57
+ def ignored_gem?(node)
58
+ ignored_gems = Array(cop_config['IgnoredGems'])
59
+ ignored_gems.include?(node.first_argument.value)
60
60
  end
61
61
  end
62
62
  end
@@ -13,8 +13,8 @@ module RuboCop
13
13
  #
14
14
  # However, it don't replace all `sources` of `http://` with `https://`.
15
15
  # For example, when specifying an internal gem server using HTTP on the
16
- # intranet, a use case where HTTPS can not be specified was considered.
17
- # Consider using HTTP only if you can not use HTTPS.
16
+ # intranet, a use case where HTTPS cannot be specified was considered.
17
+ # Consider using HTTP only if you cannot use HTTPS.
18
18
  #
19
19
  # @example
20
20
  # # bad
@@ -64,17 +64,25 @@ module RuboCop
64
64
  end
65
65
 
66
66
  def remove_irrelevant_cops(filename)
67
- @cops.reject! { |cop| cop.excluded_file?(filename) }
68
67
  @cops.reject! do |cop|
69
- cop.class.respond_to?(:support_target_ruby_version?) &&
70
- !cop.class.support_target_ruby_version?(cop.target_ruby_version)
71
- end
72
- @cops.reject! do |cop|
73
- cop.class.respond_to?(:support_target_rails_version?) &&
74
- !cop.class.support_target_rails_version?(cop.target_rails_version)
68
+ cop.excluded_file?(filename) ||
69
+ !support_target_ruby_version?(cop) ||
70
+ !support_target_rails_version?(cop)
75
71
  end
76
72
  end
77
73
 
74
+ def support_target_ruby_version?(cop)
75
+ return true unless cop.class.respond_to?(:support_target_ruby_version?)
76
+
77
+ cop.class.support_target_ruby_version?(cop.target_ruby_version)
78
+ end
79
+
80
+ def support_target_rails_version?(cop)
81
+ return true unless cop.class.respond_to?(:support_target_rails_version?)
82
+
83
+ cop.class.support_target_rails_version?(cop.target_rails_version)
84
+ end
85
+
78
86
  def reset_callbacks
79
87
  @callbacks.clear
80
88
  end
@@ -123,23 +123,19 @@ module RuboCop
123
123
  self.class::MSG
124
124
  end
125
125
 
126
- # rubocop:disable Metrics/CyclomaticComplexity
127
126
  def add_offense(node, location: :expression, message: nil, severity: nil)
128
127
  loc = find_location(node, location)
129
128
 
130
129
  return if duplicate_location?(loc)
131
130
 
132
- severity = custom_severity || severity || default_severity
133
-
134
- message ||= message(node)
135
- message = annotate(message)
131
+ severity = find_severity(node, severity)
132
+ message = find_message(node, message)
136
133
 
137
134
  status = enabled_line?(loc.line) ? correct(node) : :disabled
138
135
 
139
136
  @offenses << Offense.new(severity, loc, message, name, status)
140
137
  yield if block_given? && status != :disabled
141
138
  end
142
- # rubocop:enable Metrics/CyclomaticComplexity
143
139
 
144
140
  def find_location(node, loc)
145
141
  # Location can be provided as a symbol, e.g.: `:keyword`
@@ -176,6 +172,8 @@ module RuboCop
176
172
  end
177
173
 
178
174
  def disable_uncorrectable(node)
175
+ return unless node
176
+
179
177
  @disabled_lines ||= {}
180
178
  line = node.location.line
181
179
  return if @disabled_lines.key?(line)
@@ -221,8 +219,31 @@ module RuboCop
221
219
  !relevant_file?(file)
222
220
  end
223
221
 
222
+ # This method should be overridden when a cop's behavior depends
223
+ # on state that lives outside of these locations:
224
+ #
225
+ # (1) the file under inspection
226
+ # (2) the cop's source code
227
+ # (3) the config (eg a .rubocop.yml file)
228
+ #
229
+ # For example, some cops may want to look at other parts of
230
+ # the codebase being inspected to find violations. A cop may
231
+ # use the presence or absence of file `foo.rb` to determine
232
+ # whether a certain violation exists in `bar.rb`.
233
+ #
234
+ # Overriding this method allows the cop to indicate to RuboCop's
235
+ # ResultCache system when those external dependencies change,
236
+ # ie when the ResultCache should be invalidated.
237
+ def external_dependency_checksum
238
+ nil
239
+ end
240
+
224
241
  private
225
242
 
243
+ def find_message(node, message)
244
+ annotate(message || message(node))
245
+ end
246
+
226
247
  def annotate(message)
227
248
  RuboCop::Cop::MessageAnnotator.new(
228
249
  config, cop_name, cop_config, @options
@@ -250,6 +271,10 @@ module RuboCop
250
271
  @processed_source.comment_config.cop_enabled_at_line?(self, line_number)
251
272
  end
252
273
 
274
+ def find_severity(_node, severity)
275
+ custom_severity || severity || default_severity
276
+ end
277
+
253
278
  def default_severity
254
279
  self.class.lint? ? :warning : :convention
255
280
  end
@@ -154,16 +154,17 @@ module RuboCop
154
154
 
155
155
  # :nodoc:
156
156
  def validate_range(range)
157
- return if range.source_buffer == @source_buffer
157
+ buffer = range.source_buffer
158
+ return if buffer == @source_buffer
158
159
 
159
- unless range.source_buffer.is_a?(Parser::Source::Buffer)
160
+ unless buffer.is_a?(Parser::Source::Buffer)
160
161
  # actually this should be enforced by parser gem
161
- raise 'Corrector expected range source buffer to be a '\
162
- "Parser::Source::Buffer, but got #{range.source_buffer.class}"
162
+ raise 'Corrector expected range source buffer to be a ' \
163
+ "Parser::Source::Buffer, but got #{buffer.class}"
163
164
  end
164
- raise "Correction target buffer #{range.source_buffer.object_id} "\
165
- "name:#{range.source_buffer.name.inspect}"\
166
- " is not current #{@source_buffer.object_id} "\
165
+ raise "Correction target buffer #{buffer.object_id} " \
166
+ "name:#{buffer.name.inspect}" \
167
+ " is not current #{@source_buffer.object_id} " \
167
168
  "name:#{@source_buffer.name.inspect} under investigation"
168
169
  end
169
170
  end