rubocop 0.45.0 → 0.46.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 (73) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/config/default.yml +17 -0
  4. data/config/enabled.yml +29 -2
  5. data/lib/rubocop.rb +6 -1
  6. data/lib/rubocop/config.rb +0 -10
  7. data/lib/rubocop/config_loader.rb +21 -9
  8. data/lib/rubocop/cop/bundler/duplicated_gem.rb +69 -0
  9. data/lib/rubocop/cop/bundler/ordered_gems.rb +54 -0
  10. data/lib/rubocop/cop/cop.rb +1 -0
  11. data/lib/rubocop/cop/lint/debugger.rb +9 -1
  12. data/lib/rubocop/cop/lint/each_with_object_argument.rb +5 -6
  13. data/lib/rubocop/cop/lint/eval.rb +3 -7
  14. data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +6 -4
  15. data/lib/rubocop/cop/lint/unneeded_splat_expansion.rb +13 -4
  16. data/lib/rubocop/cop/lint/useless_comparison.rb +5 -9
  17. data/lib/rubocop/cop/lint/useless_setter_call.rb +1 -0
  18. data/lib/rubocop/cop/metrics/line_length.rb +16 -3
  19. data/lib/rubocop/cop/mixin/access_modifier_node.rb +9 -9
  20. data/lib/rubocop/cop/mixin/configurable_numbering.rb +14 -7
  21. data/lib/rubocop/cop/mixin/empty_lines_around_body.rb +92 -20
  22. data/lib/rubocop/cop/performance/compare_with_block.rb +61 -0
  23. data/lib/rubocop/cop/performance/count.rb +21 -57
  24. data/lib/rubocop/cop/performance/detect.rb +15 -15
  25. data/lib/rubocop/cop/performance/flat_map.rb +23 -35
  26. data/lib/rubocop/cop/performance/sample.rb +84 -82
  27. data/lib/rubocop/cop/performance/string_replacement.rb +18 -43
  28. data/lib/rubocop/cop/rails/enum_uniqueness.rb +71 -0
  29. data/lib/rubocop/cop/rails/http_positional_arguments.rb +1 -1
  30. data/lib/rubocop/cop/rails/output.rb +8 -12
  31. data/lib/rubocop/cop/rails/read_write_attribute.rb +10 -6
  32. data/lib/rubocop/cop/rails/request_referer.rb +8 -9
  33. data/lib/rubocop/cop/rails/scope_args.rb +5 -11
  34. data/lib/rubocop/cop/style/access_modifier_indentation.rb +1 -1
  35. data/lib/rubocop/cop/style/and_or.rb +1 -1
  36. data/lib/rubocop/cop/style/array_join.rb +4 -8
  37. data/lib/rubocop/cop/style/block_comments.rb +1 -1
  38. data/lib/rubocop/cop/style/case_equality.rb +3 -3
  39. data/lib/rubocop/cop/style/character_literal.rb +2 -4
  40. data/lib/rubocop/cop/style/class_check.rb +6 -6
  41. data/lib/rubocop/cop/style/colon_method_call.rb +6 -6
  42. data/lib/rubocop/cop/style/each_with_object.rb +13 -17
  43. data/lib/rubocop/cop/style/empty_literal.rb +46 -36
  44. data/lib/rubocop/cop/style/empty_method.rb +96 -0
  45. data/lib/rubocop/cop/style/even_odd.rb +19 -50
  46. data/lib/rubocop/cop/style/hash_syntax.rb +4 -1
  47. data/lib/rubocop/cop/style/lambda.rb +8 -18
  48. data/lib/rubocop/cop/style/module_function.rb +14 -11
  49. data/lib/rubocop/cop/style/nil_comparison.rb +4 -7
  50. data/lib/rubocop/cop/style/non_nil_check.rb +18 -36
  51. data/lib/rubocop/cop/style/numeric_predicate.rb +9 -10
  52. data/lib/rubocop/cop/style/op_method.rb +7 -9
  53. data/lib/rubocop/cop/style/parallel_assignment.rb +1 -1
  54. data/lib/rubocop/cop/style/proc.rb +5 -9
  55. data/lib/rubocop/cop/style/redundant_freeze.rb +6 -7
  56. data/lib/rubocop/cop/style/send.rb +6 -3
  57. data/lib/rubocop/cop/style/space_inside_block_braces.rb +1 -1
  58. data/lib/rubocop/cop/style/special_global_vars.rb +3 -3
  59. data/lib/rubocop/cop/style/symbol_proc.rb +22 -43
  60. data/lib/rubocop/cop/style/ternary_parentheses.rb +67 -18
  61. data/lib/rubocop/cop/util.rb +1 -1
  62. data/lib/rubocop/cop/variable_force/assignment.rb +2 -0
  63. data/lib/rubocop/cop/variable_force/locatable.rb +8 -6
  64. data/lib/rubocop/cop/variable_force/reference.rb +2 -0
  65. data/lib/rubocop/formatter/base_formatter.rb +4 -8
  66. data/lib/rubocop/formatter/fuubar_style_formatter.rb +6 -0
  67. data/lib/rubocop/node_pattern.rb +7 -5
  68. data/lib/rubocop/processed_source.rb +1 -0
  69. data/lib/rubocop/rspec/cop_helper.rb +4 -0
  70. data/lib/rubocop/rspec/host_environment_simulation_helper.rb +1 -1
  71. data/lib/rubocop/version.rb +1 -1
  72. metadata +7 -3
  73. data/lib/rubocop/cop/performance/sort_with_block.rb +0 -53
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: efe4f5525d5939f0396d7851e61030c00fd001da
4
- data.tar.gz: 6c8a76124e3ac07618a2bbd69b7ca95619cb570b
3
+ metadata.gz: 4edd0a2f31f504ae1631e4ef7f1d7a7ef94f1529
4
+ data.tar.gz: 6b80801b3432a53bfc971750598d178e4f07712c
5
5
  SHA512:
