rubocop 0.31.0 → 0.35.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (177) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +315 -0
  3. data/README.md +199 -38
  4. data/config/default.yml +91 -12
  5. data/config/disabled.yml +45 -4
  6. data/config/enabled.yml +107 -9
  7. data/lib/rubocop/ast_node.rb +48 -0
  8. data/lib/rubocop/cli.rb +11 -1
  9. data/lib/rubocop/comment_config.rb +4 -1
  10. data/lib/rubocop/config.rb +26 -17
  11. data/lib/rubocop/config_loader.rb +61 -14
  12. data/lib/rubocop/cop/commissioner.rb +7 -12
  13. data/lib/rubocop/cop/cop.rb +43 -20
  14. data/lib/rubocop/cop/lint/block_alignment.rb +1 -1
  15. data/lib/rubocop/cop/lint/circular_argument_reference.rb +69 -0
  16. data/lib/rubocop/cop/lint/debugger.rb +9 -48
  17. data/lib/rubocop/cop/lint/def_end_alignment.rb +8 -4
  18. data/lib/rubocop/cop/lint/deprecated_class_methods.rb +42 -23
  19. data/lib/rubocop/cop/lint/duplicate_methods.rb +2 -2
  20. data/lib/rubocop/cop/lint/duplicated_key.rb +37 -0
  21. data/lib/rubocop/cop/lint/end_alignment.rb +33 -13
  22. data/lib/rubocop/cop/lint/eval.rb +6 -2
  23. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +175 -0
  24. data/lib/rubocop/cop/lint/literal_in_condition.rb +0 -5
  25. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +10 -0
  26. data/lib/rubocop/cop/lint/nested_method_definition.rb +31 -0
  27. data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +19 -1
  28. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +1 -1
  29. data/lib/rubocop/cop/lint/space_before_first_arg.rb +1 -1
  30. data/lib/rubocop/cop/lint/unneeded_disable.rb +72 -0
  31. data/lib/rubocop/cop/lint/unused_block_argument.rb +6 -0
  32. data/lib/rubocop/cop/lint/unused_method_argument.rb +8 -0
  33. data/lib/rubocop/cop/metrics/abc_size.rb +17 -6
  34. data/lib/rubocop/cop/metrics/class_length.rb +1 -1
  35. data/lib/rubocop/cop/metrics/method_length.rb +1 -3
  36. data/lib/rubocop/cop/metrics/module_length.rb +1 -1
  37. data/lib/rubocop/cop/metrics/parameter_lists.rb +1 -1
  38. data/lib/rubocop/cop/mixin/access_modifier_node.rb +1 -1
  39. data/lib/rubocop/cop/mixin/annotation_comment.rb +1 -2
  40. data/lib/rubocop/cop/mixin/autocorrect_alignment.rb +28 -4
  41. data/lib/rubocop/cop/mixin/autocorrect_unless_changing_ast.rb +26 -3
  42. data/lib/rubocop/cop/mixin/check_assignment.rb +2 -3
  43. data/lib/rubocop/cop/mixin/configurable_enforced_style.rb +59 -12
  44. data/lib/rubocop/cop/mixin/configurable_max.rb +1 -1
  45. data/lib/rubocop/cop/mixin/configurable_naming.rb +14 -3
  46. data/lib/rubocop/cop/mixin/empty_lines_around_body.rb +1 -3
  47. data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +10 -1
  48. data/lib/rubocop/cop/mixin/first_element_line_break.rb +41 -0
  49. data/lib/rubocop/cop/mixin/if_node.rb +10 -0
  50. data/lib/rubocop/cop/mixin/method_preference.rb +28 -0
  51. data/lib/rubocop/cop/mixin/negative_conditional.rb +1 -1
  52. data/lib/rubocop/cop/mixin/on_method_def.rb +4 -5
  53. data/lib/rubocop/cop/mixin/safe_assignment.rb +3 -14
  54. data/lib/rubocop/cop/mixin/space_after_punctuation.rb +8 -1
  55. data/lib/rubocop/cop/mixin/space_before_punctuation.rb +8 -1
  56. data/lib/rubocop/cop/mixin/statement_modifier.rb +4 -7
  57. data/lib/rubocop/cop/mixin/string_help.rb +1 -1
  58. data/lib/rubocop/cop/mixin/string_literals_help.rb +1 -1
  59. data/lib/rubocop/cop/mixin/surrounding_space.rb +5 -4
  60. data/lib/rubocop/cop/offense.rb +16 -3
  61. data/lib/rubocop/cop/performance/case_when_splat.rb +160 -0
  62. data/lib/rubocop/cop/performance/count.rb +35 -30
  63. data/lib/rubocop/cop/performance/detect.rb +16 -3
  64. data/lib/rubocop/cop/performance/fixed_size.rb +50 -0
  65. data/lib/rubocop/cop/performance/flat_map.rb +3 -3
  66. data/lib/rubocop/cop/performance/sample.rb +103 -59
  67. data/lib/rubocop/cop/performance/size.rb +2 -1
  68. data/lib/rubocop/cop/performance/string_replacement.rb +187 -0
  69. data/lib/rubocop/cop/rails/action_filter.rb +31 -5
  70. data/lib/rubocop/cop/rails/date.rb +15 -14
  71. data/lib/rubocop/cop/rails/pluralization_grammar.rb +97 -0
  72. data/lib/rubocop/cop/rails/read_write_attribute.rb +1 -1
  73. data/lib/rubocop/cop/rails/time_zone.rb +46 -18
  74. data/lib/rubocop/cop/style/alias.rb +1 -0
  75. data/lib/rubocop/cop/style/align_hash.rb +8 -15
  76. data/lib/rubocop/cop/style/align_parameters.rb +19 -7
  77. data/lib/rubocop/cop/style/and_or.rb +42 -13
  78. data/lib/rubocop/cop/style/auto_resource_cleanup.rb +2 -1
  79. data/lib/rubocop/cop/style/block_comments.rb +4 -2
  80. data/lib/rubocop/cop/style/block_delimiters.rb +69 -24
  81. data/lib/rubocop/cop/style/braces_around_hash_parameters.rb +40 -12
  82. data/lib/rubocop/cop/style/case_indentation.rb +18 -4
  83. data/lib/rubocop/cop/style/collection_methods.rb +2 -20
  84. data/lib/rubocop/cop/style/command_literal.rb +2 -10
  85. data/lib/rubocop/cop/style/comment_annotation.rb +29 -8
  86. data/lib/rubocop/cop/style/copyright.rb +5 -3
  87. data/lib/rubocop/cop/style/documentation.rb +21 -12
  88. data/lib/rubocop/cop/style/dot_position.rb +6 -0
  89. data/lib/rubocop/cop/style/double_negation.rb +4 -15
  90. data/lib/rubocop/cop/style/each_with_object.rb +17 -4
  91. data/lib/rubocop/cop/style/else_alignment.rb +2 -1
  92. data/lib/rubocop/cop/style/empty_else.rb +25 -0
  93. data/lib/rubocop/cop/style/empty_line_between_defs.rb +39 -14
  94. data/lib/rubocop/cop/style/encoding.rb +10 -4
  95. data/lib/rubocop/cop/style/extra_spacing.rb +126 -5
  96. data/lib/rubocop/cop/style/first_array_element_line_break.rb +41 -0
  97. data/lib/rubocop/cop/style/first_hash_element_line_break.rb +35 -0
  98. data/lib/rubocop/cop/style/first_method_argument_line_break.rb +37 -0
  99. data/lib/rubocop/cop/style/first_method_parameter_line_break.rb +42 -0
  100. data/lib/rubocop/cop/style/first_parameter_indentation.rb +5 -3
  101. data/lib/rubocop/cop/style/for.rb +2 -1
  102. data/lib/rubocop/cop/style/hash_syntax.rb +5 -0
  103. data/lib/rubocop/cop/style/if_unless_modifier.rb +32 -5
  104. data/lib/rubocop/cop/style/indent_hash.rb +67 -37
  105. data/lib/rubocop/cop/style/indentation_width.rb +36 -10
  106. data/lib/rubocop/cop/style/initial_indentation.rb +37 -0
  107. data/lib/rubocop/cop/style/leading_comment_space.rb +3 -2
  108. data/lib/rubocop/cop/style/method_call_parentheses.rb +28 -1
  109. data/lib/rubocop/cop/style/method_def_parentheses.rb +10 -7
  110. data/lib/rubocop/cop/style/multiline_operation_indentation.rb +21 -24
  111. data/lib/rubocop/cop/style/mutable_constant.rb +35 -0
  112. data/lib/rubocop/cop/style/nested_modifier.rb +97 -0
  113. data/lib/rubocop/cop/style/next.rb +50 -15
  114. data/lib/rubocop/cop/style/non_nil_check.rb +12 -8
  115. data/lib/rubocop/cop/style/one_line_conditional.rb +8 -4
  116. data/lib/rubocop/cop/style/option_hash.rb +64 -0
  117. data/lib/rubocop/cop/style/optional_arguments.rb +49 -0
  118. data/lib/rubocop/cop/style/parallel_assignment.rb +218 -0
  119. data/lib/rubocop/cop/style/percent_literal_delimiters.rb +3 -66
  120. data/lib/rubocop/cop/style/predicate_name.rb +7 -2
  121. data/lib/rubocop/cop/style/redundant_begin.rb +2 -13
  122. data/lib/rubocop/cop/style/redundant_freeze.rb +37 -0
  123. data/lib/rubocop/cop/style/redundant_return.rb +32 -3
  124. data/lib/rubocop/cop/style/regexp_literal.rb +2 -10
  125. data/lib/rubocop/cop/style/rescue_ensure_alignment.rb +81 -0
  126. data/lib/rubocop/cop/style/rescue_modifier.rb +30 -22
  127. data/lib/rubocop/cop/style/send.rb +18 -0
  128. data/lib/rubocop/cop/style/signal_exception.rb +24 -11
  129. data/lib/rubocop/cop/style/single_line_methods.rb +8 -9
  130. data/lib/rubocop/cop/style/single_space_before_first_arg.rb +1 -1
  131. data/lib/rubocop/cop/style/space_around_operators.rb +2 -0
  132. data/lib/rubocop/cop/style/space_inside_string_interpolation.rb +61 -0
  133. data/lib/rubocop/cop/style/special_global_vars.rb +4 -2
  134. data/lib/rubocop/cop/style/stabby_lambda_parentheses.rb +108 -0
  135. data/lib/rubocop/cop/style/string_methods.rb +32 -0
  136. data/lib/rubocop/cop/style/struct_inheritance.rb +11 -10
  137. data/lib/rubocop/cop/style/symbol_literal.rb +1 -1
  138. data/lib/rubocop/cop/style/symbol_proc.rb +62 -13
  139. data/lib/rubocop/cop/style/trailing_blank_lines.rb +9 -1
  140. data/lib/rubocop/cop/style/trailing_comma.rb +17 -7
  141. data/lib/rubocop/cop/style/trailing_underscore_variable.rb +23 -2
  142. data/lib/rubocop/cop/style/trivial_accessors.rb +10 -1
  143. data/lib/rubocop/cop/style/unneeded_percent_q.rb +31 -20
  144. data/lib/rubocop/cop/style/variable_name.rb +5 -0
  145. data/lib/rubocop/cop/style/while_until_do.rb +1 -1
  146. data/lib/rubocop/cop/style/word_array.rb +15 -2
  147. data/lib/rubocop/cop/team.rb +25 -5
  148. data/lib/rubocop/cop/util.rb +7 -2
  149. data/lib/rubocop/cop/variable_force/locatable.rb +6 -6
  150. data/lib/rubocop/cop/variable_force.rb +10 -10
  151. data/lib/rubocop/formatter/base_formatter.rb +1 -1
  152. data/lib/rubocop/formatter/disabled_config_formatter.rb +70 -8
  153. data/lib/rubocop/formatter/formatter_set.rb +27 -1
  154. data/lib/rubocop/formatter/progress_formatter.rb +10 -2
  155. data/lib/rubocop/formatter/simple_text_formatter.rb +1 -1
  156. data/lib/rubocop/node_pattern.rb +390 -0
  157. data/lib/rubocop/options.rb +148 -81
  158. data/lib/rubocop/processed_source.rb +7 -2
  159. data/lib/rubocop/rake_task.rb +1 -1
  160. data/lib/rubocop/remote_config.rb +60 -0
  161. data/lib/rubocop/result_cache.rb +123 -0
  162. data/lib/rubocop/runner.rb +85 -22
  163. data/lib/rubocop/target_finder.rb +4 -4
  164. data/lib/rubocop/token.rb +2 -1
  165. data/lib/rubocop/version.rb +1 -1
  166. data/lib/rubocop/warning.rb +11 -0
  167. data/lib/rubocop.rb +32 -3
  168. data/relnotes/v0.32.0.md +139 -0
  169. data/relnotes/v0.32.1.md +122 -0
  170. data/relnotes/v0.33.0.md +157 -0
  171. data/relnotes/v0.34.0.md +182 -0
  172. data/relnotes/v0.34.1.md +129 -0
  173. data/relnotes/v0.34.2.md +139 -0
  174. data/relnotes/v0.35.0.md +210 -0
  175. data/rubocop.gemspec +4 -4
  176. metadata +50 -12
  177. data/lib/rubocop/cop/performance/parallel_assignment.rb +0 -79
