rubocop 1.21.0 → 1.22.3

Sign up to get free protection for your applications and to get access to all the features.
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)