rubocop 1.21.0 → 1.22.3

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 (157) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/config/default.yml +49 -9
  4. data/lib/rubocop/config.rb +5 -0
  5. data/lib/rubocop/config_loader.rb +3 -1
  6. data/lib/rubocop/config_validator.rb +9 -1
  7. data/lib/rubocop/cop/base.rb +1 -1
  8. data/lib/rubocop/cop/bundler/gem_comment.rb +3 -3
  9. data/lib/rubocop/cop/bundler/insecure_protocol_source.rb +34 -11
  10. data/lib/rubocop/cop/bundler/ordered_gems.rb +3 -12
  11. data/lib/rubocop/cop/correctors/ordered_gem_corrector.rb +11 -10
  12. data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +3 -12
  13. data/lib/rubocop/cop/gemspec/required_ruby_version.rb +31 -24
  14. data/lib/rubocop/cop/generator.rb +14 -8
  15. data/lib/rubocop/cop/internal_affairs/location_line_equality_comparison.rb +60 -0
  16. data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +1 -1
  17. data/lib/rubocop/cop/internal_affairs.rb +1 -0
  18. data/lib/rubocop/cop/layout/assignment_indentation.rb +1 -1
  19. data/lib/rubocop/cop/layout/block_alignment.rb +3 -3
  20. data/lib/rubocop/cop/layout/dot_position.rb +34 -5
  21. data/lib/rubocop/cop/layout/empty_comment.rb +1 -1
  22. data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +7 -4
  23. data/lib/rubocop/cop/layout/end_alignment.rb +1 -2
  24. data/lib/rubocop/cop/layout/first_array_element_indentation.rb +1 -1
  25. data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +1 -1
  26. data/lib/rubocop/cop/layout/first_parameter_indentation.rb +1 -1
  27. data/lib/rubocop/cop/layout/hash_alignment.rb +1 -1
  28. data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +1 -1
  29. data/lib/rubocop/cop/layout/indentation_width.rb +1 -1
  30. data/lib/rubocop/cop/layout/line_length.rb +8 -6
  31. data/lib/rubocop/cop/layout/multiline_assignment_layout.rb +1 -1
  32. data/lib/rubocop/cop/layout/multiline_block_layout.rb +2 -2
  33. data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +1 -1
  34. data/lib/rubocop/cop/layout/redundant_line_break.rb +1 -0
  35. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +1 -1
  36. data/lib/rubocop/cop/layout/space_before_comment.rb +1 -1
  37. data/lib/rubocop/cop/layout/space_inside_parens.rb +74 -28
  38. data/lib/rubocop/cop/lint/ambiguous_operator_precedence.rb +5 -1
  39. data/lib/rubocop/cop/lint/ambiguous_range.rb +8 -8
  40. data/lib/rubocop/cop/lint/assignment_in_condition.rb +7 -5
  41. data/lib/rubocop/cop/lint/binary_operator_with_identical_operands.rb +18 -5
  42. data/lib/rubocop/cop/lint/boolean_symbol.rb +5 -0
  43. data/lib/rubocop/cop/lint/deprecated_class_methods.rb +4 -4
  44. data/lib/rubocop/cop/lint/deprecated_constants.rb +3 -2
  45. data/lib/rubocop/cop/lint/disjunctive_assignment_in_constructor.rb +24 -1
  46. data/lib/rubocop/cop/lint/else_layout.rb +10 -6
  47. data/lib/rubocop/cop/lint/hash_compare_by_identity.rb +12 -3
  48. data/lib/rubocop/cop/lint/interpolation_check.rb +5 -0
  49. data/lib/rubocop/cop/lint/loop.rb +4 -3
  50. data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +5 -1
  51. data/lib/rubocop/cop/lint/number_conversion.rb +5 -0
  52. data/lib/rubocop/cop/lint/numbered_parameter_assignment.rb +1 -1
  53. data/lib/rubocop/cop/lint/or_assignment_to_constant.rb +4 -2
  54. data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +17 -0
  55. data/lib/rubocop/cop/lint/percent_string_array.rb +10 -0
  56. data/lib/rubocop/cop/lint/raise_exception.rb +4 -0
  57. data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +5 -4
  58. data/lib/rubocop/cop/lint/require_relative_self_path.rb +50 -0
  59. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +1 -1
  60. data/lib/rubocop/cop/lint/symbol_conversion.rb +1 -1
  61. data/lib/rubocop/cop/lint/triple_quotes.rb +1 -1
  62. data/lib/rubocop/cop/lint/unexpected_block_arity.rb +8 -3
  63. data/lib/rubocop/cop/lint/useless_method_definition.rb +3 -2
  64. data/lib/rubocop/cop/lint/useless_setter_call.rb +7 -4
  65. data/lib/rubocop/cop/lint/useless_times.rb +3 -2
  66. data/lib/rubocop/cop/metrics/abc_size.rb +6 -0
  67. data/lib/rubocop/cop/metrics/parameter_lists.rb +5 -2
  68. data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +1 -2
  69. data/lib/rubocop/cop/mixin/frozen_string_literal.rb +5 -1
  70. data/lib/rubocop/cop/mixin/hash_transform_method.rb +3 -3
  71. data/lib/rubocop/cop/mixin/heredoc.rb +1 -3
  72. data/lib/rubocop/cop/mixin/multiline_element_indentation.rb +1 -1
  73. data/lib/rubocop/cop/mixin/multiline_literal_brace_layout.rb +1 -1
  74. data/lib/rubocop/cop/mixin/ordered_gem_node.rb +9 -1
  75. data/lib/rubocop/cop/mixin/percent_array.rb +6 -1
  76. data/lib/rubocop/cop/mixin/space_after_punctuation.rb +1 -1
  77. data/lib/rubocop/cop/mixin/space_before_punctuation.rb +1 -1
  78. data/lib/rubocop/cop/mixin/statement_modifier.rb +1 -1
  79. data/lib/rubocop/cop/mixin/string_literals_help.rb +5 -1
  80. data/lib/rubocop/cop/mixin/trailing_body.rb +1 -1
  81. data/lib/rubocop/cop/naming/block_parameter_name.rb +1 -1
  82. data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +5 -4
  83. data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +7 -0
  84. data/lib/rubocop/cop/security/io_methods.rb +49 -0
  85. data/lib/rubocop/cop/security/json_load.rb +8 -7
  86. data/lib/rubocop/cop/security/open.rb +4 -0
  87. data/lib/rubocop/cop/security/yaml_load.rb +4 -0
  88. data/lib/rubocop/cop/style/and_or.rb +4 -3
  89. data/lib/rubocop/cop/style/arguments_forwarding.rb +13 -2
  90. data/lib/rubocop/cop/style/array_coercion.rb +21 -3
  91. data/lib/rubocop/cop/style/case_like_if.rb +5 -0
  92. data/lib/rubocop/cop/style/class_and_module_children.rb +9 -0
  93. data/lib/rubocop/cop/style/collection_compact.rb +7 -5
  94. data/lib/rubocop/cop/style/collection_methods.rb +6 -5
  95. data/lib/rubocop/cop/style/combinable_loops.rb +3 -2
  96. data/lib/rubocop/cop/style/commented_keyword.rb +9 -4
  97. data/lib/rubocop/cop/style/date_time.rb +5 -0
  98. data/lib/rubocop/cop/style/double_negation.rb +15 -5
  99. data/lib/rubocop/cop/style/float_division.rb +10 -2
  100. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +6 -1
  101. data/lib/rubocop/cop/style/global_std_stream.rb +4 -0
  102. data/lib/rubocop/cop/style/hash_each_methods.rb +5 -0
  103. data/lib/rubocop/cop/style/hash_transform_keys.rb +4 -6
  104. data/lib/rubocop/cop/style/hash_transform_values.rb +4 -6
  105. data/lib/rubocop/cop/style/identical_conditional_branches.rb +18 -16
  106. data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +15 -2
  107. data/lib/rubocop/cop/style/infinite_loop.rb +4 -3
  108. data/lib/rubocop/cop/style/inverse_methods.rb +9 -2
  109. data/lib/rubocop/cop/style/line_end_concatenation.rb +14 -1
  110. data/lib/rubocop/cop/style/module_function.rb +8 -9
  111. data/lib/rubocop/cop/style/multiline_in_pattern_then.rb +1 -1
  112. data/lib/rubocop/cop/style/multiline_when_then.rb +1 -1
  113. data/lib/rubocop/cop/style/mutable_constant.rb +12 -7
  114. data/lib/rubocop/cop/style/numbered_parameters.rb +46 -0
  115. data/lib/rubocop/cop/style/numbered_parameters_limit.rb +50 -0
  116. data/lib/rubocop/cop/style/numeric_literals.rb +7 -8
  117. data/lib/rubocop/cop/style/numeric_predicate.rb +5 -0
  118. data/lib/rubocop/cop/style/optional_arguments.rb +4 -0
  119. data/lib/rubocop/cop/style/optional_boolean_parameter.rb +14 -4
  120. data/lib/rubocop/cop/style/preferred_hash_methods.rb +9 -4
  121. data/lib/rubocop/cop/style/quoted_symbols.rb +10 -6
  122. data/lib/rubocop/cop/style/redundant_argument.rb +19 -9
  123. data/lib/rubocop/cop/style/redundant_fetch_block.rb +4 -0
  124. data/lib/rubocop/cop/style/redundant_file_extension_in_require.rb +12 -3
  125. data/lib/rubocop/cop/style/redundant_freeze.rb +0 -1
  126. data/lib/rubocop/cop/style/redundant_self.rb +10 -0
  127. data/lib/rubocop/cop/style/redundant_self_assignment.rb +4 -3
  128. data/lib/rubocop/cop/style/redundant_sort.rb +47 -29
  129. data/lib/rubocop/cop/style/safe_navigation.rb +13 -2
  130. data/lib/rubocop/cop/style/select_by_regexp.rb +139 -0
  131. data/lib/rubocop/cop/style/single_argument_dig.rb +5 -0
  132. data/lib/rubocop/cop/style/slicing_with_range.rb +13 -0
  133. data/lib/rubocop/cop/style/special_global_vars.rb +4 -0
  134. data/lib/rubocop/cop/style/static_class.rb +4 -3
  135. data/lib/rubocop/cop/style/string_chars.rb +4 -2
  136. data/lib/rubocop/cop/style/string_concatenation.rb +4 -0
  137. data/lib/rubocop/cop/style/string_hash_keys.rb +4 -0
  138. data/lib/rubocop/cop/style/struct_inheritance.rb +3 -2
  139. data/lib/rubocop/cop/style/swap_values.rb +4 -2
  140. data/lib/rubocop/cop/style/symbol_proc.rb +26 -0
  141. data/lib/rubocop/cop/style/trailing_comma_in_block_args.rb +19 -0
  142. data/lib/rubocop/cop/style/yoda_condition.rb +20 -0
  143. data/lib/rubocop/cop/style/zero_length_predicate.rb +6 -0
  144. data/lib/rubocop/cop/util.rb +15 -4
  145. data/lib/rubocop/cops_documentation_generator.rb +17 -5
  146. data/lib/rubocop/options.rb +126 -112
  147. data/lib/rubocop/rake_task.rb +1 -1
  148. data/lib/rubocop/result_cache.rb +2 -2
  149. data/lib/rubocop/rspec/cop_helper.rb +1 -1
  150. data/lib/rubocop/rspec/expect_offense.rb +6 -2
  151. data/lib/rubocop/rspec/parallel_formatter.rb +90 -0
  152. data/lib/rubocop/rspec/support.rb +1 -0
  153. data/lib/rubocop/runner.rb +1 -1
  154. data/lib/rubocop/target_finder.rb +1 -1
  155. data/lib/rubocop/version.rb +1 -1
  156. data/lib/rubocop.rb +5 -0
  157. metadata +12 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: dd3bb4ebea9d6db387e52e92a0c9ffac3f6215f0b5b9bcd7d555e979c8fb9fa7