6
- metadata.gz: b16cbb9b023e3d7757b0c7250951d83082924737fc3148ddc962efa3cfd1bcd1a1bb09881fbee457475e9325d0052a393e8d61abeeef1df6fb083761ad73a42e
7
- data.tar.gz: c35d29e51547461c170a5b9e68a8a0448f8608e238d922642c61b82dfc94d75ae22f2a771a47d9ed038ad9c530bf1e331907922bdc284bb82a634fb0461a56e4
6
+ metadata.gz: aa7daba04fc4aa617b6b9fa03ab4f83c8b27f6043b5fa4e969279da65826b51ab2f8b61ef2d8f32f900a3c729fa1e6be1bce98bd76ecc682e0e927d72607a2ea
7
+ data.tar.gz: 902ec50c6ecb24d4fd13bb2fbe4adca6639786f77e3b9bfb2a37e057909471f7da5807bcae73381b0471fe67276a681232a40cff02d85e080f7f3523112d0dfa
data/README.md CHANGED
@@ -51,7 +51,7 @@ haven't reached version 1.0 yet). To prevent an unwanted RuboCop update you
51
51
  might want to use a conservative version locking in your `Gemfile`:
52
52
 
53
53
  ```rb
54
- gem 'rubocop', '~> 0.45.0', require: false
54
+ gem 'rubocop', '~> 0.46.0', require: false
55
55
  ```
56
56
 
57
57
  ## Quickstart
@@ -436,6 +436,7 @@ Style/EmptyLinesAroundClassBody:
436
436
  SupportedStyles:
437
437
  - empty_lines
438
438
  - empty_lines_except_namespace
439
+ - empty_lines_special
439
440
  - no_empty_lines
440
441
 
441
442
  Style/EmptyLinesAroundModuleBody:
@@ -443,8 +444,15 @@ Style/EmptyLinesAroundModuleBody:
443
444
  SupportedStyles:
444
445
  - empty_lines
445
446
  - empty_lines_except_namespace
447
+ - empty_lines_special
446
448
  - no_empty_lines
447
449
 
