rubocop 1.28.2 → 1.29.1

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 (80) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +3 -3
  3. data/config/default.yml +36 -21
  4. data/lib/rubocop/cop/badge.rb +1 -1
  5. data/lib/rubocop/cop/bundler/duplicated_gem.rb +1 -1
  6. data/lib/rubocop/cop/bundler/gem_comment.rb +1 -1
  7. data/lib/rubocop/cop/gemspec/dependency_version.rb +156 -0
  8. data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +3 -6
  9. data/lib/rubocop/cop/gemspec/ruby_version_globals_usage.rb +1 -1
  10. data/lib/rubocop/cop/internal_affairs/method_name_end_with.rb +80 -0
  11. data/lib/rubocop/cop/internal_affairs.rb +1 -0
  12. data/lib/rubocop/cop/layout/comment_indentation.rb +1 -1
  13. data/lib/rubocop/cop/layout/line_end_string_concatenation_indentation.rb +1 -1
  14. data/lib/rubocop/cop/layout/space_around_block_parameters.rb +1 -1
  15. data/lib/rubocop/cop/layout/space_inside_reference_brackets.rb +1 -1
  16. data/lib/rubocop/cop/layout/trailing_empty_lines.rb +1 -1
  17. data/lib/rubocop/cop/lint/ambiguous_range.rb +2 -2
  18. data/lib/rubocop/cop/lint/erb_new_arguments.rb +1 -1
  19. data/lib/rubocop/cop/lint/loop.rb +1 -1
  20. data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +5 -5
  21. data/lib/rubocop/cop/lint/or_assignment_to_constant.rb +1 -1
  22. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +1 -1
  23. data/lib/rubocop/cop/lint/raise_exception.rb +1 -1
  24. data/lib/rubocop/cop/lint/return_in_void_context.rb +5 -17
  25. data/lib/rubocop/cop/lint/useless_times.rb +1 -1
  26. data/lib/rubocop/cop/mixin/duplication.rb +1 -1
  27. data/lib/rubocop/cop/mixin/preferred_delimiters.rb +2 -2
  28. data/lib/rubocop/cop/mixin/statement_modifier.rb +1 -1
  29. data/lib/rubocop/cop/mixin/trailing_comma.rb +1 -1
  30. data/lib/rubocop/cop/naming/block_forwarding.rb +1 -1
  31. data/lib/rubocop/cop/naming/file_name.rb +1 -1
  32. data/lib/rubocop/cop/naming/inclusive_language.rb +3 -2
  33. data/lib/rubocop/cop/naming/predicate_name.rb +2 -2
  34. data/lib/rubocop/cop/naming/variable_name.rb +9 -0
  35. data/lib/rubocop/cop/naming/variable_number.rb +10 -0
  36. data/lib/rubocop/cop/security/yaml_load.rb +1 -1
  37. data/lib/rubocop/cop/style/alias.rb +3 -3
  38. data/lib/rubocop/cop/style/and_or.rb +1 -1
  39. data/lib/rubocop/cop/style/bisected_attr_accessor/macro.rb +1 -1
  40. data/lib/rubocop/cop/style/case_like_if.rb +1 -1
  41. data/lib/rubocop/cop/style/character_literal.rb +1 -1
  42. data/lib/rubocop/cop/style/collection_compact.rb +3 -3
  43. data/lib/rubocop/cop/style/date_time.rb +1 -1
  44. data/lib/rubocop/cop/style/double_negation.rb +28 -2
  45. data/lib/rubocop/cop/style/empty_case_condition.rb +1 -1
  46. data/lib/rubocop/cop/style/empty_literal.rb +1 -1
  47. data/lib/rubocop/cop/style/env_home.rb +56 -0
  48. data/lib/rubocop/cop/style/fetch_env_var.rb +240 -11
  49. data/lib/rubocop/cop/style/identical_conditional_branches.rb +2 -2
  50. data/lib/rubocop/cop/style/mixin_grouping.rb +1 -1
  51. data/lib/rubocop/cop/style/multiline_ternary_operator.rb +5 -1
  52. data/lib/rubocop/cop/style/next.rb +1 -1
  53. data/lib/rubocop/cop/style/optional_arguments.rb +1 -1
  54. data/lib/rubocop/cop/style/optional_boolean_parameter.rb +1 -1
  55. data/lib/rubocop/cop/style/quoted_symbols.rb +1 -1
  56. data/lib/rubocop/cop/style/raise_args.rb +4 -1
  57. data/lib/rubocop/cop/style/redundant_condition.rb +108 -11
  58. data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +1 -1
  59. data/lib/rubocop/cop/style/redundant_regexp_escape.rb +1 -1
  60. data/lib/rubocop/cop/style/redundant_self_assignment.rb +1 -2
  61. data/lib/rubocop/cop/style/safe_navigation.rb +1 -1
  62. data/lib/rubocop/cop/style/string_chars.rb +1 -1
  63. data/lib/rubocop/cop/style/trivial_accessors.rb +7 -8
  64. data/lib/rubocop/cops_documentation_generator.rb +1 -1
  65. data/lib/rubocop/formatter/formatter_set.rb +1 -0
  66. data/lib/rubocop/formatter/html_formatter.rb +2 -9
  67. data/lib/rubocop/formatter/markdown_formatter.rb +76 -0
  68. data/lib/rubocop/magic_comment.rb +4 -3
  69. data/lib/rubocop/options.rb +4 -3
  70. data/lib/rubocop/result_cache.rb +1 -1
  71. data/lib/rubocop/rspec/cop_helper.rb +1 -1
  72. data/lib/rubocop/rspec/parallel_formatter.rb +1 -1
  73. data/lib/rubocop/rspec/shared_contexts.rb +1 -1
  74. data/lib/rubocop/runner.rb +1 -1
  75. data/lib/rubocop/string_interpreter.rb +4 -4
  76. data/lib/rubocop/target_ruby.rb +7 -1
  77. data/lib/rubocop/version.rb +1 -1
  78. data/lib/rubocop.rb +3 -1
  79. metadata +16 -7
  80. data/lib/rubocop/cop/lint/useless_else_without_rescue.rb +0 -45
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 84de929227f41719d154ba01b986fa7b47302c666b6920b340271894cf56237a
4
- data.tar.gz: 20a87b2853c7ddde2cdd8a6bb3c2495456926456e8bc49f601af5bc1bb212992
3
+ metadata.gz: dc3f8c82f30de8d481011d509c430f07627740062258586008ada7a2e301935d
4
+ data.tar.gz: 4a41b97adf892a9acce8faec7325b822734c717b03a46ead788f154e0db27a41
5
5
  SHA512:
6
- metadata.gz: 9b6e35bb4a8b77a1969f190bda4043d7a05efa77e896cb5327acbe47755a1d12b3345de012ad8c60c7b14bb0c42bd998da28d98045039103faedfe17a178b9db
7
- data.tar.gz: a9ba88e530a520fe10607212eb29cbb74d8f84923eaec7bc726da783c6ea6f906f28ab3473b1af99bf6b65cd781ed30630169e826a1bb7f35e140c0a00bf1aa7
6
+ metadata.gz: 7222d77b9e5dcfe8908311c2d551da58959136fa9c560afd6aac17c53b0c9abcac9d9d241e31883e35e1276e5274d8b8a33cb5f5a7b917dff27602de1e3f10fb
7
+ data.tar.gz: 296507dfa80b4166a3e4960bc56c43262ca25cc32feb280d49824c335cae916c2d45bfc353ac592857c2c83aa39cd90ffe6ff568ba2d3ed2329361e0788f3b26
data/README.md CHANGED
@@ -53,7 +53,7 @@ To prevent an unwanted RuboCop update you might want to use a conservative versi
53
53
  in your `Gemfile`:
54
54
 
55
55
  ```rb
56
- gem 'rubocop', '~> 1.28', require: false
56
+ gem 'rubocop', '~> 1.29', require: false
57
57
  ```
58
58
 