4
- data.tar.gz: 208d08bf57f092a0857776924cb529db1324ecdf4696476475f51878f803b6ac
3
+ metadata.gz: f74b024d0339618cd4782bd451e3bbe8be65eab0a5f3dbfc1d2137c74848c6fa
4
+ data.tar.gz: ef762c615b2d68f52d5aac425abea13a40d097f1b7885cd1558a991dd23c136d
5
5
  SHA512:
6
- metadata.gz: 9d32668f49f495948628017c042cbc292d62c4ba93d905635d47ecba7c12e69ff7cbff3999a6cccba62bbc27ff7b51827e1a00f41769c1dd711f342fe10e8519
7
- data.tar.gz: 9798e105b8ea95245d153e9e295a95a593e49464f91ac8c508ce0900f7f2ef0e97759a1144044f32acb726e11d3552de1f5de8d2d477151606bfd39090df3260
6
+ metadata.gz: bfdba4bbc01e69d2a0873272815dc9c03d5e95f2dce5f02186b38f2f9e1e28ae34df246e6b548cdccf0831bace4f02bfad334f59548b2bf67430431b5760731b
7
+ data.tar.gz: 662e06452c13b66a949e7a8035bc6b4b31e7af7a3cf161b9802634365a53a0b2452aeb7741ab13387186483cdf9027dc5cca736734d5d3022f78362bfabf9a5c
data/README.md CHANGED
@@ -54,7 +54,7 @@ To prevent an unwanted RuboCop update you might want to use a conservative versi
54
54
  in your `Gemfile`:
55
55
 
56
56
  ```rb
57
- gem 'rubocop', '~> 1.21', require: false
57
+ gem 'rubocop', '~> 1.22', require: false
58
58
  ```
59
59
 
60
60
  See [our versioning policy](https://docs.rubocop.org/rubocop/versioning.html) for further details.
data/config/default.yml CHANGED
@@ -130,7 +130,7 @@ AllCops:
130
130
  # What MRI version of the Ruby interpreter is the inspected code intended to
131
131
  # run on? (If there is more than one, set this to the lowest version.)
132
132
  # If a value is specified for TargetRubyVersion then it is used. Acceptable
133
- # values are specificed as a float (i.e. 3.0); the teeny version of Ruby
133
+ # values are specified as a float (i.e. 3.0); the teeny version of Ruby
134
134
  # should not be included. If the project specifies a Ruby version in the
135
135
  # .tool-versions or .ruby-version files, Gemfile or gems.rb file, RuboCop will
136
136
  # try to determine the desired version of Ruby by inspecting the
@@ -209,6 +209,7 @@ Bundler/InsecureProtocolSource:
209
209
  'https://rubygems.org' if possible, or 'http://rubygems.org' if not.
210
210
  Enabled: true
211
211
  VersionAdded: '0.50'
212
+ AllowHttpProtocol: true
212
213
  Include:
213
214
  - '**/*.gemfile'
214
215
  - '**/Gemfile'
@@ -261,7 +262,7 @@ Gemspec/RequiredRubyVersion:
261
262
  Description: 'Checks that `required_ruby_version` of gemspec is specified and equal to `TargetRubyVersion` of .rubocop.yml.'
262
263
  Enabled: true
263
264
  VersionAdded: '0.52'
264
- VersionChanged: '0.89'
265
+ VersionChanged: '1.22'
265
266
  Include:
266
267
  - '**/*.gemspec'
267
268
 
@@ -1360,10 +1361,11 @@ Layout/SpaceInsideParens:
1360
1361
  StyleGuide: '#spaces-braces'
1361
1362
  Enabled: true
1362
1363
  VersionAdded: '0.49'
1363
- VersionChanged: '0.55'
1364
+ VersionChanged: '1.22'
1364
1365
  EnforcedStyle: no_space
1365
1366
  SupportedStyles:
1366
1367
  - space
1368
+ - compact
1367
1369
  - no_space
1368
1370
 
1369
1371
  Layout/SpaceInsidePercentLiteralDelimiters:
@@ -1491,9 +1493,9 @@ Lint/BinaryOperatorWithIdenticalOperands:
1491
1493
  Lint/BooleanSymbol:
1492
1494
  Description: 'Check for `:true` and `:false` symbols.'
1493
1495
  Enabled: true
1494
- Safe: false
1496
+ SafeAutoCorrect: false
1495
1497
  VersionAdded: '0.50'
1496
- VersionChanged: '0.83'
1498
+ VersionChanged: '1.22'
1497
1499
 
1498
1500
  Lint/CircularArgumentReference:
1499
1501
  Description: "Default values in optional keyword arguments and optional ordinal arguments should not refer back to the name of the argument."
@@ -1566,6 +1568,7 @@ Lint/DeprecatedConstants:
1566
1568
  Description: 'Checks for deprecated constants.'
1567
1569
  Enabled: pending
1568
1570
  VersionAdded: '1.8'
1571
+ VersionChanged: '1.22'
1569
1572
  # You can configure deprecated constants.
1570
1573
  # If there is an alternative method, you can set alternative value as `Alternative`.
1571
1574
  # And you can set the deprecated version as `DeprecatedVersion`.
@@ -1586,6 +1589,9 @@ Lint/DeprecatedConstants:
1586
1589
  'FALSE':
1587
1590
  Alternative: 'false'
1588
1591
  DeprecatedVersion: '2.4'
1592
+ 'Net::HTTPServerException':
1593
+ Alternative: 'Net::HTTPClientException'
1594
+ DeprecatedVersion: '2.6'
1589
1595
  'Random::DEFAULT':
1590
1596
  Alternative: 'Random.new'
1591
1597
  DeprecatedVersion: '3.0'
@@ -2045,6 +2051,11 @@ Lint/RequireParentheses:
2045
2051
  Enabled: true
2046
2052
  VersionAdded: '0.18'
2047
2053
 
2054
+ Lint/RequireRelativeSelfPath:
2055
+ Description: 'Checks for uses a file requiring itself with `require_relative`.'
2056
+ Enabled: pending
2057
+ VersionAdded: '1.22'
2058
+
2048
2059
  Lint/RescueException:
2049
2060
  Description: 'Avoid rescuing the Exception class.'
2050
2061
  StyleGuide: '#no-blind-rescues'
@@ -2732,6 +2743,14 @@ Security/Eval:
2732
2743
  Enabled: true
2733
2744
  VersionAdded: '0.47'
2734
2745
 
2746
+ Security/IoMethods:
2747
+ Description: >-
2748
+ Checks for the first argument to `IO.read`, `IO.binread`, `IO.write`, `IO.binwrite`,
2749
+ `IO.foreach`, and `IO.readlines`.
2750
+ Enabled: pending
2751
+ Safe: false
2752
+ VersionAdded: '1.22'
2753
+
2735
2754
  Security/JSONLoad:
2736
2755
  Description: >-
2737
2756
  Prefer usage of `JSON.parse` over `JSON.load` due to potential
@@ -2739,10 +2758,9 @@ Security/JSONLoad:
2739
2758
  Reference: 'https://ruby-doc.org/stdlib-2.7.0/libdoc/json/rdoc/JSON.html#method-i-load'
2740
2759
  Enabled: true
2741
2760
  VersionAdded: '0.43'
2742
- VersionChanged: '0.44'
2761
+ VersionChanged: '1.22'
2743
2762
  # Autocorrect here will change to a method that may cause crashes depending
2744
2763
  # on the value of the argument.
2745
- AutoCorrect: false
2746
2764
  SafeAutoCorrect: false
2747
2765
 
2748
2766
  Security/MarshalLoad:
@@ -3703,7 +3721,7 @@ Style/InPatternThen:
3703
3721
  Style/InfiniteLoop:
3704
3722
  Description: >-
3705
3723
  Use Kernel#loop for infinite loops.
3706
- This cop is unsafe in the body may raise a `StopIteration` exception.
3724
+ This cop is unsafe if the body may raise a `StopIteration` exception.
3707
3725
  Safe: false
3708
3726
  StyleGuide: '#infinite-loop'
3709
3727
  Enabled: true
@@ -4129,6 +4147,21 @@ Style/Not:
4129
4147
  VersionAdded: '0.9'
4130
4148
  VersionChanged: '0.20'
4131
4149
 
4150
+ Style/NumberedParameters:
4151
+ Description: 'Restrict the usage of numbered parameters.'
4152
+ Enabled: pending
4153
+ VersionAdded: '1.22'
4154
+ EnforcedStyle: allow_single_line
4155
+ SupportedStyles:
4156
+ - allow_single_line
4157
+ - disallow
4158
+
4159
+ Style/NumberedParametersLimit:
4160
+ Description: 'Avoid excessive numbered params in a single block.'
4161
+ Enabled: pending
4162
+ VersionAdded: '1.22'
4163
+ Max: 1
4164
+
4132
4165
  Style/NumericLiteralPrefix:
4133
4166
  Description: 'Use smallcase prefixes for numeric literals.'
4134
4167
  StyleGuide: '#numeric-literal-prefixes'
@@ -4139,7 +4172,6 @@ Style/NumericLiteralPrefix:
4139
4172
  - zero_with_o
4140
4173
  - zero_only
4141
4174
 
4142
-
4143
4175
  Style/NumericLiterals:
4144
4176
  Description: >-
4145
4177
  Add underscores to large numeric literals to improve their
@@ -4460,6 +4492,8 @@ Style/RedundantSort:
4460
4492
  `max_by` instead of `sort_by...last`, etc.
4461
4493
  Enabled: true
4462
4494
  VersionAdded: '0.76'
4495
+ VersionChanged: '1.22'
4496
+ Safe: false
4463
4497
 
4464
4498
  Style/RedundantSortBy:
4465
4499
  Description: 'Use `sort` instead of `sort_by { |x| x }`.'
@@ -4540,6 +4574,12 @@ Style/Sample:
4540
4574
  Enabled: true
4541
4575
  VersionAdded: '0.30'
4542
4576
 
4577
+ Style/SelectByRegexp:
4578
+ Description: 'Prefer grep/grep_v to select/reject with a regexp match.'
4579
+ Enabled: pending
4580
+ SafeAutoCorrect: false
4581
+ VersionAdded: '1.22'
4582
+
4543
4583
  Style/SelfAssignment:
4544
4584
  Description: >-
4545
4585
  Checks for places where self-assignment shorthand should have
@@ -51,6 +51,11 @@ module RuboCop
51
51
  self
52
52
  end
53
53
 
54
+ def validate_after_resolution
55
+ @validator.validate_after_resolution
56
+ self
57
+ end
58
+
54
59
  def_delegators :@hash, :[], :[]=, :delete, :dig, :each, :key?, :keys, :each_key,
55
60
  :fetch, :map, :merge, :replace, :to_h, :to_hash, :transform_values
56
61
  def_delegators :@validator, :validate, :target_ruby_version
@@ -101,6 +101,8 @@ module RuboCop
101
101
  return default_configuration if config_file == DEFAULT_FILE
102
102
 
103
103
  config = load_file(config_file, check: check)
104
+ config.validate_after_resolution if check
105
+
104
106
  if ignore_parent_exclusion?
105
107
  print 'Ignoring AllCops/Exclude from parent folders' if debug?
106
108
  else
@@ -134,7 +136,7 @@ module RuboCop
134
136
  end
135
137
  end
136
138
 
137
- # Returns the path rubocop inferred as the root of the project. No file
139
+ # Returns the path RuboCop inferred as the root of the project. No file
138
140
  # searches will go past this directory.
139
141
  def project_root
140
142
  @project_root ||= find_project_root
@@ -44,7 +44,6 @@ module RuboCop
44
44
  check_obsoletions
45
45
 
46
46
  alert_about_unrecognized_cops(invalid_cop_names)
47
- check_target_ruby
48
47
  validate_new_cops_parameter
49
48
  validate_parameter_names(valid_cop_names)
50
49
  validate_enforced_styles(valid_cop_names)
@@ -52,6 +51,15 @@ module RuboCop
52
51
  reject_mutually_exclusive_defaults
53
52
  end
54
53
 
54
+ # Validations that should only be run after all config resolving has
55
+ # taken place:
56
+ # * The target ruby version is only checked once the entire inheritance
57
+ # chain has been loaded so that only the final value is validated, and
58
+ # any obsolete but overridden values are ignored.
59
+ def validate_after_resolution
60
+ check_target_ruby
61
+ end
62
+
55
63
  def target_ruby_version
56
64
  target_ruby.version
57
65
  end
@@ -24,7 +24,7 @@ module RuboCop
24
24
  # `add_global_offense`. Use the `processed_source` method to
25
25
  # get the currently processed source being investigated.
26
26
  #
27
- # In case of invalid syntax / unparseable content,
27
+ # In case of invalid syntax / unparsable content,
28
28
  # the callback `on_other_file` is called instead of all the other
29
29
  # `on_...` callbacks.
30
30
  #
@@ -88,7 +88,7 @@ module RuboCop
88
88
  CHECKED_OPTIONS_CONFIG = 'OnlyFor'
89
89
  VERSION_SPECIFIERS_OPTION = 'version_specifiers'
90
90
  RESTRICTIVE_VERSION_SPECIFIERS_OPTION = 'restrictive_version_specifiers'
91
- RESTRICTIVE_VERSION_PATTERN = /<|~>/.freeze
91
+ RESTRICTIVE_VERSION_PATTERN = /\A\s*(?:<|~>|\d|=)/.freeze
92
92
  RESTRICT_ON_SEND = %i[gem].freeze
93
93
 
94
94
  def on_send(node)
@@ -152,8 +152,8 @@ module RuboCop
152
152
  def restrictive_version_specified_gem?(node)
153
153
  return unless version_specified_gem?(node)
154
154
 
155
- node.arguments
156
- .any? { |arg| arg&.str_type? && RESTRICTIVE_VERSION_PATTERN.match?(arg.to_s) }
155
+ node.arguments[1..-1]
156
+ .any? { |arg| arg&.str_type? && RESTRICTIVE_VERSION_PATTERN.match?(arg.value) }
157
157
  end
158
158
 
159
159
  def contains_checked_options?(node)
@@ -16,6 +16,9 @@ module RuboCop
16
16
  # However, you should strongly prefer `https://` where possible, as it is
17
17
  # more secure.
18
18
  #
19
+ # If you don't allow `http://`, please set `false` to `AllowHttpProtocol`.
20
+ # This option is `true` by default for safe autocorrection.
21
+ #
19
22
  # @example
20
23
  # # bad
21
24
  # source :gemcutter
@@ -24,8 +27,17 @@ module RuboCop
24
27
  #
25
28
  # # good
26
29
  # source 'https://rubygems.org' # strongly recommended
30
+ #
31
+ # @example AllowHttpProtocol: true (default)
32
+ #
33
+ # # good
27
34
  # source 'http://rubygems.org' # use only if HTTPS is unavailable
28
35
  #
36
+ # @example AllowHttpProtocol: false
37
+ #
38
+ # # bad
39
+ # source 'http://rubygems.org'
40
+ #
29
41
  class InsecureProtocolSource < Base
30
42
  include RangeHelp
31
43
  extend AutoCorrector
@@ -34,29 +46,40 @@ module RuboCop
34
46
  'are insecure. ' \
35
47
  "Please change your source to 'https://rubygems.org' " \
36
48
  "if possible, or 'http://rubygems.org' if not."
49
+ MSG_HTTP_PROTOCOL = 'Use `https://rubygems.org` instead of `http://rubygems.org`.'
37
50
 
38
51
  RESTRICT_ON_SEND = %i[source].freeze
39
52
 
40
53
  # @!method insecure_protocol_source?(node)
41
54
  def_node_matcher :insecure_protocol_source?, <<~PATTERN
42
55
  (send nil? :source
43
- $(sym ${:gemcutter :rubygems :rubyforge}))
56
+ ${(sym :gemcutter) (sym :rubygems) (sym :rubyforge) (:str "http://rubygems.org")})
44
57
  PATTERN