450
+ Style/EmptyMethod:
451
+ EnforcedStyle: compact
452
+ SupportedStyles:
453
+ - compact
454
+ - expanded
455
+
448
456
  # Checks whether the source file has a utf-8 encoding comment or not
449
457
  # AutoCorrectEncodingComment must match the regex
450
458
  # /#.*coding\s?[:=]\s?(?:UTF|utf)-8/
@@ -998,6 +1006,7 @@ Style/TernaryParentheses:
998
1006
  SupportedStyles:
999
1007
  - require_parentheses
1000
1008
  - require_no_parentheses
1009
+ - require_parentheses_when_complex
1001
1010
  AllowSafeAssignment: true
1002
1011
 
1003
1012
  Style/TrailingBlankLines:
@@ -1135,6 +1144,10 @@ Metrics/LineLength:
1135
1144
  # The IgnoreCopDirectives option causes the LineLength rule to ignore cop
1136
1145
  # directives like '# rubocop: enable ...' when calculating a line's length.
1137
1146
  IgnoreCopDirectives: false
1147
+ # The IgnoredPatterns option is a list of !ruby/regexp and/or string
1148
+ # elements. Strings will be converted to Regexp objects. A line that matches
1149
+ # any regular expression listed in this option will be ignored by LineLength.
1150
+ IgnoredPatterns: []
1138
1151
 
1139
1152
  Metrics/MethodLength:
1140
1153
  CountComments: false # count full line comments?
@@ -1249,6 +1262,10 @@ Rails/DynamicFindBy:
1249
1262
  Whitelist:
1250
1263
  - find_by_sql
1251
1264
 
1265
+ Rails/EnumUniqueness:
1266
+ Include:
1267
+ - app/models/**/*.rb
1268
+
1252
1269
  Rails/Exit:
1253
1270
  Include:
1254
1271
  - app/**/*.rb
@@ -244,6 +244,11 @@ Style/EmptyLiteral:
244
244
  StyleGuide: '#literal-array-hash'
245
245
  Enabled: true
246
246
 
247
+ Style/EmptyMethod:
248
+ Description: 'Checks the formatting of empty method definitions.'
249
+ StyleGuide: '#no-single-line-methods'
250
+ Enabled: true
251
+
247
252
  Style/EndBlock:
248
253
  Description: 'Avoid the use of END blocks.'
249
254
  StyleGuide: '#no-END-blocks'
@@ -602,7 +607,7 @@ Style/ParenthesesAroundCondition:
602
607
  Description: >-
603
608
  Don't use parentheses around the condition of an
604
609
  if/unless/while.
605
- StyleGuide: '#no-parens-if'
610
+ StyleGuide: '#no-parens-around-condition'
606
611
  Enabled: true
607
612
 
608
613
  Style/PercentLiteralDelimiters:
@@ -1422,7 +1427,7 @@ Performance/Size:
1422
1427
  Reference: 'https://github.com/JuanitoFatas/fast-ruby#arraycount-vs-arraysize-code'
1423
1428
  Enabled: true
1424
1429
 
1425
- Performance/SortWithBlock:
1430
+ Performance/CompareWithBlock:
1426
1431
  Description: 'Use `sort_by(&:foo)` instead of `sort_by { |a, b| a.foo <=> b.foo }`.'
1427
1432
  Enabled: true
1428
1433
 
@@ -1472,6 +1477,10 @@ Rails/DynamicFindBy:
1472
1477
  StyleGuide: 'https://github.com/bbatsov/rails-style-guide#find_by'
1473
1478
  Enabled: true
1474
1479
 
1480
+ Rails/EnumUniqueness:
1481
+ Description: 'Avoid duplicate integers in hash-syntax `enum` declaration.'
1482
+ Enabled: true
1483
+
1475
1484
  Rails/Exit:
1476
1485
  Description: >-
1477
1486
  Favor `fail`, `break`, `return`, etc. over `exit` in
@@ -1559,3 +1568,21 @@ Security/JSONLoad:
1559
1568
  # Autocorrect here will change to a method that may cause crashes depending
1560
1569
  # on the value of the argument.
1561
1570
  AutoCorrect: false
