rubocop 0.19.1 → 0.20.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of rubocop might be problematic. Click here for more details.

Files changed (192) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +4 -0
  3. data/CHANGELOG.md +60 -1
  4. data/CONTRIBUTING.md +2 -1
  5. data/README.md +9 -7
  6. data/config/default.yml +3 -3
  7. data/config/disabled.yml +4 -0
  8. data/config/enabled.yml +45 -21
  9. data/lib/rubocop.rb +30 -9
  10. data/lib/rubocop/cli.rb +1 -1
  11. data/lib/rubocop/comment_config.rb +4 -2
  12. data/lib/rubocop/config.rb +16 -22
  13. data/lib/rubocop/config_loader.rb +29 -26
  14. data/lib/rubocop/cop/commissioner.rb +1 -1
  15. data/lib/rubocop/cop/cop.rb +6 -6
  16. data/lib/rubocop/cop/lint/assignment_in_condition.rb +1 -1
  17. data/lib/rubocop/cop/lint/condition_position.rb +1 -1
  18. data/lib/rubocop/cop/lint/debugger.rb +1 -1
  19. data/lib/rubocop/cop/lint/deprecated_class_methods.rb +9 -7
  20. data/lib/rubocop/cop/lint/else_layout.rb +1 -1
  21. data/lib/rubocop/cop/lint/empty_ensure.rb +1 -1
  22. data/lib/rubocop/cop/lint/empty_interpolation.rb +22 -0
  23. data/lib/rubocop/cop/lint/end_in_method.rb +1 -1
  24. data/lib/rubocop/cop/lint/ensure_return.rb +1 -1
  25. data/lib/rubocop/cop/lint/eval.rb +1 -1
  26. data/lib/rubocop/cop/lint/literal_in_condition.rb +2 -2
  27. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +9 -0
  28. data/lib/rubocop/cop/lint/loop.rb +2 -2
  29. data/lib/rubocop/cop/lint/require_parentheses.rb +0 -4
  30. data/lib/rubocop/cop/lint/rescue_exception.rb +1 -1
  31. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +1 -1
  32. data/lib/rubocop/cop/lint/space_before_first_arg.rb +36 -0
  33. data/lib/rubocop/cop/lint/string_conversion_in_interpolation.rb +14 -2
  34. data/lib/rubocop/cop/lint/useless_access_modifier.rb +57 -0
  35. data/lib/rubocop/cop/lint/useless_setter_call.rb +1 -1
  36. data/lib/rubocop/cop/lint/void.rb +3 -3
  37. data/lib/rubocop/cop/mixin/space_after_punctuation.rb +1 -1
  38. data/lib/rubocop/cop/offense.rb +3 -21
  39. data/lib/rubocop/cop/rails/action_filter.rb +1 -1
  40. data/lib/rubocop/cop/rails/default_scope.rb +1 -1
  41. data/lib/rubocop/cop/rails/has_and_belongs_to_many.rb +1 -1
  42. data/lib/rubocop/cop/rails/read_write_attribute.rb +43 -0
  43. data/lib/rubocop/cop/rails/scope_args.rb +1 -1
  44. data/lib/rubocop/cop/rails/validation.rb +1 -1
  45. data/lib/rubocop/cop/severity.rb +76 -0
  46. data/lib/rubocop/cop/style/access_modifier_indentation.rb +1 -1
  47. data/lib/rubocop/cop/style/accessor_method_name.rb +2 -2
  48. data/lib/rubocop/cop/style/alias.rb +1 -1
  49. data/lib/rubocop/cop/style/align_hash.rb +1 -1
  50. data/lib/rubocop/cop/style/and_or.rb +1 -1
  51. data/lib/rubocop/cop/style/{favor_join.rb → array_join.rb} +2 -2
  52. data/lib/rubocop/cop/style/begin_block.rb +1 -1
  53. data/lib/rubocop/cop/style/block_nesting.rb +12 -8
  54. data/lib/rubocop/cop/style/braces_around_hash_parameters.rb +1 -1
  55. data/lib/rubocop/cop/style/case_equality.rb +1 -1
  56. data/lib/rubocop/cop/style/case_indentation.rb +5 -5
  57. data/lib/rubocop/cop/style/class_methods.rb +19 -3
  58. data/lib/rubocop/cop/style/class_vars.rb +1 -1
  59. data/lib/rubocop/cop/style/collection_methods.rb +17 -7
  60. data/lib/rubocop/cop/style/colon_method_call.rb +1 -1
  61. data/lib/rubocop/cop/style/{def_parentheses.rb → def_with_parentheses.rb} +0 -0
  62. data/lib/rubocop/cop/style/{hash_methods.rb → deprecated_hash_methods.rb} +5 -4
  63. data/lib/rubocop/cop/style/double_negation.rb +1 -1
  64. data/lib/rubocop/cop/style/empty_lines_around_access_modifier.rb +1 -1
  65. data/lib/rubocop/cop/style/end_block.rb +1 -1
  66. data/lib/rubocop/cop/style/even_odd.rb +2 -2
  67. data/lib/rubocop/cop/style/file_name.rb +1 -1
  68. data/lib/rubocop/cop/style/for.rb +2 -2
  69. data/lib/rubocop/cop/style/format_string.rb +1 -1
  70. data/lib/rubocop/cop/style/guard_clause.rb +69 -0
  71. data/lib/rubocop/cop/style/hash_syntax.rb +6 -10
  72. data/lib/rubocop/cop/style/if_unless_modifier.rb +2 -2
  73. data/lib/rubocop/cop/style/lambda.rb +2 -2
  74. data/lib/rubocop/cop/style/line_end_concatenation.rb +16 -9
  75. data/lib/rubocop/cop/style/multiline_if_then.rb +1 -1
  76. data/lib/rubocop/cop/style/multiline_ternary_operator.rb +2 -2
  77. data/lib/rubocop/cop/style/negated_if.rb +37 -0
  78. data/lib/rubocop/cop/style/negated_while.rb +33 -0
  79. data/lib/rubocop/cop/style/nested_ternary_operator.rb +1 -1
  80. data/lib/rubocop/cop/style/nil_comparison.rb +14 -10
  81. data/lib/rubocop/cop/style/non_nil_check.rb +70 -0
  82. data/lib/rubocop/cop/style/not.rb +25 -1
  83. data/lib/rubocop/cop/style/numeric_literals.rb +1 -1
  84. data/lib/rubocop/cop/style/op_method.rb +4 -4
  85. data/lib/rubocop/cop/style/parentheses_around_condition.rb +1 -1
  86. data/lib/rubocop/cop/style/predicate_name.rb +1 -1
  87. data/lib/rubocop/cop/style/proc.rb +1 -1
  88. data/lib/rubocop/cop/style/raise_args.rb +3 -2
  89. data/lib/rubocop/cop/style/rescue_modifier.rb +1 -1
  90. data/lib/rubocop/cop/style/self_assignment.rb +2 -2
  91. data/lib/rubocop/cop/style/signal_exception.rb +6 -3
  92. data/lib/rubocop/cop/style/single_line_block_params.rb +1 -1
  93. data/lib/rubocop/cop/style/single_line_methods.rb +6 -5
  94. data/lib/rubocop/cop/style/single_space_before_first_arg.rb +41 -0
  95. data/lib/rubocop/cop/style/space_around_operators.rb +1 -2
  96. data/lib/rubocop/cop/style/special_global_vars.rb +8 -8
  97. data/lib/rubocop/cop/style/trailing_comma.rb +1 -1
  98. data/lib/rubocop/cop/style/trivial_accessors.rb +1 -1
  99. data/lib/rubocop/cop/style/unless_else.rb +1 -1
  100. data/lib/rubocop/cop/style/variable_interpolation.rb +10 -5
  101. data/lib/rubocop/cop/style/when_then.rb +1 -1
  102. data/lib/rubocop/cop/style/while_until_modifier.rb +1 -1
  103. data/lib/rubocop/cop/style/word_array.rb +1 -1
  104. data/lib/rubocop/cop/team.rb +12 -13
  105. data/lib/rubocop/cop/util.rb +4 -0
  106. data/lib/rubocop/cop/variable_inspector/locatable.rb +1 -1
  107. data/lib/rubocop/cop/variable_inspector/variable_table.rb +1 -1
  108. data/lib/rubocop/file_inspector.rb +46 -10
  109. data/lib/rubocop/formatter/disabled_config_formatter.rb +1 -1
  110. data/lib/rubocop/formatter/disabled_lines_formatter.rb +56 -0
  111. data/lib/rubocop/formatter/emacs_style_formatter.rb +1 -1
  112. data/lib/rubocop/formatter/formatter_set.rb +2 -1
  113. data/lib/rubocop/formatter/fuubar_style_formatter.rb +2 -4
  114. data/lib/rubocop/formatter/json_formatter.rb +3 -7
  115. data/lib/rubocop/formatter/progress_formatter.rb +1 -3
  116. data/lib/rubocop/formatter/simple_text_formatter.rb +7 -3
  117. data/lib/rubocop/options.rb +29 -10
  118. data/lib/rubocop/path_util.rb +2 -1
  119. data/lib/rubocop/processed_source.rb +8 -0
  120. data/lib/rubocop/target_finder.rb +33 -12
  121. data/lib/rubocop/version.rb +1 -1
  122. data/relnotes/v0.20.0.md +69 -0
  123. data/rubocop-todo.yml +2 -2
  124. data/spec/rubocop/cli_spec.rb +269 -94
  125. data/spec/rubocop/config_loader_spec.rb +14 -14
  126. data/spec/rubocop/config_spec.rb +8 -8
  127. data/spec/rubocop/cop/lint/deprecated_class_methods_spec.rb +11 -6
  128. data/spec/rubocop/cop/lint/empty_interpolation_spec.rb +18 -0
  129. data/spec/rubocop/cop/lint/eval_spec.rb +2 -4
  130. data/spec/rubocop/cop/lint/literal_in_interpolation_spec.rb +10 -0
  131. data/spec/rubocop/cop/lint/rescue_exception_spec.rb +0 -8
  132. data/spec/rubocop/cop/lint/shadowing_outer_local_variable_spec.rb +4 -4
  133. data/spec/rubocop/cop/lint/space_before_first_arg_spec.rb +48 -0
  134. data/spec/rubocop/cop/lint/string_conversion_in_interpolation_spec.rb +10 -0
  135. data/spec/rubocop/cop/lint/useless_access_modifier_spec.rb +154 -0
  136. data/spec/rubocop/cop/offense_spec.rb +1 -1
  137. data/spec/rubocop/cop/rails/read_write_attribute_spec.rb +19 -0
  138. data/spec/rubocop/cop/severity_spec.rb +113 -0
  139. data/spec/rubocop/cop/style/access_modifier_indentation_spec.rb +10 -10
  140. data/spec/rubocop/cop/style/alias_spec.rb +2 -2
  141. data/spec/rubocop/cop/style/and_or_spec.rb +2 -2
  142. data/spec/rubocop/cop/style/{favor_join_spec.rb → array_join_spec.rb} +1 -3
  143. data/spec/rubocop/cop/style/block_nesting_spec.rb +4 -4
  144. data/spec/rubocop/cop/style/case_equality_spec.rb +1 -0
  145. data/spec/rubocop/cop/style/case_indentation_spec.rb +12 -9
  146. data/spec/rubocop/cop/style/class_methods_spec.rb +23 -0
  147. data/spec/rubocop/cop/style/collection_methods_spec.rb +2 -2
  148. data/spec/rubocop/cop/style/{hash_methods_spec.rb → deprecated_hash_methods_spec.rb} +3 -3
  149. data/spec/rubocop/cop/style/empty_lines_around_access_modifier_spec.rb +2 -2
  150. data/spec/rubocop/cop/style/even_odd_spec.rb +8 -8
  151. data/spec/rubocop/cop/style/file_name_spec.rb +55 -42
  152. data/spec/rubocop/cop/style/for_spec.rb +4 -4
  153. data/spec/rubocop/cop/style/format_string_spec.rb +10 -10
  154. data/spec/rubocop/cop/style/guard_clause_spec.rb +77 -0
  155. data/spec/rubocop/cop/style/hash_syntax_spec.rb +4 -2
  156. data/spec/rubocop/cop/style/if_unless_modifier_spec.rb +4 -4
  157. data/spec/rubocop/cop/style/lambda_spec.rb +2 -2
  158. data/spec/rubocop/cop/style/line_end_concatenation_spec.rb +21 -0
  159. data/spec/rubocop/cop/style/multiline_if_then_spec.rb +1 -1
  160. data/spec/rubocop/cop/style/{favor_unless_over_negated_if_spec.rb → negated_if_spec.rb} +8 -3
  161. data/spec/rubocop/cop/style/{favor_until_over_negated_while_spec.rb → negated_while_spec.rb} +8 -3
  162. data/spec/rubocop/cop/style/nil_comparison_spec.rb +7 -13
  163. data/spec/rubocop/cop/style/non_nil_check_spec.rb +35 -0
  164. data/spec/rubocop/cop/style/not_spec.rb +11 -0
  165. data/spec/rubocop/cop/style/numeric_literals_spec.rb +0 -2
  166. data/spec/rubocop/cop/style/op_method_spec.rb +10 -2
  167. data/spec/rubocop/cop/style/parentheses_around_condition_spec.rb +2 -2
  168. data/spec/rubocop/cop/style/predicate_name_spec.rb +2 -1
  169. data/spec/rubocop/cop/style/raise_args_spec.rb +5 -0
  170. data/spec/rubocop/cop/style/rescue_modifier_spec.rb +2 -2
  171. data/spec/rubocop/cop/style/self_assignment_spec.rb +4 -4
  172. data/spec/rubocop/cop/style/signal_exception_spec.rb +24 -0
  173. data/spec/rubocop/cop/style/single_line_block_params_spec.rb +2 -0
  174. data/spec/rubocop/cop/style/single_space_before_first_arg_spec.rb +63 -0
  175. data/spec/rubocop/cop/style/special_global_vars_spec.rb +6 -5
  176. data/spec/rubocop/cop/style/trivial_accessors_spec.rb +6 -3
  177. data/spec/rubocop/cop/style/unless_else_spec.rb +2 -4
  178. data/spec/rubocop/cop/style/variable_interpolation_spec.rb +15 -6
  179. data/spec/rubocop/cop/style/when_then_spec.rb +3 -4
  180. data/spec/rubocop/cop/team_spec.rb +4 -18
  181. data/spec/rubocop/file_inspector_spec.rb +4 -0
  182. data/spec/rubocop/formatter/disabled_config_formatter_spec.rb +1 -1
  183. data/spec/rubocop/formatter/disabled_lines_formatter_spec.rb +69 -0
  184. data/spec/rubocop/options_spec.rb +5 -0
  185. data/spec/rubocop/target_finder_spec.rb +42 -11
  186. data/spec/support/shared_context.rb +1 -1
  187. data/spec/support/statement_modifier_helper.rb +1 -1
  188. metadata +75 -50
  189. data/lib/rubocop/cop/rails/read_attribute.rb +0 -28
  190. data/lib/rubocop/cop/style/favor_unless_over_negated_if.rb +0 -24
  191. data/lib/rubocop/cop/style/favor_until_over_negated_while.rb +0 -20
  192. data/spec/rubocop/cop/rails/read_attribute_spec.rb +0 -13