45
58
 
46
59
  def on_send(node)
47
- insecure_protocol_source?(node) do |source_node, source|
48
- message = format(MSG, source: source)
49
-
50
- add_offense(
51
- source_node,
52
- message: message
53
- ) do |corrector|
54
- corrector.replace(
55
- source_node, "'https://rubygems.org'"
56
- )
60
+ insecure_protocol_source?(node) do |source_node|
61
+ source = source_node.value
62
+ use_http_protocol = source == 'http://rubygems.org'
63
+
64
+ return if allow_http_protocol? && use_http_protocol
65
+
66
+ message = if use_http_protocol
67
+ MSG_HTTP_PROTOCOL
68
+ else
69
+ format(MSG, source: source)
70
+ end
71
+
72
+ add_offense(source_node, message: message) do |corrector|
73
+ corrector.replace(source_node, "'https://rubygems.org'")
57
74
  end
58
75
  end
59
76
  end
77
+
78
+ private
79
+
80
+ def allow_http_protocol?
81
+ cop_config.fetch('AllowHttpProtocol', true)
82
+ end
60
83
  end
61
84
  end
62
85
  end
@@ -24,15 +24,15 @@ module RuboCop
24
24
  # gem 'rubocop'
25
25
  # # For tests
26
26
  # gem 'rspec'