1571
+
1572
+ ##################### Bundler #############################
1573
+
1574
+ Bundler/DuplicatedGem:
1575
+ Description: 'Checks for duplicate gem entries in Gemfile.'
1576
+ Enabled: true
1577
+ Include:
1578
+ - '**/Gemfile'
1579
+ - '**/gems.rb'
1580
+
1581
+ Bundler/OrderedGems:
1582
+ Description: >-
1583
+ Sort alphabetically gems appearing within a contiguous set
1584
+ of lines in the Gemfile
1585
+ Enabled: true
1586
+ Include:
1587
+ - '**/Gemfile'
1588
+ - '**/gems.rb'
@@ -91,6 +91,9 @@ require 'rubocop/cop/mixin/too_many_lines'
91
91
  require 'rubocop/cop/mixin/trailing_comma'
92
92
  require 'rubocop/cop/mixin/unused_argument'
93
93
 
94
+ require 'rubocop/cop/bundler/duplicated_gem'
95
+ require 'rubocop/cop/bundler/ordered_gems'
96
+
94
97
  require 'rubocop/cop/lint/ambiguous_operator'
95
98
  require 'rubocop/cop/lint/ambiguous_regexp_literal'
96
99
  require 'rubocop/cop/lint/assignment_in_condition'
@@ -179,7 +182,7 @@ require 'rubocop/cop/performance/redundant_sort_by'
179
182
  require 'rubocop/cop/performance/reverse_each'
180
183
  require 'rubocop/cop/performance/sample'
181
184
  require 'rubocop/cop/performance/size'
182
- require 'rubocop/cop/performance/sort_with_block'
185
+ require 'rubocop/cop/performance/compare_with_block'
183
186
  require 'rubocop/cop/performance/start_with'
184
187
  require 'rubocop/cop/performance/string_replacement'
185
188
  require 'rubocop/cop/performance/times_map'
@@ -238,6 +241,7 @@ require 'rubocop/cop/style/empty_lines_around_class_body'
238
241
  require 'rubocop/cop/style/empty_lines_around_method_body'
239
242
  require 'rubocop/cop/style/empty_lines_around_module_body'
240
243
  require 'rubocop/cop/style/empty_literal'
244
+ require 'rubocop/cop/style/empty_method'
241
245
  require 'rubocop/cop/style/encoding'
242
246
  require 'rubocop/cop/style/end_block'
243
247
  require 'rubocop/cop/style/end_of_line'
@@ -393,6 +397,7 @@ require 'rubocop/cop/rails/date'
393
397
  require 'rubocop/cop/rails/dynamic_find_by'
394
398
  require 'rubocop/cop/rails/delegate'
395
399
  require 'rubocop/cop/rails/delegate_allow_blank'
400
+ require 'rubocop/cop/rails/enum_uniqueness'
396
401
  require 'rubocop/cop/rails/exit'
397
402
  require 'rubocop/cop/rails/find_by'
398
403
  require 'rubocop/cop/rails/find_each'
@@ -151,16 +151,6 @@ module RuboCop
151
151
  for_cop(cop).empty? || for_cop(cop)['Enabled']
152
152
  end
153
153
 
154
- def add_missing_namespaces
155
- keys.each do |k|
156
- q = Cop::Cop.qualified_cop_name(k, loaded_path)
157
- next if q == k
158
-
159
- self[q] = self[k]
160
- delete(k)
161
- end
162
- end
163
-
164
154
  def validate
165
155
  # Don't validate RuboCop's own files. Avoids infinite recursion.