59
59
  See [our versioning policy](https://docs.rubocop.org/rubocop/versioning.html) for further details.
@@ -75,8 +75,8 @@ You can read a lot more about RuboCop in its [official docs](https://docs.ruboco
75
75
 
76
76
  RuboCop officially supports the following Ruby implementations:
77
77
 
78
- * MRI 2.5+
79
- * JRuby 9.2+
78
+ * MRI 2.6+
79
+ * JRuby 9.3+
80
80
 
81
81
  See the [compatibility documentation](https://docs.rubocop.org/rubocop/compatibility.html) for further details.
82
82
 
data/config/default.yml CHANGED
@@ -140,7 +140,7 @@ AllCops:
140
140
  # or gems.locked file. (Although the Ruby version is specified in the Gemfile
141
141
  # or gems.rb file, RuboCop reads the final value from the lock file.) If the
142
142
  # Ruby version is still unresolved, RuboCop will use the oldest officially
143
- # supported Ruby version (currently Ruby 2.5).
143
+ # supported Ruby version (currently Ruby 2.6).
144
144
  TargetRubyVersion: ~
145
145
  # Determines if a notification for extension libraries should be shown when
146
146
  # rubocop is run. Keys are the name of the extension, and values are an array
@@ -242,6 +242,18 @@ Gemspec/DateAssignment:
242
242
  Include:
243
243
  - '**/*.gemspec'
244
244
 
245
+ Gemspec/DependencyVersion:
246
+ Description: 'Requires or forbids specifying gem dependency versions.'
247
+ Enabled: false
248
+ VersionAdded: '1.29'
249
+ EnforcedStyle: 'required'
250
+ SupportedStyles:
251
+ - 'required'
252
+ - 'forbidden'
253
+ Include:
254
+ - '**/*.gemspec'
255
+ AllowedGems: []
256
+
245
257
  Gemspec/DuplicatedAssignment:
246
258
  Description: 'An attribute assignment method calls should be listed only once in a gemspec.'
247
259
  Enabled: true
@@ -883,7 +895,7 @@ Layout/HeredocArgumentClosingParenthesis:
883
895
  VersionAdded: '0.68'
884
896
 
885
897
  Layout/HeredocIndentation:
886
- Description: 'This cop checks the indentation of the here document bodies.'
898
+ Description: 'Checks the indentation of the here document bodies.'
887
899
  StyleGuide: '#squiggly-heredocs'
888
900
  Enabled: true
889
901
  VersionAdded: '0.49'
@@ -1502,7 +1514,7 @@ Lint/BigDecimalNew:
1502
1514
  VersionAdded: '0.53'
1503
1515
 
1504
1516
  Lint/BinaryOperatorWithIdenticalOperands:
1505
- Description: 'This cop checks for places where binary operator has identical operands.'
1517
+ Description: 'Checks for places where binary operator has identical operands.'
1506
1518
  Enabled: true
1507
1519
  Safe: false
1508
1520
  VersionAdded: '0.89'
@@ -1684,7 +1696,7 @@ Lint/ElseLayout:
1684
1696
  VersionChanged: '1.2'
1685
1697
 
1686
1698
  Lint/EmptyBlock:
1687
- Description: 'This cop checks for blocks without a body.'
1699
+ Description: 'Checks for blocks without a body.'
1688
1700
  Enabled: pending
1689
1701
  VersionAdded: '1.1'
1690
1702
  VersionChanged: '1.15'
@@ -1698,7 +1710,7 @@ Lint/EmptyClass:
1698
1710
  AllowComments: false
1699
1711
 
1700
1712
  Lint/EmptyConditionalBody:
1701
- Description: 'This cop checks for the presence of `if`, `elsif` and `unless` branches without a body.'
1713
+ Description: 'Checks for the presence of `if`, `elsif` and `unless` branches without a body.'
1702
1714
  Enabled: true
1703
1715
  AllowComments: true
1704
1716
  VersionAdded: '0.89'
@@ -1877,7 +1889,7 @@ Lint/MissingCopEnableDirective:
1877
1889
 
1878
1890
  Lint/MissingSuper:
1879
1891
  Description: >-
1880
- This cop checks for the presence of constructors and lifecycle callbacks
1892
+ Checks for the presence of constructors and lifecycle callbacks
1881
1893
  without calls to `super`.
1882
1894
  Enabled: true
1883
1895
  VersionAdded: '0.89'
@@ -2206,7 +2218,7 @@ Lint/Syntax:
2206
2218
  VersionAdded: '0.9'
2207
2219
 
2208
2220
  Lint/ToEnumArguments:
2209
- Description: 'This cop ensures that `to_enum`/`enum_for`, called for the current method, has correct arguments.'
2221
+ Description: 'Ensures that `to_enum`/`enum_for`, called for the current method, has correct arguments.'
2210
2222
  Enabled: pending
2211
2223
  VersionAdded: '1.1'
2212
2224
 
@@ -2216,12 +2228,12 @@ Lint/ToJSON:
2216
2228
  VersionAdded: '0.66'
2217
2229
 
2218
2230
  Lint/TopLevelReturnWithArgument:
2219
- Description: 'This cop detects top level return statements with argument.'
2231
+ Description: 'Detects top level return statements with argument.'
2220
2232
  Enabled: true
2221
2233
  VersionAdded: '0.89'
2222
2234
 
2223
2235
  Lint/TrailingCommaInAttributeDeclaration:
2224
- Description: 'This cop checks for trailing commas in attribute declarations.'
2236
+ Description: 'Checks for trailing commas in attribute declarations.'
2225
2237
  Enabled: true
2226
2238
  VersionAdded: '0.90'
2227
2239
 
@@ -2270,7 +2282,7 @@ Lint/UnreachableCode:
2270
2282
  VersionAdded: '0.9'
2271
2283
 
2272
2284
  Lint/UnreachableLoop:
2273
- Description: 'This cop checks for loops that will have at most one iteration.'
2285
+ Description: 'Checks for loops that will have at most one iteration.'
2274
2286
  Enabled: true
2275
2287
  VersionAdded: '0.89'
2276
2288
  VersionChanged: '1.7'
@@ -2329,11 +2341,6 @@ Lint/UselessAssignment:
2329
2341
  Enabled: true
2330
2342
  VersionAdded: '0.11'
2331
2343
 
2332
- Lint/UselessElseWithoutRescue:
2333
- Description: 'Checks for useless `else` in `begin..end` without `rescue`.'
2334
- Enabled: true
2335
- VersionAdded: '0.17'
2336
-
2337
2344
  Lint/UselessMethodDefinition:
2338
2345
  Description: 'Checks for useless method definitions.'
2339
2346
  Enabled: true
@@ -2772,6 +2779,7 @@ Naming/VariableName:
2772
2779
  - snake_case
2773
2780
  - camelCase
2774
2781
  AllowedIdentifiers: []
2782
+ AllowedPatterns: []
2775
2783
 
2776
2784
  Naming/VariableNumber:
2777
2785
  Description: 'Use the configured style when numbering symbols, methods and variables.'
@@ -2793,6 +2801,7 @@ Naming/VariableNumber:
2793
2801
  - rfc822 # Time#rfc822
2794
2802
  - rfc2822 # Time#rfc2822
2795
2803
  - rfc3339 # DateTime.rfc3339
2804
+ AllowedPatterns: []
2796
2805
 
2797
2806
  #################### Security ##############################
2798
2807
 
@@ -3100,7 +3109,7 @@ Style/CaseEquality:
3100
3109
  AllowOnConstant: false
3101
3110
 
3102
3111
  Style/CaseLikeIf:
3103
- Description: 'This cop identifies places where `if-elsif` constructions can be replaced with `case-when`.'
3112
+ Description: 'Identifies places where `if-elsif` constructions can be replaced with `case-when`.'
3104
3113
  StyleGuide: '#case-vs-if-else'
3105
3114
  Enabled: true
3106
3115
  Safe: false
@@ -3495,6 +3504,12 @@ Style/EndlessMethod:
3495
3504
  - allow_always
3496
3505
  - disallow
3497
3506
 
3507
+ Style/EnvHome:
3508
+ Description: "Checks for consistent usage of `ENV['HOME']`."
3509
+ Enabled: pending
3510
+ Safe: false
3511
+ VersionAdded: '1.29'
3512
+
3498
3513
  Style/EvalWithLocation:
3499
3514
  Description: 'Pass `__FILE__` and `__LINE__` to `eval` method, as they are used by backtraces.'
3500
3515
  Enabled: true
@@ -3534,7 +3549,7 @@ Style/ExponentialNotation:
3534
3549
 
3535
3550
  Style/FetchEnvVar:
3536
3551
  Description: >-
3537
- This cop suggests `ENV.fetch` for the replacement of `ENV[]`.
3552
+ Suggests `ENV.fetch` for the replacement of `ENV[]`.
3538
3553
  Reference:
3539
3554
  - https://rubystyle.guide/#hash-fetch-defaults
3540
3555
  Enabled: pending
@@ -4131,7 +4146,7 @@ Style/NegatedIf:
4131
4146
 
4132
4147
  Style/NegatedIfElseCondition:
4133
4148
  Description: >-
4134
- This cop checks for uses of `if-else` and ternary operators with a negated condition
4149
+ Checks for uses of `if-else` and ternary operators with a negated condition
4135
4150
  which can be simplified by inverting condition and swapping branches.
4136
4151
  Enabled: pending
4137
4152
  VersionAdded: '1.2'
@@ -4688,7 +4703,7 @@ Style/ReturnNil:
4688
4703
 
4689
4704
  Style/SafeNavigation:
4690
4705
  Description: >-
4691
- This cop transforms usages of a method call safeguarded by
4706
+ Transforms usages of a method call safeguarded by
4692
4707
  a check for the existence of the object to
4693
4708
  safe navigation (`&.`).
4694
4709
  Auto-correction is unsafe as it assumes the object will
@@ -4915,7 +4930,7 @@ Style/StructInheritance:
4915
4930
  VersionChanged: '1.20'
4916
4931
 
4917
4932
  Style/SwapValues:
4918
- Description: 'This cop enforces the use of shorthand-style swapping of 2 variables.'
4933
+ Description: 'Enforces the use of shorthand-style swapping of 2 variables.'
4919
4934
  StyleGuide: '#values-swapping'
4920
4935
  Enabled: pending
4921
4936
  VersionAdded: '1.1'
@@ -4965,7 +4980,7 @@ Style/TernaryParentheses:
4965
4980
  AllowSafeAssignment: true
4966
4981
 
4967
4982
  Style/TopLevelMethodDefinition:
4968
- Description: 'This cop looks for top-level method definitions.'
4983
+ Description: 'Looks for top-level method definitions.'
4969
4984
  StyleGuide: '#top-level-methods'
4970
4985
  Enabled: false
4971
4986
  VersionAdded: '1.15'
@@ -15,7 +15,7 @@ module RuboCop
15
15
  def self.for(class_name)
16
16
  parts = class_name.split('::')
17
17
  name_deep_enough = parts.length >= 4
18
- new(name_deep_enough ? parts[2..-1] : parts.last(2))
18
+ new(name_deep_enough ? parts[2..] : parts.last(2))
19
19
  end
20
20
 
21
21
  def self.parse(identifier)
@@ -45,7 +45,7 @@ module RuboCop
45
45
  return if processed_source.blank?
46
46
 
47
47
  duplicated_gem_nodes.each do |nodes|
48
- nodes[1..-1].each do |node|
48
+ nodes[1..].each do |node|
49
49
  register_offense(node, node.first_argument.to_a.first, nodes.first.first_line)
50
50
  end
51
51
  end
@@ -152,7 +152,7 @@ module RuboCop
152
152
  def restrictive_version_specified_gem?(node)
153
153
  return unless version_specified_gem?(node)
154
154
 
155
- node.arguments[1..-1]
155
+ node.arguments[1..]
156
156
  .any? { |arg| arg&.str_type? && RESTRICTIVE_VERSION_PATTERN.match?(arg.value) }
157
157
  end
158
158
 
@@ -0,0 +1,156 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Gemspec
6
+ # Enforce that gem dependency version specifications or a commit reference (branch,
7
+ # ref, or tag) are either required or forbidden.
8
+ #
9
+ # @example EnforcedStyle: required (default)
10
+ #
11
+ # # bad
12
+ # Gem::Specification.new do |spec|
13
+ # spec.add_dependency 'parser'
14
+ # end
15
+ #
16
+ # # bad
17
+ # Gem::Specification.new do |spec|
18
+ # spec.add_development_dependency 'parser'
19
+ # end
20
+ #
21
+ # # good
22
+ # Gem::Specification.new do |spec|
23
+ # spec.add_dependency 'parser', '>= 2.3.3.1', '< 3.0'
24
+ # end
25
+ #
26
+ # # good
27
+ # Gem::Specification.new do |spec|
28
+ # spec.add_development_dependency 'parser', '>= 2.3.3.1', '< 3.0'
29
+ # end
30
+ #
31
+ # @example EnforcedStyle: forbidden
32
+ #
33
+ # # bad
34
+ # Gem::Specification.new do |spec|
35
+ # spec.add_dependency 'parser', '>= 2.3.3.1', '< 3.0'
36
+ # end
37
+ #
38
+ # # bad
39
+ # Gem::Specification.new do |spec|
40
+ # spec.add_development_dependency 'parser', '>= 2.3.3.1', '< 3.0'
41
+ # end
42
+ #
43
+ # # good
44
+ # Gem::Specification.new do |spec|
45
+ # spec.add_dependency 'parser'
46
+ # end
47
+ #
48
+ # # good
49
+ # Gem::Specification.new do |spec|
50
+ # spec.add_development_dependency 'parser'
51
+ # end
52
+ #
53
+ class DependencyVersion < Base
54
+ include ConfigurableEnforcedStyle
55
+ include GemspecHelp
56
+
57
+ REQUIRED_MSG = 'Dependency version specification is required.'
58
+ FORBIDDEN_MSG = 'Dependency version specification is forbidden.'
59
+ VERSION_SPECIFICATION_REGEX = /^\s*[~<>=]*\s*[0-9.]+/.freeze
60
+
61
+ # @!method add_dependency_method_declarations(node)
62
+ def_node_search :add_dependency_method_declarations, <<~PATTERN
63
+ (send
64
+ (lvar #match_block_variable_name?) #add_dependency_method? ...)
65
+ PATTERN
66
+
67
+ # @!method includes_version_specification?(node)
68
+ def_node_matcher :includes_version_specification?, <<~PATTERN
69
+ (send _ #add_dependency_method? <(str #version_specification?) ...>)
70
+ PATTERN
71
+
72
+ # @!method includes_commit_reference?(node)
73
+ def_node_matcher :includes_commit_reference?, <<~PATTERN
74
+ (send _ #add_dependency_method? <(hash <(pair (sym {:branch :ref :tag}) (str _)) ...>) ...>)
75
+ PATTERN
76
+
77
+ def on_new_investigation
78
+ return if processed_source.blank?
79
+
80
+ add_dependency_method_nodes.each do |node|
81
+ next if allowed_gem?(node)
82
+
83
+ if offense?(node)
84
+ add_offense(node)
85
+ opposite_style_detected
86
+ else
87
+ correct_style_detected
88
+ end
89
+ end
90
+ end
91
+
92
+ private
93
+
94
+ def allowed_gem?(node)
95
+ allowed_gems.include?(node.first_argument.value)
96
+ end
97
+
98
+ def allowed_gems
99
+ Array(cop_config['AllowedGems'])
100
+ end
101
+
102
+ def message(range)
103
+ gem_specification = range.source
104
+
105
+ if required_style?
106
+ format(REQUIRED_MSG, gem_specification: gem_specification)
107
+ elsif forbidden_style?
108
+ format(FORBIDDEN_MSG, gem_specification: gem_specification)
109
+ end
110
+ end
111
+
112
+ def match_block_variable_name?(receiver_name)
113
+ gem_specification(processed_source.ast) do |block_variable_name|
114
+ return block_variable_name == receiver_name
115
+ end
116
+ end
117
+
118
+ def add_dependency_method?(method_name)
119
+ method_name.to_s.end_with?('_dependency')
120
+ end
121
+
122
+ def add_dependency_method_nodes
123
+ add_dependency_method_declarations(processed_source.ast)
124
+ end
125
+
126
+ def offense?(node)
127
+ required_offense?(node) || forbidden_offense?(node)
128
+ end
129
+
130
+ def required_offense?(node)
131
+ return unless required_style?
132
+
133
+ !includes_version_specification?(node) && !includes_commit_reference?(node)
134
+ end
135
+
136
+ def forbidden_offense?(node)
137
+ return unless forbidden_style?
138
+
139
+ includes_version_specification?(node) || includes_commit_reference?(node)
140
+ end
141
+
142
+ def forbidden_style?
143
+ style == :forbidden
144
+ end
145
+
146
+ def required_style?
147
+ style == :required
148
+ end
149
+
150
+ def version_specification?(expression)
151
+ expression.match?(VERSION_SPECIFICATION_REGEX)
152
+ end
153
+ end
154
+ end
155
+ end
156
+ end
@@ -44,14 +44,14 @@ module RuboCop
44
44
  # @!method assignment_method_declarations(node)
45
45
  def_node_search :assignment_method_declarations, <<~PATTERN
46
46
  (send
47
- (lvar #match_block_variable_name?) #assignment_method? ...)
47
+ (lvar #match_block_variable_name?) _ ...)
48
48
  PATTERN
49
49
 
50
50
  def on_new_investigation
51
51
  return if processed_source.blank?
52
52
 
53
53
  duplicated_assignment_method_nodes.each do |nodes|
54
- nodes[1..-1].each do |node|
54
+ nodes[1..].each do |node|
55
55
  register_offense(node, node.method_name, nodes.first.first_line)
56
56
  end
57
57
  end
@@ -65,12 +65,9 @@ module RuboCop
65
65
  end
66
66
  end
67
67
 
68
- def assignment_method?(method_name)
69
- method_name.to_s.end_with?('=')
70
- end
71
-
72
68
  def duplicated_assignment_method_nodes
73
69
  assignment_method_declarations(processed_source.ast)
70
+ .select(&:assignment_method?)
74
71
  .group_by(&:method_name)
75
72
  .values
76
73
  .select { |nodes| nodes.size > 1 }
@@ -13,7 +13,7 @@ module RuboCop
13
13
  #
14
14
  # # bad
15
15
  # Gem::Specification.new do |spec|
16
- # if RUBY_VERSION >= '2.5'
16
+ # if RUBY_VERSION >= '3.0'
17
17
  # spec.add_runtime_dependency 'gem_a'
18
18
  # else
19
19
  # spec.add_runtime_dependency 'gem_b'
@@ -0,0 +1,80 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module InternalAffairs
6
+ # This cop checks potentially usage of method identifier predicates
7
+ # defined in rubocop-ast instead of `method_name.end_with?`.
8
+ #
9
+ # @example
10
+ # # bad
11
+ # node.method_name.to_s.end_with?('=')
12
+ #
13
+ # # good
14
+ # node.assignment_method?
15
+ #
16
+ # # bad
17
+ # node.method_name.to_s.end_with?('?')
18
+ #
19
+ # # good
20
+ # node.predicate_method?
21
+ #
22
+ # # bad
23
+ # node.method_name.to_s.end_with?('!')
24
+ #
25
+ # # good
26
+ # node.bang_method?
27
+ #
28
+ class MethodNameEndWith < Base
29
+ include RangeHelp
30
+ extend AutoCorrector
31
+
32
+ MSG = 'Use `%<method_name>s` instead of `%<method_suffix>s`.'
33
+ SUGGEST_METHOD_FOR_SUFFIX = {
34
+ '=' => 'assignment_method?',
35
+ '!' => 'bang_method?',
36
+ '?' => 'predicate_method?'
37
+ }.freeze
38
+
39
+ # @!method method_name_end_with?(node)
40
+ def_node_matcher :method_name_end_with?, <<~PATTERN
41
+ {
42
+ (call
43
+ (call
44
+ $(... :method_name) :to_s) :end_with?
45
+ $(str {"=" "?" "!"}))
46
+ (call
47
+ $(... :method_name) :end_with?
48
+ $(str {"=" "?" "!"}))
49
+ }
50
+ PATTERN
51
+
52
+ def on_send(node)
53
+ method_name_end_with?(node) do |method_name_node, end_with_arg|
54
+ range = range(method_name_node, node)
55
+ message = format(
56
+ MSG,
57
+ method_name: SUGGEST_METHOD_FOR_SUFFIX[end_with_arg.value],
58
+ method_suffix: range.source
59
+ )
60
+
61
+ add_offense(range, message: message)
62
+ end
63
+ end
64
+ alias on_csend on_send
65
+
66
+ private
67
+
68
+ def range(method_name_node, node)
69
+ range = if method_name_node.call_type?
70
+ method_name_node.loc.selector
71
+ else
72
+ method_name_node.source_range
73
+ end
74
+
75
+ range_between(range.begin_pos, node.source_range.end_pos)
76
+ end
77
+ end
78
+ end
79
+ end
80
+ end
@@ -4,6 +4,7 @@ require_relative 'internal_affairs/empty_line_between_expect_offense_and_correct
4
4
  require_relative 'internal_affairs/example_description'
5
5
  require_relative 'internal_affairs/inherit_deprecated_cop_class'
6
6
  require_relative 'internal_affairs/location_line_equality_comparison'
7
+ require_relative 'internal_affairs/method_name_end_with'
7
8
  require_relative 'internal_affairs/method_name_equal'
8
9
  require_relative 'internal_affairs/node_destructuring'
9
10
  require_relative 'internal_affairs/node_matcher_directive'
@@ -139,7 +139,7 @@ module RuboCop
139
139
 
140
140
  def line_after_comment(comment)
141
141
  lines = processed_source.lines
142
- lines[comment.loc.line..-1].find { |line| !line.blank? }
142
+ lines[comment.loc.line..].find { |line| !line.blank? }
143
143
  end
144
144
 
145
145
  def correct_indentation(next_line)
@@ -110,7 +110,7 @@ module RuboCop
110
110
 
111
111
  def check_aligned(children, start_index)
112
112
  base_column = children[start_index - 1].loc.column
113
- children[start_index..-1].each do |child|
113
+ children[start_index..].each do |child|
114
114
  @column_delta = base_column - child.loc.column
115
115
  add_offense_and_correction(child, MSG_ALIGN) if @column_delta != 0
116
116
  base_column = child.loc.column
@@ -113,7 +113,7 @@ module RuboCop
113
113
  def last_end_pos_inside_pipes(arguments, range)
114
114
  pos = range.end_pos
115
115
  num = pos - arguments.source_range.begin_pos
116
- trailing_comma_index = arguments.source[num..-1].index(',')
116
+ trailing_comma_index = arguments.source[num..].index(',')
117
117
 
118
118
  trailing_comma_index ? pos + trailing_comma_index + 1 : pos
119
119
  end
@@ -118,7 +118,7 @@ module RuboCop
118
118
  i = tokens.index(opening_bracket)
119
119
  inner_left_brackets_needing_closure = 0
120
120
 
121
- tokens[i..-1].each do |token|
121
+ tokens[i..].each do |token|
122
122
  inner_left_brackets_needing_closure += 1 if token.left_bracket?
123
123
  inner_left_brackets_needing_closure -= 1 if token.right_bracket?
124
124
  return token if inner_left_brackets_needing_closure.zero? && token.right_bracket?
@@ -82,7 +82,7 @@ module RuboCop
82
82
  return true if buffer.source.strip.start_with?('__END__')
83
83
  return false if processed_source.tokens.empty?
84
84
 
85
- extra = buffer.source[processed_source.tokens.last.end_pos..-1]
85
+ extra = buffer.source[processed_source.tokens.last.end_pos..]
86
86
  extra&.strip&.start_with?('__END__')
87
87
  end
88
88
 
@@ -5,7 +5,7 @@ module RuboCop
5
5
  module Lint
6
6
  # This cop checks for ambiguous ranges.
7
7
  #
8
- # Ranges have quite low precedence, which leads to unexpected behaviour when
8
+ # Ranges have quite low precedence, which leads to unexpected behavior when
9
9
  # using a range with other operators. This cop avoids that by making ranges
10
10
  # explicit by requiring parenthesis around complex range boundaries (anything
11
11
  # that is not a literal: numerics, strings, symbols, etc.).
@@ -21,7 +21,7 @@ module RuboCop
21
21
  # The cop auto-corrects by wrapping the entire boundary in parentheses, which
22
22
  # makes the outcome more explicit but is possible to not be the intention of the
23
23
  # programmer. For this reason, this cop's auto-correct is unsafe (it will not
24
- # change the behaviour of the code, but will not necessarily match the
24
+ # change the behavior of the code, but will not necessarily match the
25
25
  # intent of the program).
26
26
  #
27
27
  # @example
@@ -61,8 +61,8 @@ module RuboCop
61
61
  #
62
62
  class ErbNewArguments < Base
63
63
  include RangeHelp
64
- extend TargetRubyVersion
65
64
  extend AutoCorrector
65
+ extend TargetRubyVersion
66
66
 
67
67
  minimum_target_ruby_version 2.6
68
68
 
@@ -6,7 +6,7 @@ module RuboCop
6
6
  # This cop checks for uses of `begin...end while/until something`.
7
7
  #
8
8
  # @safety
9
- # The cop is unsafe because behaviour can change in some cases, including
9
+ # The cop is unsafe because behavior can change in some cases, including
10
10
  # if a local variable inside the loop body is accessed outside of it, or if the
11
11
  # loop body raises a `StopIteration` exception (which `Kernel#loop` rescues).
12
12
  #
@@ -18,7 +18,7 @@ module RuboCop
18
18
  #
19
19
  # @safety
20
20
  # This cop is unsafe in the case where sorting files changes existing
21
- # expected behaviour.
21
+ # expected behavior.
22
22
  #
23
23
  # @example
24
24
  #
@@ -143,19 +143,19 @@ module RuboCop
143
143
 
144
144
  # @!method method_require?(node)
145
145
  def_node_matcher :method_require?, <<~PATTERN
146
- (block-pass (send nil? :method (sym :require)))
146
+ (block-pass (send nil? :method (sym {:require :require_relative})))
147
147
  PATTERN
148
148
 
149
149
  # @!method unsorted_dir_glob_pass?(node)
150
150
  def_node_matcher :unsorted_dir_glob_pass?, <<~PATTERN
151
151
  (send (const {nil? cbase} :Dir) :glob ...
152
- (block-pass (send nil? :method (sym :require))))
152
+ (block-pass (send nil? :method (sym {:require :require_relative}))))
153
153
  PATTERN
154
154
 
155
155
  # @!method unsorted_dir_each_pass?(node)
156
156
  def_node_matcher :unsorted_dir_each_pass?, <<~PATTERN
157
157
  (send (send (const {nil? cbase} :Dir) {:[] :glob} ...) :each
158
- (block-pass (send nil? :method (sym :require))))
158
+ (block-pass (send nil? :method (sym {:require :require_relative}))))
159
159
  PATTERN
160
160
 
161
161
  # @!method loop_variable(node)
@@ -165,7 +165,7 @@ module RuboCop
165
165
 
166
166
  # @!method var_is_required?(node, name)
167
167
  def_node_search :var_is_required?, <<~PATTERN
168
- (send nil? :require (lvar %1))
168
+ (send nil? {:require :require_relative} (lvar %1))
169
169
  PATTERN
170
170
  end
171
171
  end