data/config/disabled.yml CHANGED
@@ -22,6 +22,30 @@ Style/InlineComment:
22
22
  Description: 'Avoid inline comments.'
23
23
  Enabled: false
24
24
 
25
+ Style/FirstArrayElementLineBreak:
26
+ Description: >-
27
+ Checks for a line break before the first element in a
28
+ multi-line array.
29
+ Enabled: false
30
+
31
+ Style/FirstHashElementLineBreak:
32
+ Description: >-
33
+ Checks for a line break before the first element in a
34
+ multi-line hash.
35
+ Enabled: false
36
+
37
+ Style/FirstMethodArgumentLineBreak:
38
+ Description: >-
39
+ Checks for a line break before the first argument in a
40
+ multi-line method call.
41
+ Enabled: false
42
+
43
+ Style/FirstMethodParameterLineBreak:
44
+ Description: >-
45
+ Checks for a line break before the first parameter in a
46
+ multi-line method parameter definition.
47
+ Enabled: false
48
+
25
49
  Style/MethodCalledOnDoEndBlock:
26
50
  Description: 'Avoid chaining a method call on a do...end block.'
27
51
  StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#single-line-blocks'
@@ -38,17 +62,34 @@ Style/MissingElse:
38
62
  EnforcedStyle: both
39
63
  SupportedStyles:
40
64
  # if - warn when an if expression is missing an else branch
41
- # case - warn when a case expression is misisng an else branch
65
+ # case - warn when a case expression is missing an else branch
42
66
  # both - warn when an if or case expression is missing an else branch
43
67
  - if
44
68
  - case
45
69
  - both
46
70
 
71
+ Style/MutableConstant:
72
+ Description: 'Do not assign mutable objects to constants.'
73
+ Enabled: false
74
+
75
+ Style/OptionHash:
76
+ Description: "Don't use option hashes when you can use keyword arguments."
77
+ Enabled: false
78
+
79
+ Style/Send:
80
+ Description: 'Prefer `Object#__send__` or `Object#public_send` to `send`, as `send` may overlap with existing methods.'
81
+ StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#prefer-public-send'
82
+ Enabled: false
83
+
84
+ Style/StringMethods:
85
+ Description: 'Checks if configured preferred methods are used over non-preferred.'
86
+ Enabled: false
87
+
47
88
  Style/SymbolArray:
48
89
  Description: 'Use %i or %I for arrays of symbols.'
49
90
  StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#percent-i'
50
91
  Enabled: false
51
92
 
52
- Style/ExtraSpacing:
53
- Description: 'Do not use unnecessary spacing.'
54
- Enabled: false
93
+ Lint/LiteralInInterpolation:
94
+ Description: 'Avoid interpolating literals in strings'
95
+ AutoCorrect: false
data/config/enabled.yml CHANGED
@@ -120,7 +120,7 @@ Style/ClassCheck:
120
120
 
121
121
  Style/ClassMethods:
122
122
  Description: 'Use self when defining module/class methods.'
123
- StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#def-self-singletons'
123
+ StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#def-self-class-methods'
124
124
  Enabled: true
125
125
 
126
126
  Style/ClassVars:
@@ -171,6 +171,9 @@ Style/DeprecatedHashMethods:
171
171
  Style/Documentation:
172
172
  Description: 'Document classes and non-namespace modules.'
173
173
  Enabled: true
174
+ Exclude:
175
+ - 'spec/**/*'
176
+ - 'test/**/*'
174
177
 
175
178
  Style/DotPosition:
176
179
  Description: 'Checks the position of the dot in multi-line method calls.'
@@ -243,11 +246,20 @@ Style/EvenOdd:
243
246
  StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#predicate-methods'
244
247
  Enabled: true
245
248
 
249
+ Style/ExtraSpacing:
250
+ Description: 'Do not use unnecessary spacing.'
251
+ Enabled: true
252
+
246
253
  Style/FileName:
247
254
  Description: 'Use snake_case for source file names.'
248
255
  StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#snake-case-files'
249
256
  Enabled: true
250
257
 
258
+ Style/InitialIndentation:
259
+ Description: >-
260
+ Checks the indentation of the first non-blank non-comment line in a file.
261
+ Enabled: true
262
+
251
263
  Style/FirstParameterIndentation:
252
264
  Description: 'Checks the indentation of the first parameter in a method call.'
253
265
  Enabled: true
@@ -270,6 +282,7 @@ Style/FormatString:
270
282
  Style/GlobalVars:
271
283
  Description: 'Do not introduce global variables.'
272
284
  StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#instance-vars'
285
+ Reference: 'http://www.zenspider.com/Languages/Ruby/QuickRef.html'
273
286
  Enabled: true
274
287
 
275
288
  Style/GuardClause:
@@ -402,6 +415,10 @@ Style/NegatedWhile:
402
415
  StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#until-for-negatives'
403
416
  Enabled: true
404
417
 
418
+ Style/NestedModifier:
419
+ Description: 'Avoid using nested modifiers.'
420
+ Enabled: true
421
+
405
422
  Style/NestedTernaryOperator:
406
423
  Description: 'Use one expression per branch in a ternary operator.'
407
424
  StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-nested-ternary'
@@ -446,6 +463,21 @@ Style/OpMethod:
446
463
  StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#other-arg'
447
464
  Enabled: true
448
465
 
466
+ Style/OptionalArguments:
467
+ Description: >-
468
+ Checks for optional arguments that do not appear at the end
469
+ of the argument list
470
+ StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#optional-arguments'
471
+ Enabled: true
472
+
473
+ Style/ParallelAssignment:
474
+ Description: >-
475
+ Check for simple usages of parallel assignment.
476
+ It will only warn when the number of variables
477
+ matches on both sides of the assignment.
478
+ StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#parallel-assignment'
479
+ Enabled: true
480
+
449
481
  Style/ParenthesesAroundCondition:
450
482
  Description: >-
451
483
  Don't use parentheses around the condition of an
@@ -492,6 +524,10 @@ Style/RedundantException:
492
524
  StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-explicit-runtimeerror'
493
525
  Enabled: true
494
526
 
527
+ Style/RedundantFreeze:
528
+ Description: "Checks usages of Object#freeze on immutable objects."
529
+ Enabled: true
530
+
495
531
  Style/RedundantReturn:
496
532
  Description: "Don't use return where it's not required."
497
533
  StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-explicit-return'
@@ -507,6 +543,10 @@ Style/RegexpLiteral:
507
543
  StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#percent-r'
508
544
  Enabled: true
509
545
 
546
+ Style/RescueEnsureAlignment:
547
+ Description: 'Align rescues and ensures correctly.'
548
+ Enabled: true
549
+
510
550
  Style/RescueModifier:
511
551
  Description: 'Avoid using rescue in its modifier form.'
512
552
  StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-rescue-modifiers'
@@ -644,11 +684,21 @@ Style/SpaceInsideRangeLiteral:
644
684
  StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-space-inside-range-literals'
645
685
  Enabled: true
646
686
 
687
+ Style/SpaceInsideStringInterpolation:
688
+ Description: 'Checks for padding/surrounding spaces inside string interpolation.'
689
+ StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#string-interpolation'
690
+ Enabled: true
691
+
647
692
  Style/SpecialGlobalVars:
648
693
  Description: 'Avoid Perl-style global variables.'
649
694
  StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-cryptic-perlisms'
650
695
  Enabled: true
651
696
 
697
+ Style/StabbyLambdaParentheses:
698
+ Description: 'Check for the usage of parentheses around stabby lambda arguments.'
699
+ StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#stabby-lambda-with-args'
700
+ Enabled: true
701
+
652
702
  Style/StringLiterals:
653
703
  Description: 'Checks if uses of quotes match the configured preference.'
654
704
  StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#consistent-string-literals'
@@ -718,6 +768,7 @@ Style/TrailingUnderscoreVariable:
718
768
  Description: >-
719
769
  Checks for the usage of unneeded trailing underscores at the
720
770
  end of parallel variable assignment.
771
+ AllowNamedUnderscoreVariables: true
721
772
  Enabled: true
722
773
 
723
774
  Style/VariableInterpolation:
@@ -760,6 +811,7 @@ Metrics/AbcSize:
760
811
  Description: >-
761
812
  A calculated magnitude based on number of assignments,
762
813
  branches, and conditions.