27
- class OrderedGems < Cop # rubocop:disable InternalAffairs/InheritDeprecatedCopClass
28
- include ConfigurableEnforcedStyle
27
+ class OrderedGems < Base
28
+ extend AutoCorrector
29
29
  include OrderedGemNode
30
30
 
31
31
  MSG = 'Gems should be sorted in an alphabetical order within their '\
32
32
  'section of the Gemfile. '\
33
33
  'Gem `%<previous>s` should appear before `%<current>s`.'
34
34
 
35
- def investigate(processed_source)
35
+ def on_new_investigation
36
36
  return if processed_source.blank?
37
37
 
38
38
  gem_declarations(processed_source.ast)
@@ -44,15 +44,6 @@ module RuboCop
44
44
  end
45
45
  end
46
46
 
47
- def autocorrect(node)
48
- OrderedGemCorrector.correct(
49
- processed_source,
50
- node,
51
- previous_declaration(node),
52
- treat_comments_as_separators
53
- )
54
- end
55
-
56
47
  private
57
48
 
58
49
  def previous_declaration(node)
@@ -4,9 +4,10 @@ module RuboCop
4
4
  module Cop
5
5
  # This auto-corrects gem dependency order
6
6
  class OrderedGemCorrector
7
- extend OrderedGemNode
8
-
9
7
  class << self
