rubocop 0.9.1 → 0.10.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 (149) hide show
  1. data/.travis.yml +3 -1
  2. data/CHANGELOG.md +38 -0
  3. data/README.md +34 -0
  4. data/Rakefile +3 -0
  5. data/config/default.yml +14 -1
  6. data/config/enabled.yml +30 -7
  7. data/lib/rubocop.rb +15 -0
  8. data/lib/rubocop/cli.rb +48 -154
  9. data/lib/rubocop/config.rb +19 -22
  10. data/lib/rubocop/config_store.rb +2 -4
  11. data/lib/rubocop/cop/commissioner.rb +90 -0
  12. data/lib/rubocop/cop/cop.rb +38 -31
  13. data/lib/rubocop/cop/corrector.rb +84 -0
  14. data/lib/rubocop/cop/lint/assignment_in_condition.rb +0 -3
  15. data/lib/rubocop/cop/lint/block_alignment.rb +151 -0
  16. data/lib/rubocop/cop/lint/empty_ensure.rb +18 -0
  17. data/lib/rubocop/cop/lint/end_alignment.rb +0 -124
  18. data/lib/rubocop/cop/lint/end_in_method.rb +0 -2
  19. data/lib/rubocop/cop/lint/ensure_return.rb +3 -3
  20. data/lib/rubocop/cop/lint/eval.rb +0 -2
  21. data/lib/rubocop/cop/lint/handle_exceptions.rb +0 -2
  22. data/lib/rubocop/cop/lint/literal_in_condition.rb +0 -10
  23. data/lib/rubocop/cop/lint/loop.rb +0 -2
  24. data/lib/rubocop/cop/lint/rescue_exception.rb +0 -2
  25. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +2 -2
  26. data/lib/rubocop/cop/lint/unreachable_code.rb +0 -2
  27. data/lib/rubocop/cop/lint/unused_local_variable.rb +2 -2
  28. data/lib/rubocop/cop/lint/void.rb +0 -2
  29. data/lib/rubocop/cop/offence.rb +9 -0
  30. data/lib/rubocop/cop/rails/validation.rb +2 -1
  31. data/lib/rubocop/cop/style/access_control.rb +4 -3
  32. data/lib/rubocop/cop/style/alias.rb +2 -4
  33. data/lib/rubocop/cop/style/align_parameters.rb +0 -2
  34. data/lib/rubocop/cop/style/and_or.rb +4 -6
  35. data/lib/rubocop/cop/style/ascii_comments.rb +2 -2
  36. data/lib/rubocop/cop/style/ascii_identifiers.rb +2 -2
  37. data/lib/rubocop/cop/style/attr.rb +0 -2
  38. data/lib/rubocop/cop/style/avoid_class_vars.rb +0 -1
  39. data/lib/rubocop/cop/style/avoid_for.rb +0 -2
  40. data/lib/rubocop/cop/style/avoid_global_vars.rb +3 -7
  41. data/lib/rubocop/cop/style/avoid_perl_backrefs.rb +0 -2
  42. data/lib/rubocop/cop/style/avoid_perlisms.rb +2 -4
  43. data/lib/rubocop/cop/style/begin_block.rb +0 -2
  44. data/lib/rubocop/cop/style/block_comments.rb +2 -2
  45. data/lib/rubocop/cop/style/block_nesting.rb +3 -3
  46. data/lib/rubocop/cop/style/blocks.rb +0 -2
  47. data/lib/rubocop/cop/style/case_equality.rb +0 -2
  48. data/lib/rubocop/cop/style/case_indentation.rb +0 -2
  49. data/lib/rubocop/cop/style/character_literal.rb +10 -6
  50. data/lib/rubocop/cop/style/class_and_module_camel_case.rb +0 -4
  51. data/lib/rubocop/cop/style/class_methods.rb +1 -1
  52. data/lib/rubocop/cop/style/collection_methods.rb +3 -5
  53. data/lib/rubocop/cop/style/colon_method_call.rb +3 -3
  54. data/lib/rubocop/cop/style/comment_annotation.rb +44 -0
  55. data/lib/rubocop/cop/style/constant_name.rb +0 -2
  56. data/lib/rubocop/cop/style/def_parentheses.rb +0 -8
  57. data/lib/rubocop/cop/style/documentation.rb +6 -2
  58. data/lib/rubocop/cop/style/dot_position.rb +0 -2
  59. data/lib/rubocop/cop/style/empty_line_between_defs.rb +0 -2
  60. data/lib/rubocop/cop/style/empty_lines.rb +10 -8
  61. data/lib/rubocop/cop/style/empty_literal.rb +3 -1
  62. data/lib/rubocop/cop/style/encoding.rb +7 -6
  63. data/lib/rubocop/cop/style/end_block.rb +0 -2
  64. data/lib/rubocop/cop/style/end_of_line.rb +4 -3
  65. data/lib/rubocop/cop/style/favor_join.rb +0 -2
  66. data/lib/rubocop/cop/style/favor_modifier.rb +9 -9
  67. data/lib/rubocop/cop/style/favor_sprintf.rb +0 -2
  68. data/lib/rubocop/cop/style/favor_unless_over_negated_if.rb +0 -2
  69. data/lib/rubocop/cop/style/hash_syntax.rb +0 -2
  70. data/lib/rubocop/cop/style/if_then_else.rb +0 -2
  71. data/lib/rubocop/cop/style/lambda.rb +0 -2
  72. data/lib/rubocop/cop/style/leading_comment_space.rb +2 -2
  73. data/lib/rubocop/cop/style/line_continuation.rb +4 -3
  74. data/lib/rubocop/cop/style/line_length.rb +4 -3
  75. data/lib/rubocop/cop/style/method_and_variable_snake_case.rb +4 -3
  76. data/lib/rubocop/cop/style/method_call_parentheses.rb +0 -2
  77. data/lib/rubocop/cop/style/method_length.rb +0 -4
  78. data/lib/rubocop/cop/style/not.rb +0 -2
  79. data/lib/rubocop/cop/style/op_method.rb +0 -2
  80. data/lib/rubocop/cop/style/parameter_lists.rb +0 -2
  81. data/lib/rubocop/cop/style/parentheses_around_condition.rb +12 -6
  82. data/lib/rubocop/cop/style/proc.rb +0 -2
  83. data/lib/rubocop/cop/style/reduce_arguments.rb +0 -2
  84. data/lib/rubocop/cop/style/redundant_begin.rb +45 -0
  85. data/lib/rubocop/cop/style/redundant_return.rb +59 -0
  86. data/lib/rubocop/cop/style/redundant_self.rb +83 -0
  87. data/lib/rubocop/cop/style/regexp_literal.rb +0 -2
  88. data/lib/rubocop/cop/style/rescue_modifier.rb +13 -21
  89. data/lib/rubocop/cop/style/semicolon.rb +15 -9
  90. data/lib/rubocop/cop/style/single_line_methods.rb +0 -4
  91. data/lib/rubocop/cop/style/space_after_comma_etc.rb +2 -2
  92. data/lib/rubocop/cop/style/space_after_control_keyword.rb +0 -1
  93. data/lib/rubocop/cop/style/string_literals.rb +5 -2
  94. data/lib/rubocop/cop/style/surrounding_space.rb +106 -91
  95. data/lib/rubocop/cop/style/tab.rb +4 -3
  96. data/lib/rubocop/cop/style/ternary_operator.rb +0 -4
  97. data/lib/rubocop/cop/style/trailing_whitespace.rb +4 -3
  98. data/lib/rubocop/cop/style/trivial_accessors.rb +51 -6
  99. data/lib/rubocop/cop/style/unless_else.rb +0 -2
  100. data/lib/rubocop/cop/style/variable_interpolation.rb +0 -2
  101. data/lib/rubocop/cop/style/when_then.rb +3 -3
  102. data/lib/rubocop/cop/style/while_until_do.rb +3 -5
  103. data/lib/rubocop/cop/style/word_array.rb +0 -2
  104. data/lib/rubocop/cop/util.rb +0 -4
  105. data/lib/rubocop/formatter/file_list_formatter.rb +18 -0
  106. data/lib/rubocop/formatter/formatter_set.rb +2 -1
  107. data/lib/rubocop/processed_source.rb +27 -0
  108. data/lib/rubocop/rake_task.rb +50 -0
  109. data/lib/rubocop/source_parser.rb +105 -0
  110. data/lib/rubocop/target_finder.rb +67 -0
  111. data/lib/rubocop/token.rb +22 -0
  112. data/lib/rubocop/version.rb +1 -1
  113. data/rubocop.gemspec +5 -3
  114. data/spec/project_spec.rb +0 -11
  115. data/spec/rubocop/cli_spec.rb +112 -6
  116. data/spec/rubocop/config_spec.rb +13 -17
  117. data/spec/rubocop/config_store_spec.rb +8 -23
  118. data/spec/rubocop/cops/commissioner_spec.rb +72 -0
  119. data/spec/rubocop/cops/corrector_spec.rb +63 -0
  120. data/spec/rubocop/cops/lint/assignment_in_condition_spec.rb +2 -2
  121. data/spec/rubocop/cops/lint/block_alignment_spec.rb +357 -0
  122. data/spec/rubocop/cops/lint/empty_ensure_spec.rb +33 -0
  123. data/spec/rubocop/cops/lint/end_alignment_spec.rb +0 -263
  124. data/spec/rubocop/cops/lint/ensure_return_spec.rb +6 -9
  125. data/spec/rubocop/cops/offence_spec.rb +28 -0
  126. data/spec/rubocop/cops/style/and_or_spec.rb +21 -11
  127. data/spec/rubocop/cops/style/ascii_identifiers_spec.rb +14 -0
  128. data/spec/rubocop/cops/style/avoid_global_vars_spec.rb +10 -14
  129. data/spec/rubocop/cops/style/character_literal_spec.rb +17 -2
  130. data/spec/rubocop/cops/style/colon_method_call_spec.rb +20 -15
  131. data/spec/rubocop/cops/style/comment_annotation_spec.rb +62 -0
  132. data/spec/rubocop/cops/style/encoding_spec.rb +7 -0
  133. data/spec/rubocop/cops/style/parentheses_around_condition_spec.rb +37 -9
  134. data/spec/rubocop/cops/style/redundant_begin_spec.rb +63 -0
  135. data/spec/rubocop/cops/style/redundant_return_spec.rb +64 -0
  136. data/spec/rubocop/cops/style/redundant_self_spec.rb +76 -0
  137. data/spec/rubocop/cops/style/string_literals_spec.rb +18 -13
  138. data/spec/rubocop/cops/style/trivial_accessors_spec.rb +110 -52
  139. data/spec/rubocop/cops/style/when_then_spec.rb +14 -7
  140. data/spec/rubocop/cops/style/while_until_do_spec.rb +12 -0
  141. data/spec/rubocop/cops/variable_inspector_spec.rb +3 -5
  142. data/spec/rubocop/formatter/file_list_formatter_spec.rb +33 -0
  143. data/spec/rubocop/processed_source_spec.rb +67 -0
  144. data/spec/rubocop/source_parser_spec.rb +141 -0
  145. data/spec/rubocop/target_finder_spec.rb +180 -0
  146. data/spec/rubocop/token_spec.rb +27 -0
  147. data/spec/spec_helper.rb +24 -4
  148. metadata +108 -18
  149. checksums.yaml +0 -7