814
+ Reference: 'http://c2.com/cgi/wiki?AbcMetric'
763
815
  Enabled: true
764
816
 
765
817
  Metrics/BlockNesting:
@@ -815,7 +867,7 @@ Lint/AmbiguousOperator:
815
867
  Lint/AmbiguousRegexpLiteral:
816
868
  Description: >-
817
869
  Checks for ambiguous regexp literals in the first argument of
818
- a method invocation without parenthesis.
870
+ a method invocation without parentheses.
819
871
  Enabled: true
820
872
 
821
873
  Lint/AssignmentInCondition:
@@ -827,6 +879,10 @@ Lint/BlockAlignment:
827
879
  Description: 'Align block ends correctly.'
828
880
  Enabled: true
829
881
 
882
+ Lint/CircularArgumentReference:
883
+ Description: "Default values in optional keyword arguments and optional ordinal arguments should not refer back to the name of the argument."
884
+ Enabled: true
885
+
830
886
  Lint/ConditionPosition:
831
887
  Description: >-
832
888
  Checks for condition placed in a confusing position relative to
@@ -850,6 +906,10 @@ Lint/DuplicateMethods:
850
906
  Description: 'Check for duplicate methods calls.'
851
907
  Enabled: true
852
908
 
909
+ Lint/DuplicatedKey:
910
+ Description: 'Check for duplicate keys in hash literals.'
911
+ Enabled: true
912
+
853
913
  Lint/EachWithObjectArgument:
854
914
  Description: 'Check for immutable argument given to each_with_object.'
855
915
  Enabled: true
@@ -883,6 +943,10 @@ Lint/Eval:
883
943
  Description: 'The use of eval represents a serious security risk.'
884
944
  Enabled: true
885
945
 
946
+ Lint/FormatParameterMismatch:
947
+ Description: 'The number of parameters to format/sprint must match the fields.'
948
+ Enabled: true
949
+
886
950
  Lint/HandleExceptions:
887
951
  Description: "Don't suppress exception."
888
952
  StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#dont-hide-exceptions'
@@ -909,6 +973,11 @@ Lint/Loop:
909
973
  StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#loop-with-break'
910
974
  Enabled: true
911
975
 
976
+ Lint/NestedMethodDefinition:
977
+ Description: 'Do not use nested method definitions.'
978
+ StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-nested-methods'
979
+ Enabled: true
980
+
912
981
  Lint/NonLocalExitFromIterator:
913
982
  Description: 'Do not use return in iterator to cause non-local exit.'
914
983
  Enabled: true
@@ -952,6 +1021,13 @@ Lint/UnderscorePrefixedVariableName:
952
1021
  Description: 'Do not use prefix `_` for a variable that is used.'
953
1022
  Enabled: true
954
1023
 
1024
+ Lint/UnneededDisable:
1025
+ Description: >-
1026
+ Checks for rubocop:disable comments that can be removed.
1027
+ Note: this cop is not disabled when disabling all cops.
1028
+ It must be explicitly disabled.
1029
+ Enabled: true
1030
+
955
1031
  Lint/UnusedBlockArgument:
956
1032
  Description: 'Checks for unused block arguments.'
957
1033
  StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#underscore-unused-vars'
@@ -993,6 +1069,12 @@ Lint/Void:
993
1069
 
994
1070
  ##################### Performance #############################
995
1071
 
1072
+ Performance/CaseWhenSplat:
1073
+ Description: >-
1074
+ Place `when` conditions that use splat at the end
1075
+ of the list of `when` branches.
1076
+ Enabled: true
1077
+
996
1078
  Performance/Count:
997
1079
  Description: >-
998
1080
  Use `count` instead of `select...size`, `reject...size`,
@@ -1004,6 +1086,11 @@ Performance/Detect:
1004
1086
  Description: >-
1005
1087
  Use `detect` instead of `select.first`, `find_all.first`,
1006
1088
  `select.last`, and `find_all.last`.
1089
+ Reference: 'https://github.com/JuanitoFatas/fast-ruby#enumerabledetect-vs-enumerableselectfirst-code'
1090
+ Enabled: true
1091
+
1092
+ Performance/FixedSize:
1093
+ Description: 'Do not compute the size of statically sized objects except in constants'
1007
1094
  Enabled: true
1008
1095
 
1009
1096
  Performance/FlatMap:
@@ -1011,6 +1098,7 @@ Performance/FlatMap:
1011
1098
  Use `Enumerable#flat_map`
1012
1099
  instead of `Enumerable#map...Array#flatten(1)`
1013
1100
  or `Enumberable#collect..Array#flatten(1)`
1101
+ Reference: 'https://github.com/JuanitoFatas/fast-ruby#enumerablemaparrayflatten-vs-enumerableflat_map-code'
1014
1102
  Enabled: true
1015
1103
  EnabledForFlattenWithoutParams: false
1016
1104
  # If enabled, this cop will warn about usages of
@@ -1018,27 +1106,31 @@ Performance/FlatMap:
1018
1106
  # This can be dangerous since `flat_map` will only flatten 1 level, and
1019
1107
  # `flatten` without any parameters can flatten multiple levels.
1020
1108
 
1021
- Performance/ParallelAssignment:
1022
- Description: >-
1023
- Check for simple usages of parallel assignment.
1024
- It will only warn when the number of variables
1025
- matches on both sides of the assignment.
1026
- Enabled: true
1027
-
1028
1109
  Performance/ReverseEach:
1029
1110
  Description: 'Use `reverse_each` instead of `reverse.each`.'