8
+ include OrderedGemNode
9
+ include RangeHelp
10
+
10
11
  attr_reader :processed_source, :comments_as_separators
11
12
 
12
13
  def correct(processed_source, node,
@@ -17,24 +18,24 @@ module RuboCop
17
18
  current_range = declaration_with_comment(node)
18
19
  previous_range = declaration_with_comment(previous_declaration)
19
20
 
20
- ->(corrector) do swap_range(corrector, current_range, previous_range) end
21
+ ->(corrector) { swap_range(corrector, current_range, previous_range) }
21
22
  end
22
23
 
23
24
  private
24
25
 
25
26
  def declaration_with_comment(node)
26
27
  buffer = processed_source.buffer
27
- begin_pos = get_source_range(node, comments_as_separators).begin_pos
28
+ begin_pos = range_by_whole_lines(get_source_range(node, comments_as_separators)).begin_pos
28
29
  end_line = buffer.line_for_position(node.loc.expression.end_pos)
29
- end_pos = buffer.line_range(end_line).end_pos
30
- Parser::Source::Range.new(buffer, begin_pos, end_pos)
30
+ end_pos = range_by_whole_lines(buffer.line_range(end_line),
31
+ include_final_newline: true).end_pos
32
+
33
+ range_between(begin_pos, end_pos)
31
34
  end
32
35
 
33
36
  def swap_range(corrector, range1, range2)
34
- src1 = range1.source
35
- src2 = range2.source
36
- corrector.replace(range1, src2)
37
- corrector.replace(range2, src1)
37
+ corrector.insert_before(range2, range1.source)
38
+ corrector.remove(range1)
38
39
  end
39
40
  end
40
41
  end
@@ -50,15 +50,15 @@ module RuboCop
50
50
  # spec.add_dependency 'rubocop'
51
51
  # # For tests
52
52
  # spec.add_dependency 'rspec'
53
- class OrderedDependencies < Cop # rubocop:disable InternalAffairs/InheritDeprecatedCopClass
54
- include ConfigurableEnforcedStyle
53
+ class OrderedDependencies < Base
54
+ extend AutoCorrector
55
55
  include OrderedGemNode
56
56
 
57
57
  MSG = 'Dependencies should be sorted in an alphabetical order within ' \
58
58
  'their section of the gemspec. '\
59
59
  'Dependency `%<previous>s` should appear before `%<current>s`.'
60
60
 
61
- def investigate(processed_source)
61
+ def on_new_investigation
62
62
  return if processed_source.blank?
63
63
 
64
64
  dependency_declarations(processed_source.ast)
@@ -71,15 +71,6 @@ module RuboCop
71
71
  end
72
72
  end
73
73
 
74
- def autocorrect(node)
75
- OrderedGemCorrector.correct(
76
- processed_source,
77
- node,
78
- previous_declaration(node),
79
- treat_comments_as_separators
80
- )
81
- end
82
-
83
74
  private
84
75
 
85
76
  def previous_declaration(node)
@@ -3,10 +3,11 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Gemspec
6
- # Checks that `required_ruby_version` of gemspec is specified and
7
- # equal to `TargetRubyVersion` of .rubocop.yml.
8
- # Thereby, RuboCop to perform static analysis working on the version
9
- # required by gemspec.
6
+ # Checks that `required_ruby_version` in a gemspec file is set to a valid
7
+ # value (non-blank) and matches `TargetRubyVersion` as set in RuboCop's
8
+ # configuration for the gem.
9
+ #
10
+ # This ensures that RuboCop is using the same Ruby version as the gem.
10
11
  #
11
12
  # @example
12
13
  # # When `TargetRubyVersion` of .rubocop.yml is `2.5`.
@@ -26,6 +27,11 @@ module RuboCop
26
27
  # spec.required_ruby_version = '>= 2.6.0'
27
28
  # end
28
29
  #
30
+ # # bad
31
+ # Gem::Specification.new do |spec|
32
+ # spec.required_ruby_version = ''
33
+ # end
34
+ #
29
35
  # # good
30
36
  # Gem::Specification.new do |spec|
31
37
  # spec.required_ruby_version = '>= 2.5.0'
@@ -42,22 +48,22 @@ module RuboCop
42
48
  # end
43
49
  #
44
50
  # # accepted but not recommended, since
45
- # # Ruby does not really follow semantic versionning
51
+ # # Ruby does not really follow semantic versioning
46
52
  # Gem::Specification.new do |spec|
47
53
  # spec.required_ruby_version = '~> 2.5'
48
54
  # end
49
55
  class RequiredRubyVersion < Base
50
56
  include RangeHelp
51
57
 
52
- NOT_EQUAL_MSG = '`required_ruby_version` (%<required_ruby_version>s, ' \
53
- 'declared in %<gemspec_filename>s) and `TargetRubyVersion` ' \
58
+ RESTRICT_ON_SEND = %i[required_ruby_version=].freeze
59
+ NOT_EQUAL_MSG = '`required_ruby_version` and `TargetRubyVersion` ' \
54
60
  '(%<target_ruby_version>s, which may be specified in ' \
55
61
  '.rubocop.yml) should be equal.'
56
62
  MISSING_MSG = '`required_ruby_version` should be specified.'
57
63
 
58
- # @!method required_ruby_version(node)
59
- def_node_search :required_ruby_version, <<~PATTERN
60
- (send _ :required_ruby_version= $_)
64
+ # @!method required_ruby_version?(node)
65
+ def_node_search :required_ruby_version?, <<~PATTERN
66
+ (send _ :required_ruby_version= _)
61
67
  PATTERN
62
68
 
63
69
  # @!method defined_ruby_version(node)
@@ -66,27 +72,28 @@ module RuboCop
66
72
  (send (const (const nil? :Gem) :Requirement) :new $(str _))}