@@ -4,4 +4,6 @@ rvm:
4
4
  - 2.0.0
5
5
  - jruby-19mode
6
6
  - rbx-19mode
7
- script: bundle exec rspec
7
+ script:
8
+ - bundle exec rspec
9
+ - bundle exec rubocop
@@ -2,6 +2,44 @@
2
2
 
3
3
  ## master (unreleased)
4
4
 
5
+ ## 0.10.0 (17/07/2013)
6
+
7
+ ### New features
8
+
9
+ * New cop `RedundantReturn` tracks redundant `return`s in method bodies
10
+ * New cop `RedundantBegin` tracks redundant `begin` blocks in method definitions.
11
+ * New cop `RedundantSelf` tracks redundant uses of `self`.
12
+ * New cop `EmptyEnsure` tracks empty `ensure` blocks.
13
+ * New cop `CommentAnnotation` tracks formatting of annotation comments such as TODO.
14
+ * Added custom rake task.
15
+ * New formatter `FileListFormatter` outputs just a list of files with offences in them (related to [#357](https://github.com/bbatsov/rubocop/issues/357)).
16
+
17
+ ### Changes
18
+
19
+ * `TrivialAccessors` now has an `ExactNameMatch` config option (related to [#308](https://github.com/bbatsov/rubocop/issues/308)).
20
+ * `TrivialAccessors` now has an `ExcludePredicates` config option (related to [#326](https://github.com/bbatsov/rubocop/issues/326)).
21
+ * Cops don't inherit from `Parser::AST::Rewriter` anymore. All 3rd party Cops should remove the call to `super` in their
22
+ callbacks. If you implement your own processing you need to define the `#investigate` method instead of `#inspect`. Refer to
23
+ the documentation of `Cop::Commissioner` and `Cop::Cop` classes for more information.
24
+ * `EndAlignment` cop split into `EndAlignment` and `BlockAlignment` cops.
25
+
26
+ ### Bugs fixed
27
+
28
+ * [#288](https://github.com/bbatsov/rubocop/issues/288) - work with absolute Excludes paths internally (2nd fix for this issue)
29
+ * `TrivialAccessors` now detects class attributes as well as instance attributes
30
+ * [#338](https://github.com/bbatsov/rubocop/issues/338) - fix end alignment of blocks in chained assignments
31
+ * [#345](https://github.com/bbatsov/rubocop/issues/345) - add `$SAFE` to the list of built-in global variables
32
+ * [#340](https://github.com/bbatsov/rubocop/issues/340) - override config parameters rather than merging them
33
+ * [#349](https://github.com/bbatsov/rubocop/issues/349) - fix false positive for `CharacterLiteral` (`%w(?)`)
34
+ * [#346](https://github.com/bbatsov/rubocop/issues/346) - support method chains for block end alignment checks
35
+ * [#350](https://github.com/bbatsov/rubocop/issues/350) - support line breaks between variables on left hand side for block end alignment checks
36
+ * [#356](https://github.com/bbatsov/rubocop/issues/350) - allow safe assignment in `ParenthesesAroundCondition`
37
+
38
+ ### Misc
39
+
40
+ * Improved performance on Ruby 1.9 by about 20%
41
+ * Improved overall performance by about 35%
42
+
5
43
  ## 0.9.1 (05/07/2013)
6
44
 
7
45
  ### New features
data/README.md CHANGED
@@ -165,6 +165,16 @@ subdirectories.
165
165
 
166
166
  ## Formatters
167
167
 
168
+ ### File List Formmater
169
+
170
+ Sometimes you might want to just open all files with offences in your
171
+ favorite editor. This formatter outputs just the names of the files
172
+ with offences in them and makes it possible to do something like:
173
+
174
+ ```
175
+ rubocop --format files | xargs vim
176
+ ```
177
+
168
178
  ### JSON Formatter
169
179
 
170
180
  You can get RuboCop's inspection result in JSON format by passing `--format json` option in command line.
@@ -287,6 +297,30 @@ like
287
297
  allows you to automatically check Ruby code style with RuboCop when
288
298
  files are modified.
289
299
 
300
+
301
+ ## Rake integration
302
+
303
+ To use RuboCop in your `Rakefile` add the following:
304
+
305
+ ```ruby
306
+ require 'rubocop/rake_task'
307
+
308
+ Rubocop::RakeTask.new
309
+ ```
310
+
311
+ The above will use default values
312
+
313
+ ```ruby
314
+ require 'rubocop/rake_task'
315
+
316
+ desc 'Run RuboCop on the lib directory'
317
+ Rubocop::RakeTask.new(:rubocop) do |task|
318
+ task.patterns = ['lib/**/*.rb']
319
+ # don't abort rake on failure
320
+ task.fail_on_error = false
321
+ end
322
+ ```
323
+
290
324
  ## Contributors
291
325
 
292
326
  Here's a [list](https://github.com/bbatsov/rubocop/contributors) of
data/Rakefile CHANGED
@@ -27,3 +27,6 @@ task default: :spec
27
27
 
28
28
  require 'yard'
29
29
  YARD::Rake::YardocTask.new
30
+
31
+ require 'rubocop/rake_task'
32
+ Rubocop::RakeTask.new
@@ -67,4 +67,17 @@ CollectionMethods:
67
67
 
68
68
  # Muli-line method chaining should be done with leading dots.
69
69
  DotPosition:
70
- Style: 'leading'
70
+ Style: 'leading'
71
+
72
+ # TrivialAccessors doesn't require exact name matches and doesn't allow predicated methods by default.
73
+ TrivialAccessors:
74
+ ExactNameMatch: false
75
+ AllowPredicates: false
76
+
77
+ # Allow safe assignment in conditions.
78
+ AssignmentInCondition:
79
+ AllowSafeAssignment: true
80
+
81
+ # Allow safe assignment in conditions.
82
+ ParenthesesAroundCondition:
83
+ AllowSafeAssignment: true
@@ -352,17 +352,40 @@ BeginBlock:
352
352
  EndBlock:
353
353
  Enabled: true
354
354
 
355
- ## Warnings
355
+ # Don't use return where it's not required.
356
+ RedundantReturn:
357
+ Enabled: true
358
+
359
+ # Don't use begin blocks when they are not needed.
360
+ RedundantBegin:
361
+ Enabled: true
362
+
363
+ # Don't use self where it's not needed.
364
+ RedundantSelf:
365
+ Enabled: true
366
+
367
+ # Checks the position of the dot in multi-line method calls.
368
+ DotPosition:
369
+ Enabled: true
370
+
371
+ # Checks for uses of Module#attr.
372
+ Attr:
373
+ Enabled: true
374
+
375
+ #################### Lint ################################
356
376
 
357
377
  # Don't use assignment in conditions.
358
378
  AssignmentInCondition:
359
379
  Enabled: true
360
- AllowSafeAssignment: true
361
380
 
362
381
  # Align ends correctly.
363
382
  EndAlignment:
364
383
  Enabled: true
365
384
 
385
+ # Align block ends correctly.
386
+ BlockAlignment:
387
+ Enabled: true
388
+
366
389
  # Possible use of operator/literal/variable in void context.
367
390
  Void:
368
391
  Enabled: true
@@ -388,15 +411,15 @@ EndInMethod:
388
411
  LiteralInCondition:
389
412
  Enabled: true
390
413
 
391
- # Checks the position of the dot in multi-line method calls.
392
- DotPosition:
414
+ # Checks for empty ensure block.
415
+ EmptyEnsure:
393
416
  Enabled: true
394
417
 
395
- # Checks for uses of Module#attr.
396
- Attr:
418
+ # Checks formatting of special comments (TODO, FIXME, OPTIMIZE, HACK, REVIEW).
419
+ CommentAnnotation:
397
420
  Enabled: true
398
421
 
399
- ## Rails
422
+ ##################### Rails ##################################
400
423
 
401
424
  # Use sexy validations.
402
425
  Validation:
@@ -1,16 +1,22 @@
1
1
  # encoding: utf-8
2
2
 
3
+ require 'backports/2.0.0/array/bsearch'
3
4
  require 'rainbow'
4
5
  require 'English'
5
6
  require 'parser/current'
6
7
  require 'ast/sexp'
8
+ require 'powerpack'
7
9
 
8
10
  require 'rubocop/cop/util'
9
11
  require 'rubocop/cop/variable_inspector'
10
12
  require 'rubocop/cop/offence'
11
13
  require 'rubocop/cop/cop'
14
+ require 'rubocop/cop/commissioner'
15
+ require 'rubocop/cop/corrector'
12
16
 
13
17
  require 'rubocop/cop/lint/assignment_in_condition'
18
+ require 'rubocop/cop/lint/block_alignment'
19
+ require 'rubocop/cop/lint/empty_ensure'
14
20
  require 'rubocop/cop/lint/end_alignment'
15
21
  require 'rubocop/cop/lint/end_in_method'
16
22
  require 'rubocop/cop/lint/ensure_return'
@@ -47,6 +53,7 @@ require 'rubocop/cop/style/class_and_module_camel_case'
47
53
  require 'rubocop/cop/style/class_methods'
48
54
  require 'rubocop/cop/style/collection_methods'
49
55
  require 'rubocop/cop/style/colon_method_call'
56
+ require 'rubocop/cop/style/comment_annotation'
50
57
  require 'rubocop/cop/style/constant_name'
51
58
  require 'rubocop/cop/style/def_parentheses'
52
59
  require 'rubocop/cop/style/documentation'
@@ -80,6 +87,9 @@ require 'rubocop/cop/style/parameter_lists'
80
87
  require 'rubocop/cop/style/parentheses_around_condition'
81
88
  require 'rubocop/cop/style/proc'
82
89
  require 'rubocop/cop/style/reduce_arguments'
90
+ require 'rubocop/cop/style/redundant_begin'
91
+ require 'rubocop/cop/style/redundant_return'
92
+ require 'rubocop/cop/style/redundant_self'
83
93
  require 'rubocop/cop/style/regexp_literal'
84
94
  require 'rubocop/cop/style/rescue_modifier'
85
95
  require 'rubocop/cop/style/semicolon'
@@ -108,9 +118,14 @@ require 'rubocop/formatter/emacs_style_formatter'
108
118
  require 'rubocop/formatter/clang_style_formatter'
109
119
  require 'rubocop/formatter/progress_formatter'
110
120
  require 'rubocop/formatter/json_formatter'
121
+ require 'rubocop/formatter/file_list_formatter'
111
122
  require 'rubocop/formatter/formatter_set'
112
123
 
113
124
  require 'rubocop/config'
114
125
  require 'rubocop/config_store'
126
+ require 'rubocop/target_finder'
127
+ require 'rubocop/token'
128
+ require 'rubocop/processed_source'
129
+ require 'rubocop/source_parser'
115
130
  require 'rubocop/cli'
116
131
  require 'rubocop/version'
@@ -19,7 +19,7 @@ module Rubocop
19
19
  @cops = Cop::Cop.all
20
20
  @errors = []
21
21
  @options = {}
22
- ConfigStore.prepare
22
+ @config_store = ConfigStore.new
23
23
  end
24
24
 
25
25
  # Entry point for the application logic. Here we
@@ -42,7 +42,7 @@ module Rubocop
42
42
  # filter out style cops when --lint is passed
43
43
  @cops.select!(&:lint?) if @options[:lint]
44
44
 
45
- target_files = target_files(args)
45
+ target_files = target_finder.find(args)
46
46
  target_files.each(&:freeze).freeze
47
47
  inspected_files = []
48
48
  any_failed = false
@@ -78,9 +78,7 @@ module Rubocop
78
78
 
79
79
  def inspect_file(file)
80
80
  begin
81
- ast, comments, tokens, source_buffer, source, syntax_offences =
82
- CLI.parse(file) { |sb| sb.read }
83
-
81
+ processed_source = SourceParser.parse_file(file)
84
82
  rescue Encoding::UndefinedConversionError, ArgumentError => e
85
83
  handle_error(e, "An error occurred while parsing #{file}.".color(:red))
86
84
  return []
@@ -89,30 +87,39 @@ module Rubocop
89
87
  # If we got any syntax errors, return only the syntax offences.
90
88
  # Parser may return nil for AST even though there are no syntax errors.
91
89
  # e.g. sources which contain only comments
92
- return syntax_offences unless syntax_offences.empty?
90
+ unless processed_source.diagnostics.empty?
91
+ return processed_source.diagnostics.map do |diagnostic|
92
+ Cop::Offence.from_diagnostic(diagnostic)
93
+ end
94
+ end
93
95
 
94
- config = ConfigStore.for(file)
95
- disabled_lines = disabled_lines_in(source)
96
+ config = @config_store.for(file)
96
97
 
97
98
  set_config_for_all_cops(config)
98
99
 
99
- @cops.reduce([]) do |offences, cop_class|
100
+ cops = []
101
+ @cops.each do |cop_class|
100
102
  cop_name = cop_class.cop_name
101
- if config.cop_enabled?(cop_name)
102
- cop = setup_cop(cop_class, disabled_lines)
103
- if !@options[:only] || @options[:only] == cop_name
104
- begin
105
- cop.inspect(source_buffer, source, tokens, ast, comments)
106
- rescue => e
107
- handle_error(e,
108
- "An error occurred while #{cop.name}".color(:red) +
109
- " cop was inspecting #{file}.".color(:red))
110
- end
111
- end
112
- offences.concat(cop.offences)
103
+ next unless config.cop_enabled?(cop_name)
104
+ next unless !@options[:only] || @options[:only] == cop_name
105
+ cop = setup_cop(cop_class, processed_source.disabled_lines_for_cops)
106
+ cops << cop
107
+ end
108
+ commissioner = Cop::Commissioner.new(cops)
109
+ offences = commissioner.investigate(processed_source)
110
+ process_commissioner_errors(file, commissioner.errors)
111
+ autocorrect(processed_source.buffer, cops)
112
+ offences.sort
113
+ end
114
+
115
+ def process_commissioner_errors(file, file_errors)
116
+ file_errors.each do |cop, errors|
117
+ errors.each do |e|
118
+ handle_error(e,
119
+ "An error occurred while #{cop.name}".color(:red) +
120
+ " cop was inspecting #{file}.".color(:red))
113
121
  end
114
- offences
115
- end.sort
122
+ end
116
123
  end
117
124
 
118
125
  def set_config_for_all_cops(config)
@@ -121,11 +128,13 @@ module Rubocop
121
128
  end
122
129
  end
123
130
 
124
- def setup_cop(cop_class, disabled_lines = nil)
131
+ def setup_cop(cop_class, disabled_lines_for_cops = nil)
125
132
  cop = cop_class.new
126
133
  cop.debug = @options[:debug]
127
134
  cop.autocorrect = @options[:autocorrect]
128
- cop.disabled_lines = disabled_lines[cop_class.cop_name] if disabled_lines
135
+ if disabled_lines_for_cops
136
+ cop.disabled_lines = disabled_lines_for_cops[cop_class.cop_name]
137
+ end
129
138
  cop
130
139
  end
131
140
 
@@ -151,7 +160,7 @@ module Rubocop
151
160
  end
152
161
  opts.on('-c', '--config FILE', 'Specify configuration file.') do |f|
153
162
  @options[:config] = f
154
- ConfigStore.set_options_config(@options[:config])
163
+ @config_store.set_options_config(@options[:config])
155
164
  end
156
165
  opts.on('--only COP', 'Run just one cop.') do |s|
157
166
  @options[:only] = s
@@ -166,6 +175,7 @@ module Rubocop
166
175
  ' [c]lang',
167
176
  ' [e]macs',
168
177
  ' [j]son',
178
+ ' [f]iles',
169
179
  ' custom formatter class name') do |key|
170
180
  @options[:formatters] ||= []
171
181
  @options[:formatters] << [key]
@@ -240,139 +250,27 @@ module Rubocop
240
250
  puts Rubocop::Version.version(true)
241
251
  end
242
252
 
243
- def disabled_lines_in(source)
244
- disabled_lines = Hash.new([])
245
- disabled_section = {}
246
- regexp = '# rubocop : (%s)\b ((?:\w+,? )+)'.gsub(' ', '\s*')
247
- section_regexp = '^\s*' + sprintf(regexp, '(?:dis|en)able')
248
- single_line_regexp = '\S.*' + sprintf(regexp, 'disable')
249
-
250
- source.each_with_index do |line, ix|
251
- each_mentioned_cop(/#{section_regexp}/, line) do |cop_name, kind|
252
- disabled_section[cop_name] = (kind == 'disable')
253
- end
254
- disabled_section.keys.each do |cop_name|
255
- disabled_lines[cop_name] += [ix + 1] if disabled_section[cop_name]
256
- end
257
-
258
- each_mentioned_cop(/#{single_line_regexp}/, line) do |cop_name, kind|
259
- disabled_lines[cop_name] += [ix + 1] if kind == 'disable'
260
- end
261
- end
262
- disabled_lines
263
- end
264
-
265
- def each_mentioned_cop(regexp, line)
266
- match = line.match(regexp)
267
- if match
268
- kind, cops = match.captures
269
- cops = Cop::Cop.all.map(&:cop_name).join(',') if cops.include?('all')
270
- cops.split(/,\s*/).each { |cop_name| yield cop_name, kind }
271
- end
272
- end
273
-
274
- def self.parse(file)
275
- parser = Parser::CurrentRuby.new
276
-
277
- # On JRuby and Rubinius, there's a risk that we hang in
278
- # tokenize() if we don't set the all errors as fatal flag.
279
- parser.diagnostics.all_errors_are_fatal = RUBY_ENGINE != 'ruby'
280
- parser.diagnostics.ignore_warnings = false
253
+ def autocorrect(buffer, cops)
254
+ return unless @options[:autocorrect]
281
255
 
282
- diagnostics = []
283
- parser.diagnostics.consumer = lambda do |diagnostic|
284
- diagnostics << diagnostic
256
+ corrections = cops.reduce([]) do |array, cop|
257
+ array.concat(cop.corrections)
258
+ array
285
259
  end
286
260
 
287
- source_buffer = Parser::Source::Buffer.new(file, 1)
288
- yield source_buffer
289
-
290
- begin
291
- ast, comments, tokens = parser.tokenize(source_buffer)
292
- rescue Parser::SyntaxError # rubocop:disable HandleExceptions
293
- # All errors are in diagnostics. No need to handle exception.
294
- end
261
+ corrector = Cop::Corrector.new(buffer, corrections)
262
+ new_source = corrector.rewrite
295
263
 
296
- if tokens
297
- tokens = tokens.map do |t|
298
- type, details = *t
299
- text, range = *details
300
- Rubocop::Cop::Token.new(range, type, text)
301
- end
264
+ unless new_source == buffer.source
265
+ filename = buffer.instance_variable_get(:@name)
266
+ File.open(filename, 'w') { |f| f.write(new_source) }
302
267
  end
303
-
304
- syntax_offences = diagnostics.map do |d|
305
- Cop::Offence.new(d.level, d.location, "#{d.message}",
306
- 'Syntax')
307
- end
308
-
309
- source = source_buffer.source.split($RS)
310
-
311
- [ast, comments, tokens, source_buffer, source, syntax_offences]
312
- end
313
-
314
- # Generate a list of target files by expanding globing patterns
315
- # (if any). If args is empty recursively finds all Ruby source
316
- # files under the current directory
317
- # @return [Array] array of filenames
318
- def target_files(args)
319
- return ruby_files if args.empty?
320
-
321
- files = []
322
-
323
- args.each do |target|
324
- if File.directory?(target)
325
- files += ruby_files(target.chomp(File::SEPARATOR))
326
- elsif target =~ /\*/
327
- files += Dir[target]
328
- else
329
- files << target
330
- end
331
- end
332
-
333
- files.map { |f| File.expand_path(f) }.uniq
334
- end
335
-
336
- # Finds all Ruby source files under the current or other supplied
337
- # directory. A Ruby source file is defined as a file with the `.rb`
338
- # extension or a file with no extension that has a ruby shebang line
339
- # as its first line.
340
- # It is possible to specify includes and excludes using the config file,
341
- # so you can include other Ruby files like Rakefiles and gemspecs.
342
- # @param root Root directory under which to search for ruby source files
343
- # @return [Array] Array of filenames
344
- def ruby_files(root = Dir.pwd)
345
- files = Dir["#{root}/**/*"].select { |file| FileTest.file?(file) }
346
-
347
- rb = []
348
-
349
- rb += files.select { |file| File.extname(file) == '.rb' }
350
- rb += files.select do |file|
351
- if File.extname(file) == '' && !excluded_file?(file)
352
- begin
353
- File.open(file) { |f| f.readline } =~ /#!.*ruby/
354
- rescue EOFError, ArgumentError => e
355
- log_error(e, "Unprocessable file #{file.inspect}: ")
356
- false
357
- end
358
- end
359
- end
360
-
361
- rb += files.select do |file|
362
- config = ConfigStore.for(file)
363
- config.file_to_include?(file)
364
- end
365
-
366
- rb.reject { |file| excluded_file?(file) }.uniq
367
268
  end
368
269
 
369
270
  private
370
271
 
371
- def log_error(e, msg = '')
372
- if @options[:debug]
373
- error_message = "#{e.class}, #{e.message}"
374
- warn "#{msg}\t#{error_message}"
375
- end
272
+ def target_finder
273
+ @target_finder ||= TargetFinder.new(@config_store, @options[:debug])
376
274
  end
377
275
 
378
276
  def formatter_set
@@ -396,9 +294,5 @@ module Rubocop
396
294
  message << " Please use #{alternative} instead." if alternative
397
295
  warn message
398
296
  end
399
-
400
- def excluded_file?(file)
401
- ConfigStore.for(file).file_to_exclude?(file)
402
- end
403
297
  end
404
298
  end