1111
+ Reference: 'https://github.com/JuanitoFatas/fast-ruby#enumerablereverseeach-vs-enumerablereverse_each-code'
1030
1112
  Enabled: true
1031
1113
 
1032
1114
  Performance/Sample:
1033
1115
  Description: >-
1034
1116
  Use `sample` instead of `shuffle.first`,
1035
1117
  `shuffle.last`, and `shuffle[Fixnum]`.
1118
+ Reference: 'https://github.com/JuanitoFatas/fast-ruby#arrayshufflefirst-vs-arraysample-code'
1036
1119
  Enabled: true
1037
1120
 
1038
1121
  Performance/Size:
1039
1122
  Description: >-
1040
1123
  Use `size` instead of `count` for counting
1041
1124
  the number of elements in `Array` and `Hash`.
1125
+ Reference: 'https://github.com/JuanitoFatas/fast-ruby#arraycount-vs-arraysize-code'
1126
+ Enabled: true
1127
+
1128
+ Performance/StringReplacement:
1129
+ Description: >-
1130
+ Use `tr` instead of `gsub` when you are replacing the same
1131
+ number of characters. Use `delete` instead of `gsub` when
1132
+ you are deleting characters.
1133
+ Reference: 'https://github.com/JuanitoFatas/fast-ruby#stringgsub-vs-stringtr-code'
1042
1134
  Enabled: true
1043
1135
 
1044
1136
  ##################### Rails ##################################
@@ -1077,6 +1169,10 @@ Rails/Output:
1077
1169
  Description: 'Checks for calls to puts, print, etc.'
1078
1170
  Enabled: true
1079
1171
 
1172
+ Rails/PluralizationGrammar:
1173
+ Description: 'Checks for incorrect grammar when using methods like `3.day.ago`.'
1174
+ Enabled: true
1175
+
1080
1176
  Rails/ReadWriteAttribute:
1081
1177
  Description: >-
1082
1178
  Checks for read_attribute(:attr) and
@@ -1089,6 +1185,8 @@ Rails/ScopeArgs:
1089
1185
 
1090
1186
  Rails/TimeZone:
1091
1187
  Description: 'Checks the correct usage of time zone aware methods.'
1188
+ StyleGuide: 'https://github.com/bbatsov/rails-style-guide#time'
1189
+ Reference: 'http://danilenko.org/2012/7/6/rails_timezones'
1092
1190
  Enabled: true
1093
1191
 
1094
1192
  Rails/Validation:
@@ -0,0 +1,48 @@
1
+ # encoding: utf-8
2
+
3
+ require 'astrolabe/node'
4
+
5
+ module Astrolabe
6
+ # RuboCop's extensions to Astrolabe::Node (which extends Parser::AST::Node)
7
+ #
8
+ # Contribute as much of this as possible to the `astrolabe` gem
9
+ # If any of it is accepted, it can be deleted from here
10
+ #
11
+ class Node
12
+ # def_matcher can be used to define a pattern-matching method on Node:
13
+ class << self
14
+ extend RuboCop::NodePattern::Macros
15
+
16
+ # define both Node.method_name(node), and also node.method_name
17
+ def def_matcher(method_name, pattern_str)
18
+ singleton_class.def_node_matcher method_name, pattern_str
19
+ class_eval("def #{method_name}; Node.#{method_name}(self); end")
20
+ end
21
+ end
22
+
23
+ ## Destructuring
24
+
25
+ def_matcher :method_name, '{(send _ $_ ...) (block (send _ $_ ...) ...)}'
26
+ # Note: for masgn, #asgn_rhs will be an array node
27
+ def_matcher :asgn_rhs, '[assignment? (... $_)]'
28
+
29
+ ## Predicates
30
+
31
+ def multiline?
32
+ expr = loc.expression
33
+ expr && (expr.first_line != expr.last_line)
34
+ end
35
+
36
+ def single_line?
37
+ !multiline?
38
+ end
39
+
40
+ def asgn_method_call?
41
+ method_name != :== && method_name.to_s.end_with?('=')
42
+ end
43
+
44
+ def_matcher :equals_asgn?, '{lvasgn ivasgn cvasgn gvasgn casgn masgn}'
45
+ def_matcher :shorthand_asgn?, '{op_asgn or_asgn and_asgn}'
46
+ def_matcher :assignment?, '{equals_asgn? shorthand_asgn? asgn_method_call?}'
47
+ end
48
+ end
data/lib/rubocop/cli.rb CHANGED
@@ -24,6 +24,7 @@ module RuboCop
24
24
  runner = Runner.new(@options, @config_store)
25
25
  trap_interrupt(runner)
26
26
  all_passed = runner.run(paths)
27
+ display_warning_summary(runner.warnings)
27
28
  display_error_summary(runner.errors)
28
29
 
29
30
  all_passed && !runner.aborting? && runner.errors.empty? ? 0 : 1
@@ -53,6 +54,7 @@ module RuboCop
53
54
 
54
55
  ConfigLoader.debug = @options[:debug]
55
56
  ConfigLoader.auto_gen_config = @options[:auto_gen_config]
57
+ ConfigLoader.exclude_limit = @options[:exclude_limit]
56
58
 
57
59
  @config_store.options_config = @options[:config] if @options[:config]
58
60
 
@@ -99,10 +101,18 @@ module RuboCop
99
101
  end
100
102
  end
101
103
 
104
+ def display_warning_summary(warnings)
105
+ return if warnings.empty?
106
+
107
+ warn Rainbow("\n#{pluralize(warnings.size, 'warning')}:").yellow
108
+
109
+ warnings.each { |warning| warn warning }
110
+ end
111
+
102
112
  def display_error_summary(errors)