67
73
  PATTERN
68
74
 
69
- # rubocop:disable Metrics/AbcSize
70
75
  def on_new_investigation
71
- version_def = required_ruby_version(processed_source.ast).first
76
+ add_global_offense(MISSING_MSG) unless required_ruby_version?(processed_source.ast)
77
+ end
72
78
 
73
- if version_def
74
- ruby_version = extract_ruby_version(defined_ruby_version(version_def))
75
- return if !ruby_version || ruby_version == target_ruby_version.to_s
79
+ def on_send(node)
80
+ version_def = node.first_argument
81
+ return if dynamic_version?(version_def)
76
82
 
77
- add_offense(
78
- version_def.loc.expression,
79
- message: not_equal_message(ruby_version, target_ruby_version)
80
- )
81
- else
82
- range = source_range(processed_source.buffer, 1, 0)
83
- add_offense(range, message: MISSING_MSG)
84
- end
83
+ ruby_version = extract_ruby_version(defined_ruby_version(version_def))
84
+ return if ruby_version == target_ruby_version.to_s
85
+
86
+ add_offense(version_def, message: not_equal_message(ruby_version, target_ruby_version))
85
87
  end
86
- # rubocop:enable Metrics/AbcSize
87
88
 
88
89
  private
89
90
 
91
+ def dynamic_version?(node)
92
+ (node.send_type? && !node.receiver) ||
93
+ node.variable? ||
94
+ node.each_descendant(:send, *RuboCop::AST::Node::VARIABLES).any?
95
+ end
96
+
90
97
  def extract_ruby_version(required_ruby_version)