166
156
  base_config_path = File.expand_path(File.join(ConfigLoader::RUBOCOP_HOME,
@@ -32,25 +32,34 @@ module RuboCop
32
32
  def load_file(path)
33
33
  path = File.absolute_path(path)
34
34
  hash = load_yaml_configuration(path)
35
+
36
+ add_missing_namespaces(path, hash)
37
+
38
+ resolve_inheritance_from_gems(hash, hash.delete('inherit_gem'))
39
+ resolve_inheritance(path, hash)
40
+ resolve_requires(path, hash)
41
+
42
+ hash.delete('inherit_from')
35
43
  config = Config.new(hash, path)
36
44
 
37
45
  config.deprecation_check do |deprecation_message|
38
46
  warn("#{path} - #{deprecation_message}")
39
47
  end
40
48
 
41
- config.add_missing_namespaces
42
-
43
- resolve_inheritance_from_gems(config, config.delete('inherit_gem'))
44
- resolve_inheritance(path, config)
45
- resolve_requires(path, config)
46
-
47
- config.delete('inherit_from')
48
-
49
49
  config.validate
50
50
  config.make_excludes_absolute
51
51
  config
52
52
  end
53
53
 
54
+ def add_missing_namespaces(path, hash)
55
+ hash.keys.each do |k|
56
+ q = Cop::Cop.qualified_cop_name(k, path)
57
+ next if q == k
58
+
59
+ hash[q] = hash.delete(k)
60
+ end
61
+ end
62
+
54
63
  # Return a recursive merge of two hashes. That is, a normal hash merge,
55
64
  # with the addition that any value that is a hash, and occurs in both
56
65
  # arguments, will also be merged. And so on.
@@ -66,7 +75,7 @@ module RuboCop
66
75
 
67
76
  def base_configs(path, inherit_from)
68
77
  configs = Array(inherit_from).compact.map do |f|
69
- if f =~ /\A#{URI.regexp(%w(http https))}\z/
78
+ if f =~ /\A#{URI::Parser.new.make_regexp(%w(http https))}\z/
70
79
  f = RemoteConfig.new(f, File.dirname(path)).file
71
80
  else
72
81
  f = File.expand_path(f, File.dirname(path))
@@ -189,5 +198,8 @@ module RuboCop
189
198
  dirs_to_search
190
199
  end
191
200
  end
201
+
202
+ # Initializing class ivars
203
+ clear_options
192
204
  end
193
205
  end
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Bundler
6
+ # A Gem's requirements should be listed only once in a Gemfile.
7
+ # @example
8
+ # # bad
9
+ # gem 'rubocop'
10
+ # gem 'rubocop'
11
+ #
12
+ # # bad
13
+ # group :development do
14
+ # gem 'rubocop'
15
+ # end
16
+ #
17
+ # group :test do
18
+ # gem 'rubocop'
19
+ # end
20
+ #
21
+ # # good
22
+ # group :development, :test do
23
+ # gem 'rubocop'
24
+ # end
25
+ #
26
+ # # good
27
+ # gem 'rubocop', groups: [:development, :test]
28
+ class DuplicatedGem < Cop
29
+ MSG = 'Gem `%s` requirements already given on line %d ' \
30
+ 'of the Gemfile.'.freeze
31
+
32
+ def investigate(processed_source)
33
+ return unless processed_source.ast
34
+
35
+ duplicated_gem_nodes.each do |nodes|
36
+ nodes[1..-1].each do |node|
37
+ offense(
38
+ node,
39
+ node.method_args.first.to_a.first,
40
+ nodes.first.loc.line
41
+ )
42
+ end
43
+ end
44
+ end
45
+
46
+ private
47
+
48
+ def_node_search :gem_declarations, '(send nil :gem str ...)'
49
+
50
+ def duplicated_gem_nodes
51
+ gem_declarations(processed_source.ast)
52
+ .group_by { |e| e.method_args.first }
53
+ .keep_if { |_, nodes| nodes.length > 1 }
54
+ .values
55
+ end
56
+
57
+ def offense(node, gem_name, line_of_first_occurence)
58
+ line_range = node.loc.column...node.loc.last_column
59
+
60
+ add_offense(
61
+ node,
62
+ source_range(processed_source.buffer, node.loc.line, line_range),
63
+ format(MSG, gem_name, line_of_first_occurence)
64
+ )
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+ module RuboCop
3
+ module Cop
4
+ module Bundler
5
+ # Gems in consecutive lines should be alphabetically sorted
6
+ # @example
7
+ # # bad
8
+ # gem 'rubocop'
9
+ # gem 'rspec'
10
+ #
11
+ # # good
12
+ # gem 'rspec'
13
+ # gem 'rubocop'
14
+ #
15
+ # # good
16
+ # gem 'rubocop'
17
+ #
18
+ # gem 'rspec'
19
+ class OrderedGems < Cop
20
+ MSG = 'Gem `%s` should appear before `%s` in their gem group.'.freeze
21
+ def investigate(processed_source)
22
+ return if processed_source.ast.nil?
23
+ gem_declarations(processed_source.ast)
24
+ .each_cons(2) do |previous, current|
25
+ next unless consecutive_lines(previous, current)
26
+ next unless current.children[2].children.first.to_s <
27
+ previous.children[2].children.first.to_s
28
+ register_offense(previous, current)
29
+ end
30
+ end
31
+
32
+ def consecutive_lines(previous, current)
33
+ previous.source_range.last_line == current.source_range.first_line - 1
34
+ end
35
+
36
+ def register_offense(previous, current)
37
+ add_offense(
38
+ current,
39
+ current.source_range,
40
+ format(
41
+ MSG,
42
+ current.children[2].children.first,
43
+ previous.children[2].children.first
44
+ )
45
+ )
46
+ end
47
+
48
+ def_node_search :gem_declarations, <<-PATTERN
49
+ (:send, nil, :gem, ...)
50
+ PATTERN
51
+ end
52
+ end
53
+ end
54
+ end
@@ -130,6 +130,7 @@ module RuboCop
130
130
 
131
131
  @offenses = []
132
132
  @corrections = []
133
+ @processed_source = nil
133
134
  end
134
135
 
135
136
  def join_force?(_force_class)
@@ -17,10 +17,14 @@ module RuboCop
17
17
  :save_screenshot} ...)}