103
113
  return if errors.empty?
104
114
 
105
- warn "\n#{pluralize(errors.size, 'error')} occurred:".color(:red)
115
+ warn Rainbow("\n#{pluralize(errors.size, 'error')} occurred:").red
106
116
 
107
117
  errors.each { |error| warn error }
108
118
 
@@ -4,6 +4,7 @@ module RuboCop
4
4
  # This class parses the special `rubocop:disable` comments in a source
5
5
  # and provides a way to check if each cop is enabled at arbitrary line.
6
6
  class CommentConfig
7
+ UNNEEDED_DISABLE = 'Lint/UnneededDisable'
7
8
  COMMENT_DIRECTIVE_REGEXP = Regexp.new(
8
9
  '\A# rubocop : ((?:dis|en)able)\b ((?:[\w/]+,? )+)'.gsub(' ', '\s*')
9
10
  )
@@ -73,7 +74,9 @@ module RuboCop
73
74
  end
74
75
 
75
76
  def all_cop_names
76
- @all_cop_names ||= Cop::Cop.all.map(&:cop_name)
77
+ @all_cop_names ||= Cop::Cop.all.map(&:cop_name).reject do |cop_name|
78
+ cop_name == UNNEEDED_DISABLE
79
+ end
77
80
  end
78
81
 
79
82
  def comment_only_line?(line_number)
@@ -14,15 +14,22 @@ module RuboCop
14
14
 
15
15
  class ValidationError < StandardError; end
16
16
 
17
- COMMON_PARAMS = %w(Exclude Include Severity AutoCorrect)
17
+ COMMON_PARAMS = %w(Exclude Include Severity AutoCorrect StyleGuide Details)
18
18
 
19
19
  attr_reader :loaded_path
20
20
 
21
21
  def initialize(hash = {}, loaded_path = nil)
22
22
  @loaded_path = loaded_path
23
+ @for_cop = Hash.new do |h, cop|
24
+ h[cop] = self[Cop::Cop.qualified_cop_name(cop, loaded_path)] || {}
25
+ end
23
26
  super(hash)
24
27
  end
25
28
 
29
+ def to_s
30
+ @to_s ||= __getobj__.to_s
31
+ end
32
+
26
33
  def make_excludes_absolute
27
34
  keys.each do |key|
28
35
  validate_section_presence(key)
@@ -68,19 +75,17 @@ module RuboCop
68
75
  end
69
76
 
70
77
  def for_cop(cop)
71
- cop = cop.cop_name if cop.respond_to?(:cop_name)
72
- @for_cop ||= {}
73
- @for_cop[cop] ||= self[Cop::Cop.qualified_cop_name(cop, loaded_path)]
78
+ @for_cop[cop.respond_to?(:cop_name) ? cop.cop_name : cop]
74
79
  end
75
80
 
76
81
  def cop_enabled?(cop)
77
- for_cop(cop).nil? || for_cop(cop)['Enabled']
82
+ for_cop(cop).empty? || for_cop(cop)['Enabled']
78
83
  end
79
84
 
80
85
  def warn_unless_valid
81
86
  validate
82
87
  rescue Config::ValidationError => e
83
- warn "Warning: #{e.message}".color(:red)
88
+ warn Rainbow.new.wrap("Warning: #{e.message}").red
84
89
  end
85
90
 
86
91
  def add_missing_namespaces
@@ -147,27 +152,31 @@ module RuboCop
147
152
  end
148
153
 
149
154
  def patterns_to_include
150
- self['AllCops']['Include']
155
+ @patterns_to_include ||= self['AllCops']['Include']
151
156
  end
152
157
 
153
158
  def patterns_to_exclude
154
- self['AllCops']['Exclude']
159
+ @patterns_to_exclude ||= self['AllCops']['Exclude']
155
160
  end
156
161
 
157
162
  def path_relative_to_config(path)
158
163
  relative_path(path, base_dir_for_path_parameters)
159
164
  end
160
165
 
161
- # Paths specified in .rubocop.yml files are relative to the directory where
162
- # that file is. Paths in other config files are relative to the current
163
- # directory. This is so that paths in config/default.yml, for example, are
164
- # not relative to RuboCop's config directory since that wouldn't work.
166
+ # Paths specified in .rubocop.yml and .rubocop_todo.yml files are relative
167
+ # to the directory where that file is. Paths in other config files are
168
+ # relative to the current directory. This is so that paths in
169
+ # config/default.yml, for example, are not relative to RuboCop's config
170
+ # directory since that wouldn't work.
165
171
  def base_dir_for_path_parameters
166
- if File.basename(loaded_path) == ConfigLoader::DOTFILE
167
- File.expand_path(File.dirname(loaded_path))
168
- else
169
- Dir.pwd
170
- end
172
+ config_files = [ConfigLoader::DOTFILE, ConfigLoader::AUTO_GENERATED_FILE]
173
+ @base_dir_for_path_parameters ||=
174
+ if config_files.include?(File.basename(loaded_path)) &&
175
+ loaded_path != File.join(Dir.home, ConfigLoader::DOTFILE)
176
+ File.expand_path(File.dirname(loaded_path))
177
+ else
178
+ Dir.pwd
179
+ end
171
180
  end
172
181
 
173
182
  private
@@ -16,8 +16,9 @@ module RuboCop
16
16
  AUTO_GENERATED_FILE = '.rubocop_todo.yml'