91
98
  return unless required_ruby_version
92
99
 
@@ -24,6 +24,11 @@ module RuboCop
24
24
  # `SupportedStyle` and unique configuration, there needs to be examples.
25
25
  # Examples must have valid Ruby syntax. Do not use upticks.
26
26
  #
27
+ # @safety
28
+ # Delete this section if the cop is not unsafe (`Safe: false` or
29
+ # `SafeAutoCorrect: false`), or use it to explain how the cop is
30
+ # unsafe.
31
+ #
27
32
  # @example EnforcedStyle: bar (default)
28
33
  # # Description of the `bar` style.
29
34
  #
@@ -106,9 +111,8 @@ module RuboCop
106
111
  '[modify] A configuration for the cop is added into ' \
107
112
  '%<configuration_file_path>s.'
108
113
 
109
- def initialize(name, github_user, output: $stdout)
114
+ def initialize(name, output: $stdout)
110
115
  @badge = Badge.parse(name)
111
- @github_user = github_user
112
116
  @output = output
113
117
  return if badge.qualified?
114
118
 
@@ -142,17 +146,19 @@ module RuboCop
142
146
 
143
147
  def todo
144
148
  <<~TODO
145
- Do 3 steps:
146
- 1. Add an entry to the "New features" section in CHANGELOG.md,
147
- e.g. "Add new `#{badge}` cop. ([@#{github_user}][])"
148
- 2. Modify the description of #{badge} in config/default.yml
149
- 3. Implement your new cop in the generated file!
149
+ Do 4 steps:
150
+ 1. Modify the description of #{badge} in config/default.yml
151
+ 2. Implement your new cop in the generated file!
152
+ 3. Commit your new cop with a message such as
153
+ e.g. "Add new `#{badge}` cop."
154
+ 4. Run `bundle exec rake changelog:new` to generate a changelog entry
155
+ for your new cop.
150
156
  TODO
151
157
  end
152
158
 
153
159
  private
154
160
 
155
- attr_reader :badge, :github_user, :output
161
+ attr_reader :badge, :output
156
162
 
157
163
  def write_unless_file_exists(path, contents)
158
164
  if File.exist?(path)