@@ -0,0 +1,41 @@
1
+ # encoding: utf-8
2
+
3
+ module Rubocop
4
+ module Cop
5
+ module Style
6
+ # Checks that exactly one space is used between a method name and the
7
+ # first argument for method calls without parentheses.
8
+ #
9
+ # @example
10
+ #
11
+ # something x
12
+ # something y, z
13
+ #
14
+ class SingleSpaceBeforeFirstArg < Cop
15
+ MSG = 'Put one space between the method name and the first argument.'
16
+
17
+ def on_send(node)
18
+ return if parentheses?(node)
19
+
20
+ _receiver, method_name, *args = *node
21
+ return if args.empty?
22
+ return if operator?(method_name)
23
+ return if method_name.to_s.end_with?('=')
24
+
25
+ arg1 = args.first.loc.expression
26
+ return if arg1.line > node.loc.line
27
+
28
+ arg1_with_space = range_with_surrounding_space(arg1, :left)
29
+ space = Parser::Source::Range.new(arg1.source_buffer,
30
+ arg1_with_space.begin_pos,
31
+ arg1.begin_pos)
32
+ add_offense(space, space) if space.length > 1
33
+ end
34
+
35
+ def autocorrect(range)
36
+ @corrections << ->(corrector) { corrector.replace(range, ' ') }
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -72,8 +72,7 @@ module Rubocop
72
72
  when /\*\*/