18
18
  END
19
19
 
20
+ def_node_matcher :binding_irb_call?, <<-END
21
+ (send (send nil :binding) :irb ...)
22
+ END
23
+
20
24
  def_node_matcher :pry_rescue?, '(send (const nil :Pry) :rescue ...)'
21
25
 
22
26
  def on_send(node)
23
- return unless debugger_call?(node)
27
+ return unless debugger_call?(node) || binding_irb?(node)
24
28
  add_offense(node, :expression, format(MSG, node.source))
25
29
  end
26
30
 
@@ -38,6 +42,10 @@ module RuboCop
38
42
  end
39
43
  end
40
44
  end
45
+
46
+ def binding_irb?(node)
47
+ target_ruby_version >= 2.4 && binding_irb_call?(node)
48
+ end
41
49
  end
42
50
  end
43
51
  end
@@ -15,13 +15,12 @@ module RuboCop
15
15
  class EachWithObjectArgument < Cop
16
16
  MSG = 'The argument to each_with_object can not be immutable.'.freeze
17
17
 
18
- def on_send(node)
19
- _receiver, method_name, *args = *node
20
- return unless method_name == :each_with_object
21
- return unless args.length == 1
18
+ def_node_matcher :each_with_object?, '(send _ :each_with_object $_)'
22
19
 
23
- arg = args.first
24
- add_offense(node, :expression) if arg.immutable_literal?
20
+ def on_send(node)
21
+ each_with_object?(node) do |arg|
22
+ add_offense(node, :expression) if arg.immutable_literal?
23
+ end
25
24
  end
26
25
  end
27
26
  end
@@ -7,14 +7,10 @@ module RuboCop
7
7
  class Eval < Cop
8
8
  MSG = 'The use of `eval` is a serious security risk.'.freeze
9
9
 
10
- def on_send(node)
11
- receiver, method_name, *args = *node
10
+ def_node_matcher :eval?, '(send nil :eval $!str ...)'
12
11
 
13
- return unless receiver.nil? &&
14
- method_name == :eval &&
15
- !args.empty? &&
16
- !args.first.str_type?
17
- add_offense(node, :selector)
12
+ def on_send(node)
13
+ eval?(node) { add_offense(node, :selector) }
18
14
  end
19
15
  end
20
16
  end