17
17
 
18
18
  class << self
19
- attr_accessor :debug, :auto_gen_config
19
+ attr_accessor :debug, :auto_gen_config, :exclude_limit
20
20
  attr_writer :root_level # The upwards search is stopped at this level.
21
+ attr_writer :default_configuration
21
22
 
22
23
  alias_method :debug?, :debug
23
24
  alias_method :auto_gen_config?, :auto_gen_config
@@ -26,6 +27,7 @@ module RuboCop
26
27
  path = File.absolute_path(path)
27
28
  hash = load_yaml_configuration(path)
28
29
 
30
+ resolve_inheritance_from_gems(hash, hash.delete('inherit_gem'))
29
31
  resolve_inheritance(path, hash)
30
32
 
31
33
  Array(hash.delete('require')).each { |r| require(r) }
@@ -57,16 +59,21 @@ module RuboCop
57
59
  end
58
60
 
59
61
  def base_configs(path, inherit_from)
60
- configs = Array(inherit_from).map do |f|
61
- f = File.expand_path(f, File.dirname(path))
62
-
63
- if auto_gen_config?
64
- next if f.include?(AUTO_GENERATED_FILE)
65
- old_auto_config_file_warning if f.include?('rubocop-todo.yml')
62
+ configs = Array(inherit_from).compact.map do |f|
63
+ if f =~ URI.regexp
64
+ f = RemoteConfig.new(f).file
65
+ load_file(f)
66
+ else
67
+ f = File.expand_path(f, File.dirname(path))
68
+
69
+ if auto_gen_config?
70
+ next if f.include?(AUTO_GENERATED_FILE)
71
+ old_auto_config_file_warning if f.include?('rubocop-todo.yml')
72
+ end
73
+
74
+ print 'Inheriting ' if debug?
75
+ load_file(f)
66
76
  end
67
-
68
- print 'Inheriting ' if debug?
69
- load_file(f)
70
77
  end
71
78
 
72
79
  configs.compact
@@ -100,12 +107,33 @@ module RuboCop
100
107
  end
101
108
  end
102
109
 
110
+ # Merges the given configuration with the default one. If
111
+ # AllCops:DisabledByDefault is true, it changes the Enabled params so
112
+ # that only cops from user configuration are enabled.
103
113
  def merge_with_default(config, config_file)
104
- Config.new(merge(default_configuration, config), config_file)
114
+ configs =
115
+ if config.key?('AllCops') && config['AllCops']['DisabledByDefault']
116
+ disabled_default = transform(default_configuration) do |params|
117
+ params.merge('Enabled' => false) # Overwrite with false.
118
+ end
119
+ enabled_user_config = transform(config) do |params|
120
+ { 'Enabled' => true }.merge(params) # Set true if not set.
121
+ end
122
+ [disabled_default, enabled_user_config]
123
+ else
124
+ [default_configuration, config]
125
+ end
126
+ Config.new(merge(configs.first, configs.last), config_file)
105
127
  end
106
128
 
107
129
  private
108
130
 
131
+ # Returns a new hash where the parameters of the given config hash have
132
+ # been replaced by parmeters returned by the given block.
133
+ def transform(config)
134
+ Hash[config.map { |cop, params| [cop, yield(params)] }]
135
+ end
136
+
109
137
  def load_yaml_configuration(absolute_path)
110
138
  yaml_code = IO.read(absolute_path)
111
139
  # At one time, there was a problem with the psych YAML engine under
@@ -126,7 +154,11 @@ module RuboCop
126
154
 
127
155
  def yaml_safe_load(yaml_code)
128
156
  if YAML.respond_to?(:safe_load) # Ruby 2.1+
129
- YAML.safe_load(yaml_code, [Regexp])
157
+ if defined?(SafeYAML)
158
+ SafeYAML.load(yaml_code, nil, whitelisted_tags: %w(!ruby/regexp))
159
+ else
160
+ YAML.safe_load(yaml_code, [Regexp])
161
+ end
130
162
  else
131
163
  YAML.load(yaml_code)
132
164
  end
@@ -140,6 +172,21 @@ module RuboCop
140
172
  end
141
173
  end
142
174
 
175
+ def resolve_inheritance_from_gems(hash, gems)
176
+ (gems || {}).each_pair do |gem_name, config_path|
177
+ hash['inherit_from'] = Array(hash['inherit_from'])
178
+ hash['inherit_from'] << gem_config_path(gem_name, config_path)
179
+ end
180
+ end
181
+
182
+ def gem_config_path(gem_name, relative_config_path)
183
+ spec = Gem::Specification.find_by_name(gem_name)
184
+ return File.join(spec.gem_dir, relative_config_path)
185
+ rescue Gem::LoadError => e
186
+ raise Gem::LoadError,
187
+ "Unable to find gem #{gem_name}; is the gem installed? #{e}"
188
+ end
189
+
143
190
  def config_files_in_path(target)
144
191
  possible_config_files = dirs_to_search(target).map do |dir|
145
192
  File.join(dir, DOTFILE)
@@ -157,8 +204,8 @@ module RuboCop
157
204
  end
158
205
 
159
206
  def old_auto_config_file_warning
160
- warn 'Attention: rubocop-todo.yml has been renamed to ' \
161
- "#{AUTO_GENERATED_FILE}".color(:red)
207
+ warn Rainbow('Attention: rubocop-todo.yml has been renamed to ' \
208
+ "#{AUTO_GENERATED_FILE}").red
162
209
  exit(1)
163
210
  end
164
211
  end