73
73
  corrector.replace(range, '**')
74
74
  else
75
- corrector.insert_before(range, ' ') unless range.source =~ /^\s/
76
- corrector.insert_after(range, ' ') unless range.source =~ /\s$/
75
+ corrector.replace(range, " #{range.source.strip} ")
77
76
  end
78
77
  end
79
78
  end
@@ -5,9 +5,9 @@ module Rubocop
5
5
  module Style
6
6
  # This cop looks for uses of Perl-style global variables.
7
7
  class SpecialGlobalVars < Cop
8
- MSG_BOTH = 'Prefer %s from the English library, or %s over %s.'
9
- MSG_ENGLISH = 'Prefer %s from the English library over %s.'
10
- MSG_REGULAR = 'Prefer %s over %s.'
8
+ MSG_BOTH = 'Prefer `%s` from the English library, or `%s` over `%s`.'
9
+ MSG_ENGLISH = 'Prefer `%s` from the English library over `%s`.'
10
+ MSG_REGULAR = 'Prefer `%s` over `%s`.'
11
11
 
12
12
  PREFERRED_VARS = {
13
13
  '$:' => ['$LOAD_PATH'],
@@ -56,15 +56,15 @@ module Rubocop
56
56
  end
57
57
 
58
58
  # For now, we assume that lists are 2 items or less. Easy grammar!
59
- regular_msg = regular.join(' or ')
60
- english_msg = english.join(' or ')
59
+ regular_msg = regular.join('` or `')
60
+ english_msg = english.join('` or `')
61
61
 
62
62
  if regular.length > 0 && english.length > 0
63
- MSG_BOTH.format(english_msg, regular_msg, global_var)
63
+ format(MSG_BOTH, english_msg, regular_msg, global_var)
64
64
  elsif regular.length > 0
65
- MSG_REGULAR.format(regular_msg, global_var)
65
+ format(MSG_REGULAR, regular_msg, global_var)
66
66
  elsif english.length > 0
67
- MSG_ENGLISH.format(english_msg, global_var)
67
+ format(MSG_ENGLISH, english_msg, global_var)
68
68
  else
69
69
  fail 'Bug in SpecialGlobalVars - global var w/o preferred vars!'
70
70
  end
@@ -70,7 +70,7 @@ module Rubocop
70
70
 
71
71
  # Returns true if the node has round/square/curly brackets.
72
72
  def brackets?(node)
73
- !node.loc.end.nil?
73
+ node.loc.end
74
74
  end
75
75
 
76
76
  # Returns true if the round/square/curly brackets of the given node are
@@ -8,7 +8,7 @@ module Rubocop
8
8
  class TrivialAccessors < Cop
9
9
  include CheckMethods
10
10
 
11
- MSG = 'Use attr_%s to define trivial %s methods.'
11
+ MSG = 'Use `attr_%s` to define trivial %s methods.'
12
12
 
13
13
  private
14
14
 
@@ -5,7 +5,7 @@ module Rubocop
5
5
  module Style
6
6
  # This cop looks for *unless* expressions with *else* clauses.
7
7
  class UnlessElse < Cop
8
- MSG = 'Never use unless with else. Rewrite these with the ' \
8
+ MSG = 'Never use `unless` with `else`. Rewrite these with the ' \
9
9
  'positive case first.'
10
10
 
11
11
  def on_if(node)
@@ -5,20 +5,25 @@ module Rubocop
5
5
  module Style
6
6
  # This cop checks for variable interpolation (like "#@ivar").
7
7
  class VariableInterpolation < Cop
8
- MSG = 'Replace interpolated var %s with expression #{%s}.'
8
+ MSG = 'Replace interpolated variable `%s` with expression `#{%s}`.'
9
9
 
10
10
  def on_dstr(node)
11
11
  var_nodes(node.children).each do |v|
12
- var = (v.type == :nth_ref ? '$' : '') + v.to_a[0].to_s
12
+ var = v.loc.expression.source
13
13
 
14
- if node.loc.expression.source.include?("##{var}")
15
- add_offense(v, :expression, format(MSG, var, var))
16
- end
14
+ add_offense(v, :expression, format(MSG, var, var))
17
15
  end
18
16
  end
19
17
 
20
18
  private
21
19
 
20
+ def autocorrect(node)
21
+ @corrections << lambda do |corrector|
22
+ expr = node.loc.expression
23
+ corrector.replace(expr, "{#{expr.source}}")
24
+ end
25
+ end
26
+
22
27
  def var_nodes(nodes)
23
28
  nodes.select { |n| [:ivar, :cvar, :gvar, :nth_ref].include?(n.type) }
24
29
  end
@@ -5,7 +5,7 @@ module Rubocop
5
5
  module Style
6
6
  # This cop checks for *when;* uses in *case* expressions.
7
7
  class WhenThen < Cop
8
- MSG = 'Never use "when x;". Use "when x then" instead.'
8
+ MSG = 'Never use `when x;`. Use `when x then` instead.'
9
9
 
10
10
  def on_when(node)
11
11
  if node.loc.begin && node.loc.begin.is?(';')
@@ -25,7 +25,7 @@ module Rubocop
25
25
  private
26
26
 
27
27
  def message(keyword)
28
- "Favor modifier #{keyword} usage when you have a single-line body."
28
+ "Favor modifier `#{keyword}` usage when having a single-line body."
29
29
  end
30
30
  end
31
31
  end
@@ -12,7 +12,7 @@ module Rubocop
12
12
  # parameter (the maximum number of something that's allowed).
13
13
  include ConfigurableMax
14
14
 
15
- MSG = 'Use %w or %W for array of words.'
15
+ MSG = 'Use `%w` or `%W` for array of words.'
16
16
 
17
17
  def on_array(node)
18
18
  array_elems = node.children
@@ -23,15 +23,7 @@ module Rubocop
23
23
  @options[:debug]
24
24
  end
25
25
 
26
- def inspect_file(file)
27
- begin
28
- processed_source = SourceParser.parse_file(file)
29
- rescue Encoding::UndefinedConversionError, ArgumentError => e
30
- range = Struct.new(:line, :column, :source_line).new(1, 0, '')
31
- return [Offense.new(:fatal, range, e.message.capitalize + '.',
32
- 'Parser')]
33
- end
34
-
26
+ def inspect_file(processed_source)
35
27
  # If we got any syntax errors, return only the syntax offenses.
36
28
  # Parser may return nil for AST even though there are no syntax errors.
37
29
  # e.g. sources which contain only comments
@@ -42,22 +34,29 @@ module Rubocop
42
34
 
43
35
  commissioner = Commissioner.new(cops)
44
36
  offenses = commissioner.investigate(processed_source)
45
- process_commissioner_errors(file, commissioner.errors)
37
+ process_commissioner_errors(
38
+ processed_source.file_path, commissioner.errors)
46
39
  autocorrect(processed_source.buffer, cops)
47
40
  offenses
48
41
  end
49
42
 
50
43
  def cops
51
44
  @cops ||= begin
52
- @cop_classes.reduce([]) do |instances, cop_class|
53
- next instances unless @config.cop_enabled?(cop_class)
54
- instances << cop_class.new(@config, @options)
45
+ @cop_classes.each_with_object([]) do |cop_class, instances|
46
+ if cop_enabled?(cop_class)
47
+ instances << cop_class.new(@config, @options)
48
+ end
55
49
  end
56
50
  end
57
51
  end
58
52
 
59
53
  private
60
54
 
55
+ def cop_enabled?(cop_class)
56
+ @config.cop_enabled?(cop_class) ||
57
+ cop_class.cop_name == @options[:only]
58
+ end
59
+
61
60
  def autocorrect(buffer, cops)
62
61
  @updated_source_file = false
63
62
  return unless autocorrect?
@@ -106,6 +106,10 @@ module Rubocop
106
106
  lambda?(node) || proc?(node)
107
107
  end
108
108
 
109
+ def parentheses?(node)
110
+ node.loc.respond_to?(:end) && node.loc.end
111
+ end
112
+
109
113
  def on_node(syms, sexp, excludes = [])
110
114
  yield sexp if Array(syms).include?(sexp.type)
111
115
 
@@ -24,7 +24,7 @@ module Rubocop
24
24
  end
25
25
 
26
26
  def inside_of_branch?
27
- !branch_point_node.nil?
27
+ branch_point_node
28
28
  end
29
29
 
30
30
  def branch_id
@@ -105,7 +105,7 @@ module Rubocop
105
105
  end
106
106
 
107
107
  def variable_exist?(name)
108
- !find_variable(name).nil?
108
+ find_variable(name)
109
109
  end
110
110
 
111
111
  def accessible_variables
@@ -22,11 +22,14 @@ module Rubocop
22
22
  break if yield
23
23
  offenses = process_file(file, config_store)
24
24
 
25
- any_failed = true unless offenses.empty?
25
+ any_failed = true if offenses.any? do |o|
26
+ o.severity >= fail_level
27
+ end
26
28
  inspected_files << file
27
29
  end
28
30
 
29
31
  formatter_set.finished(inspected_files.freeze)
32
+
30
33
  formatter_set.close_output_files
31
34
  any_failed
32
35
  end
@@ -46,28 +49,56 @@ module Rubocop
46
49
 
47
50
  def process_file(file, config_store)
48
51
  puts "Scanning #{file}" if @options[:debug]
49
- offenses = []
50
- formatter_set.file_started(file, {})
52
+ processed_source, offenses = process_source(file)
53
+
54
+ if offenses.any?
55
+ formatter_set.file_started(file, offenses)
56
+ formatter_set.file_finished(file, offenses.compact.sort.freeze)
57
+ return offenses
58
+ end
59
+
60
+ formatter_set.file_started(
61
+ file, cop_disabled_line_ranges: processed_source.disabled_line_ranges)
51
62
 
52
63
  # When running with --auto-correct, we need to inspect the file (which
53
64
  # includes writing a corrected version of it) until no more corrections
54
65
  # are made. This is because automatic corrections can introduce new
55
66
  # offenses. In the normal case the loop is only executed once.
56
67
  loop do
57
- new_offenses, updated_source_file = inspect_file(file, config_store)
58
- unique_new = new_offenses.reject { |n| offenses.include?(n) }
59
- offenses += unique_new
68
+ new_offenses, updated_source_file =
69
+ inspect_file(processed_source, config_store)
70
+ offenses += new_offenses.reject { |n| offenses.include?(n) }
60
71
  break unless updated_source_file
72
+
73
+ # We have to reprocess the source to pickup the changes. Since the
74
+ # change could (theoretically) introduce parsing errors, we break the
75
+ # loop if we find any.
76
+ processed_source, parse_offenses = process_source(file)
77
+ offenses += parse_offenses if parse_offenses.any?
61
78
  end
62
79
 
63
- formatter_set.file_finished(file, offenses.sort.freeze)
80
+ formatter_set.file_finished(file, offenses.compact.sort.freeze)
64
81
  offenses
65
82
  end
66
83
 
67
- def inspect_file(file, config_store)
68
- config = config_store.for(file)
84
+ def process_source(file)
85
+ begin
86
+ processed_source = SourceParser.parse_file(file)
87
+ rescue Encoding::UndefinedConversionError, ArgumentError => e
88
+ range = Struct.new(:line, :column, :source_line).new(1, 0, '')
89
+ return [
90
+ nil,
91
+ [Cop::Offense.new(:fatal, range, e.message.capitalize + '.',
92
+ 'Parser')]]
93
+ end
94
+
95
+ [processed_source, []]
96
+ end
97
+
98
+ def inspect_file(processed_source, config_store)
99
+ config = config_store.for(processed_source.file_path)
69
100
  team = Cop::Team.new(mobilized_cop_classes(config), config, @options)
70
- offenses = team.inspect_file(file)
101
+ offenses = team.inspect_file(processed_source)
71
102
  @errors.concat(team.errors)
72
103
  [offenses, team.updated_source_file?]
73
104
  end
@@ -109,5 +140,10 @@ module Rubocop
109
140
  exit(1)
110
141
  end
111
142
  end
143
+
144
+ def fail_level
145
+ @fail_level ||= Rubocop::Cop::Severity.new(
146
+ @options[:fail_level] || :refactor)
147
+ end
112
148
  end
113
149
  end
@@ -38,7 +38,7 @@ module Rubocop
38
38
  cfg.each { |key, value| output.puts " #{key}: #{value}" }
39
39
  end
40
40
  puts "Created #{output.path}."
41
- puts "Run rubocop with --config #{output.path}, or"
41
+ puts "Run `rubocop --config #{output.path}`, or"
42
42
  puts "add inherit_from: #{output.path} in a .rubocop.yml file."
43
43
  end
44
44
 
@@ -0,0 +1,56 @@
1
+ # encoding: utf-8
2
+ module Rubocop
3
+ module Formatter
4
+ # A basic formatter that displays the lines disabled
5
+ # inline comments.
6
+ class DisabledLinesFormatter < BaseFormatter
7
+ include PathUtil
8
+ include Colorizable
9
+
10
+ attr_reader :cop_disabled_line_ranges
11
+
12
+ def started(target_files)
13
+ @cop_disabled_line_ranges = {}
14
+ end
15
+
16
+ def file_started(file, options)
17
+ return unless options[:cop_disabled_line_ranges]
18
+
19
+ @cop_disabled_line_ranges[file] =
20
+ options[:cop_disabled_line_ranges]
21
+ end
22
+
23
+ def finished(inspected_files)
24
+ cops_disabled_in_comments_summary
25
+ end
26
+
27
+ private
28
+
29
+ def cops_disabled_in_comments_summary
30
+ summary = "\nCops disabled line ranges:\n\n"
31
+
32
+ @cop_disabled_line_ranges.each do |file, disabled_cops|
33
+ disabled_cops.each do |cop, line_ranges|
34
+ line_ranges.each do |line_range|
35
+ file = cyan(smart_path(file))
36
+ summary << "#{file}:#{line_range}: #{cop}\n"
37
+ end
38
+ end
39
+ end
40
+
41
+ output.puts summary
42
+ end
43
+
44
+ def smart_path(path)
45
+ # Ideally, we calculate this relative to the project root.
46
+ base_dir = Dir.pwd
47
+
48
+ if path.start_with? base_dir
49
+ relative_path(path, base_dir)
50
+ else
51
+ path
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
@@ -12,7 +12,7 @@ module Rubocop
12
12
  message << o.message
13
13
 
14
14
  output.printf("%s:%d:%d: %s: %s\n",
15
- file, o.line, o.real_column, o.severity_code,
15
+ file, o.line, o.real_column, o.severity.code,
16
16
  message)
17
17
  end
18
18
  end
@@ -14,7 +14,8 @@ module Rubocop
14
14
  'emacs' => EmacsStyleFormatter,
15
15
  'json' => JSONFormatter,
16
16
  'files' => FileListFormatter,
17
- 'offenses' => OffenseCountFormatter
17
+ 'offenses' => OffenseCountFormatter,
18
+ 'disabled' => DisabledLinesFormatter
18
19
  }
19
20
 
20
21
  FORMATTER_APIS = [:started, :file_started, :file_finished, :finished]
@@ -49,9 +49,7 @@ module Rubocop
49
49
  return if offenses.empty?
50
50
 
51
51
  offenses << @severest_offense if @severest_offense
52
- @severest_offense = offenses.max do |a, b|
53
- a.severity_level <=> b.severity_level
54
- end
52
+ @severest_offense = offenses.max_by { |offense| offense.severity }
55
53
  end
56
54
 
57
55
  def with_color
@@ -66,7 +64,7 @@ module Rubocop
66
64
 
67
65
  def progressbar_color
68
66
  if @severest_offense
69
- COLOR_FOR_SEVERITY[@severest_offense.severity]
67
+ COLOR_FOR_SEVERITY[@severest_offense.severity.name]
70
68
  else
71
69
  :green
72
70
  end