rubocop 1.65.1 → 1.66.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 (70) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +67 -67
  3. data/config/default.yml +18 -2
  4. data/exe/rubocop +4 -3
  5. data/lib/rubocop/comment_config.rb +1 -1
  6. data/lib/rubocop/config.rb +5 -1
  7. data/lib/rubocop/config_loader.rb +14 -8
  8. data/lib/rubocop/config_loader_resolver.rb +1 -2
  9. data/lib/rubocop/config_validator.rb +1 -1
  10. data/lib/rubocop/cop/base.rb +4 -0
  11. data/lib/rubocop/cop/correctors/line_break_corrector.rb +2 -0
  12. data/lib/rubocop/cop/documentation.rb +18 -1
  13. data/lib/rubocop/cop/internal_affairs/empty_line_between_expect_offense_and_correction.rb +2 -1
  14. data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +1 -1
  15. data/lib/rubocop/cop/internal_affairs/undefined_config.rb +11 -1
  16. data/lib/rubocop/cop/layout/block_alignment.rb +30 -12
  17. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +2 -1
  18. data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +8 -3
  19. data/lib/rubocop/cop/layout/first_array_element_indentation.rb +0 -3
  20. data/lib/rubocop/cop/layout/line_length.rb +14 -14
  21. data/lib/rubocop/cop/lint/empty_conditional_body.rb +27 -6
  22. data/lib/rubocop/cop/lint/float_comparison.rb +1 -3
  23. data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +4 -2
  24. data/lib/rubocop/cop/lint/useless_assignment.rb +18 -11
  25. data/lib/rubocop/cop/lint/useless_numeric_operation.rb +77 -0
  26. data/lib/rubocop/cop/lint/void.rb +30 -8
  27. data/lib/rubocop/cop/metrics/block_length.rb +6 -5
  28. data/lib/rubocop/cop/metrics/class_length.rb +6 -5
  29. data/lib/rubocop/cop/metrics/method_length.rb +6 -5
  30. data/lib/rubocop/cop/metrics/module_length.rb +6 -5
  31. data/lib/rubocop/cop/mixin/annotation_comment.rb +0 -2
  32. data/lib/rubocop/cop/mixin/frozen_string_literal.rb +19 -9
  33. data/lib/rubocop/cop/mixin/line_length_help.rb +7 -2
  34. data/lib/rubocop/cop/mixin/string_literals_help.rb +12 -0
  35. data/lib/rubocop/cop/naming/accessor_method_name.rb +5 -0
  36. data/lib/rubocop/cop/naming/predicate_name.rb +1 -1
  37. data/lib/rubocop/cop/style/alias.rb +1 -1
  38. data/lib/rubocop/cop/style/arguments_forwarding.rb +8 -3
  39. data/lib/rubocop/cop/style/empty_else.rb +6 -5
  40. data/lib/rubocop/cop/style/empty_heredoc.rb +1 -14
  41. data/lib/rubocop/cop/style/empty_literal.rb +31 -22
  42. data/lib/rubocop/cop/style/format_string_token.rb +2 -2
  43. data/lib/rubocop/cop/style/guard_clause.rb +2 -0
  44. data/lib/rubocop/cop/style/identical_conditional_branches.rb +1 -1
  45. data/lib/rubocop/cop/style/if_with_semicolon.rb +45 -6
  46. data/lib/rubocop/cop/style/in_pattern_then.rb +6 -2
  47. data/lib/rubocop/cop/style/magic_comment_format.rb +1 -1
  48. data/lib/rubocop/cop/style/map_into_array.rb +12 -5
  49. data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +2 -2
  50. data/lib/rubocop/cop/style/multiple_comparison.rb +3 -11
  51. data/lib/rubocop/cop/style/numeric_predicate.rb +2 -2
  52. data/lib/rubocop/cop/style/one_line_conditional.rb +1 -1
  53. data/lib/rubocop/cop/style/parallel_assignment.rb +5 -4
  54. data/lib/rubocop/cop/style/quoted_symbols.rb +0 -2
  55. data/lib/rubocop/cop/style/redundant_condition.rb +3 -2
  56. data/lib/rubocop/cop/style/redundant_interpolation_unfreeze.rb +46 -0
  57. data/lib/rubocop/cop/style/redundant_regexp_argument.rb +4 -1
  58. data/lib/rubocop/cop/style/safe_navigation.rb +2 -2
  59. data/lib/rubocop/cop/team.rb +6 -2
  60. data/lib/rubocop/formatter/junit_formatter.rb +70 -23
  61. data/lib/rubocop/lockfile.rb +6 -4
  62. data/lib/rubocop/remote_config.rb +5 -1
  63. data/lib/rubocop/result_cache.rb +2 -8
  64. data/lib/rubocop/rspec/shared_contexts.rb +2 -2
  65. data/lib/rubocop/server/cache.rb +1 -1
  66. data/lib/rubocop/target_ruby.rb +7 -3
  67. data/lib/rubocop/version.rb +1 -1
  68. data/lib/rubocop/yaml_duplication_checker.rb +1 -0
  69. data/lib/rubocop.rb +2 -1
  70. metadata +12 -30
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'rexml/document'
4
-
5
3
  #
6
4
  # This code is based on https://github.com/mikian/rubocop-junit-formatter.
7
5
  #
@@ -15,13 +13,18 @@ module RuboCop
15
13
  module Formatter
16
14
  # This formatter formats the report data in JUnit format.
17
15
  class JUnitFormatter < BaseFormatter
16
+ ESCAPE_MAP = {
17
+ '"' => '&quot;',
18
+ "'" => '&apos;',
19
+ '<' => '&lt;',
20
+ '>' => '&gt;',
21
+ '&' => '&amp;'
22
+ }.freeze
23
+
18
24
  def initialize(output, options = {})
19
25
  super
20
26
 
21
- @document = REXML::Document.new.tap { |document| document << REXML::XMLDecl.new }
22
- testsuites = REXML::Element.new('testsuites', @document)
23
- testsuite = REXML::Element.new('testsuite', testsuites)
24
- @testsuite = testsuite.tap { |element| element.add_attributes('name' => 'rubocop') }
27
+ @test_case_elements = []
25
28
 
26
29
  reset_count
27
30
  end
@@ -44,6 +47,33 @@ module RuboCop
44
47
  end
45
48
  end
46
49
 
50
+ # rubocop:disable Layout/LineLength,Metrics/AbcSize,Metrics/MethodLength
51
+ def finished(_inspected_files)
52
+ output.puts %(<?xml version='1.0'?>)
53
+ output.puts %(<testsuites>)
54
+ output.puts %( <testsuite name='rubocop' tests='#{@inspected_file_count}' failures='#{@offense_count}'>)
55
+
56
+ @test_case_elements.each do |test_case_element|
57
+ if test_case_element.failures.empty?
58
+ output.puts %( <testcase classname='#{xml_escape test_case_element.classname}' name='#{test_case_element.name}'/>)
59
+ else
60
+ output.puts %( <testcase classname='#{xml_escape test_case_element.classname}' name='#{test_case_element.name}'>)
61
+ test_case_element.failures.each do |failure_element|
62
+ output.puts %( <failure type='#{failure_element.type}' message='#{xml_escape failure_element.message}'>)
63
+ output.puts %( #{xml_escape failure_element.text})
64
+ output.puts %( </failure>)
65
+ end
66
+ output.puts %( </testcase>)
67
+ end
68
+ end
69
+
70
+ output.puts %( </testsuite>)
71
+ output.puts %(</testsuites>)
72
+ end
73
+ # rubocop:enable Layout/LineLength,Metrics/AbcSize,Metrics/MethodLength
74
+
75
+ private
76
+
47
77
  def relevant_for_output?(options, target_offenses)
48
78
  !options[:display_only_failed] || target_offenses.any?
49
79
  end
@@ -53,11 +83,11 @@ module RuboCop
53
83
  end
54
84
 
55
85
  def add_testcase_element_to_testsuite_element(file, target_offenses, cop)
56
- REXML::Element.new('testcase', @testsuite).tap do |testcase|
57
- testcase.attributes['classname'] = classname_attribute_value(file)
58
- testcase.attributes['name'] = cop.cop_name
59
-
60
- add_failure_to(testcase, target_offenses, cop.cop_name)
86
+ @test_case_elements << TestCaseElement.new(
87
+ classname: classname_attribute_value(file),
88
+ name: cop.cop_name
89
+ ).tap do |test_case_element|
90
+ add_failure_to(test_case_element, target_offenses, cop.cop_name)
61
91
  end
62
92
  end
63
93
 
@@ -68,13 +98,6 @@ module RuboCop
68
98
  @classname_attribute_value_cache[file]
69
99
  end
70
100
 
71
- def finished(_inspected_files)
72
- @testsuite.add_attributes('tests' => @inspected_file_count, 'failures' => @offense_count)
73
- @document.write(output, 2)
74
- end
75
-
76
- private
77
-
78
101
  def reset_count
79
102
  @inspected_file_count = 0
80
103
  @offense_count = 0
@@ -84,11 +107,35 @@ module RuboCop
84
107
  # One failure per offense. Zero failures is a passing test case,
85
108
  # for most surefire/nUnit parsers.
86
109
  offenses.each do |offense|
87
- REXML::Element.new('failure', testcase).tap do |failure|
88
- failure.attributes['type'] = cop_name
89
- failure.attributes['message'] = offense.message
90
- failure.add_text(offense.location.to_s)
91
- end
110
+ testcase.failures << FailureElement.new(
111
+ type: cop_name,
112
+ message: offense.message,
113
+ text: offense.location.to_s
114
+ )
115
+ end
116
+ end
117
+
118
+ def xml_escape(string)
119
+ string.gsub(Regexp.union(ESCAPE_MAP.keys), ESCAPE_MAP)
120
+ end
121
+
122
+ class TestCaseElement # :nodoc:
123
+ attr_reader :classname, :name, :failures
124
+
125
+ def initialize(classname:, name:)
126
+ @classname = classname
127
+ @name = name
128
+ @failures = []
129
+ end
130
+ end
131
+
132
+ class FailureElement # :nodoc:
133
+ attr_reader :type, :message, :text
134
+
135
+ def initialize(type:, message:, text:)
136
+ @type = type
137
+ @message = message
138
+ @text = text
92
139
  end
93
140
  end
94
141
  end
@@ -16,7 +16,7 @@ module RuboCop
16
16
  # @param [String, Pathname, nil] lockfile_path
17
17
  def initialize(lockfile_path = nil)
18
18
  lockfile_path ||= begin
19
- ::Bundler.default_lockfile if bundler_lock_parser_defined?
19
+ ::Bundler.default_lockfile if use_bundler_lock_parser?
20
20
  rescue ::Bundler::GemfileNotFound
21
21
  nil # We might not be a folder with a Gemfile, but that's okay.
22
22
  end
@@ -72,7 +72,7 @@ module RuboCop
72
72
  def parser
73
73
  return @parser if defined?(@parser)
74
74
 
75
- @parser = if @lockfile_path && File.exist?(@lockfile_path) && bundler_lock_parser_defined?
75
+ @parser = if @lockfile_path && File.exist?(@lockfile_path) && use_bundler_lock_parser?
76
76
  begin
77
77
  lockfile = ::Bundler.read_file(@lockfile_path)
78
78
  ::Bundler::LockfileParser.new(lockfile) if lockfile
@@ -82,8 +82,10 @@ module RuboCop
82
82
  end
83
83
  end
84
84
 
85
- def bundler_lock_parser_defined?
86
- Object.const_defined?(:Bundler) && Bundler.const_defined?(:LockfileParser)
85
+ def use_bundler_lock_parser?
86
+ return false unless Object.const_defined?(:Bundler)
87
+
88
+ Bundler.const_defined?(:LockfileParser) && Bundler::VERSION >= '2.0'
87
89
  end
88
90
  end
89
91
  end
@@ -12,7 +12,11 @@ module RuboCop
12
12
  CACHE_LIFETIME = 24 * 60 * 60
13
13
 
14
14
  def initialize(url, base_dir)
15
- @uri = URI.parse(url)
15
+ begin
16
+ @uri = URI.parse(url)
17
+ rescue URI::InvalidURIError
18
+ raise ConfigNotFoundError, "Failed to resolve configuration: '#{url}' is not a valid URI"
19
+ end
16
20
  @base_dir = base_dir
17
21
  end
18
22
 
@@ -222,19 +222,13 @@ module RuboCop
222
222
  options.to_s.gsub(/[^a-z]+/i, '_')
223
223
  end
224
224
 
225
- # The external dependency checksums are cached per RuboCop team so that
226
- # the checksums don't need to be recomputed for each file.
227
- def team_checksum(team)
228
- @checksum_by_team ||= {}.compare_by_identity
229
- @checksum_by_team[team] ||= team.external_dependency_checksum
230
- end
231
-
232
225
  # We combine team and options into a single "context" checksum to avoid
233
226
  # making file names that are too long for some filesystems to handle.
234
227
  # This context is for anything that's not (1) the RuboCop executable
235
228
  # checksum or (2) the inspected file checksum.
236
229
  def context_checksum(team, options)
237
- Digest::SHA1.hexdigest([team_checksum(team), relevant_options_digest(options)].join)
230
+ keys = [team.external_dependency_checksum, relevant_options_digest(options)]
231
+ Digest::SHA1.hexdigest(keys.join)
238
232
  end
239
233
  end
240
234
  end
@@ -86,9 +86,9 @@ RSpec.shared_context 'config' do # rubocop:disable Metrics/BlockLength
86
86
 
87
87
  let(:cop_class) do
88
88
  unless described_class.is_a?(Class) && described_class < RuboCop::Cop::Base
89
- raise 'Specify which cop class to use (e.g `let(:cop_class) { RuboCop::Cop::Base }`, ' \
90
- 'or RuboCop::Cop::Cop for legacy)'
89
+ raise 'Specify which cop class to use (e.g `let(:cop_class) { RuboCop::Cop::Base }`)'
91
90
  end
91
+
92
92
  described_class
93
93
  end
94
94
 
@@ -126,7 +126,7 @@ module RuboCop
126
126
 
127
127
  def pid_running?
128
128
  Process.kill(0, pid_path.read.to_i) == 1
129
- rescue Errno::ESRCH, Errno::ENOENT, Errno::EACCES, Errno::EROFS
129
+ rescue Errno::ESRCH, Errno::ENOENT, Errno::EACCES, Errno::EROFS, Errno::ENAMETOOLONG
130
130
  false
131
131
  end
132
132
 
@@ -80,7 +80,7 @@ module RuboCop
80
80
  right_hand_side = version_from_gemspec_file(file)
81
81
  return if right_hand_side.nil?
82
82
 
83
- find_default_minimal_known_ruby(right_hand_side)
83
+ find_minimal_known_ruby(right_hand_side)
84
84
  end
85
85
 
86
86
  def gemspec_filename
@@ -99,6 +99,8 @@ module RuboCop
99
99
  processed_source = ProcessedSource.from_file(
100
100
  file, DEFAULT_VERSION, parser_engine: @config.parser_engine
101
101
  )
102
+ return unless processed_source.valid_syntax?
103
+
102
104
  required_ruby_version(processed_source.ast).first
103
105
  end
104
106
 
@@ -118,12 +120,14 @@ module RuboCop
118
120
  array.children.map(&:value)
119
121
  end
120
122
 
121
- def find_default_minimal_known_ruby(right_hand_side)
123
+ def find_minimal_known_ruby(right_hand_side)
122
124
  version = version_from_right_hand_side(right_hand_side)
125
+ return unless version
126
+
123
127
  requirement = Gem::Requirement.new(version)
124
128
 
125
129
  KNOWN_RUBIES.detect do |v|
126
- v >= DEFAULT_VERSION && requirement.satisfied_by?(Gem::Version.new("#{v}.99"))
130
+ requirement.satisfied_by?(Gem::Version.new("#{v}.99"))
127
131
  end
128
132
  end
129
133
  end
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  # This module holds the RuboCop version information.
5
5
  module Version
6
- STRING = '1.65.1'
6
+ STRING = '1.66.1'
7
7
 
8
8
  MSG = '%<version>s (using %<parser_version>s, ' \
9
9
  'rubocop-ast %<rubocop_ast_version>s, ' \
@@ -16,6 +16,7 @@ module RuboCop
16
16
  return unless tree
17
17
 
18
18
  traverse(tree, &on_duplicated)
19
+ tree
19
20
  end
20
21
 
21
22
  def self.traverse(tree, &on_duplicated)
data/lib/rubocop.rb CHANGED
@@ -9,7 +9,6 @@ require 'fileutils'
9
9
  before_us = $LOADED_FEATURES.dup
10
10
  require 'rainbow'
11
11
 
12
- require 'forwardable'
13
12
  require 'regexp_parser'
14
13
  require 'set'
15
14
  require 'unicode/display_width'
@@ -416,6 +415,7 @@ require_relative 'rubocop/cop/lint/useless_access_modifier'
416
415
  require_relative 'rubocop/cop/lint/useless_assignment'
417
416
  require_relative 'rubocop/cop/lint/useless_else_without_rescue'
418
417
  require_relative 'rubocop/cop/lint/useless_method_definition'
418
+ require_relative 'rubocop/cop/lint/useless_numeric_operation'
419
419
  require_relative 'rubocop/cop/lint/useless_rescue'
420
420
  require_relative 'rubocop/cop/lint/useless_ruby2_keywords'
421
421
  require_relative 'rubocop/cop/lint/useless_setter_call'
@@ -584,6 +584,7 @@ require_relative 'rubocop/cop/style/redundant_file_extension_in_require'
584
584
  require_relative 'rubocop/cop/style/redundant_filter_chain'
585
585
  require_relative 'rubocop/cop/style/redundant_heredoc_delimiter_quotes'
586
586
  require_relative 'rubocop/cop/style/redundant_initialize'
587
+ require_relative 'rubocop/cop/style/redundant_interpolation_unfreeze'
587
588
  require_relative 'rubocop/cop/style/redundant_line_continuation'
588
589
  require_relative 'rubocop/cop/style/redundant_regexp_argument'
589
590
  require_relative 'rubocop/cop/style/redundant_regexp_constructor'
metadata CHANGED
@@ -1,16 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubocop
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.65.1
4
+ version: 1.66.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bozhidar Batsov
8
8
  - Jonas Arvidsson
9
9
  - Yuji Nakayama
10
- autorequire:
10
+ autorequire:
11
11
  bindir: exe
12
12
  cert_chain: []
13
- date: 2024-08-01 00:00:00.000000000 Z
13
+ date: 2024-09-04 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: json
@@ -108,33 +108,13 @@ dependencies:
108
108
  - - "<"
109
109
  - !ruby/object:Gem::Version
110
110
  version: '3.0'
111
- - !ruby/object:Gem::Dependency
112
- name: rexml
113
- requirement: !ruby/object:Gem::Requirement
114
- requirements:
115
- - - ">="
116
- - !ruby/object:Gem::Version
117
- version: 3.2.5
118
- - - "<"
119
- - !ruby/object:Gem::Version
120
- version: '4.0'
121
- type: :runtime
122
- prerelease: false
123
- version_requirements: !ruby/object:Gem::Requirement
124
- requirements:
125
- - - ">="
126
- - !ruby/object:Gem::Version
127
- version: 3.2.5
128
- - - "<"
129
- - !ruby/object:Gem::Version
130
- version: '4.0'
131
111
  - !ruby/object:Gem::Dependency
132
112
  name: rubocop-ast
133
113
  requirement: !ruby/object:Gem::Requirement
134
114
  requirements:
135
115
  - - ">="
136
116
  - !ruby/object:Gem::Version
137
- version: 1.31.1
117
+ version: 1.32.2
138
118
  - - "<"
139
119
  - !ruby/object:Gem::Version
140
120
  version: '2.0'
@@ -144,7 +124,7 @@ dependencies:
144
124
  requirements:
145
125
  - - ">="
146
126
  - !ruby/object:Gem::Version
147
- version: 1.31.1
127
+ version: 1.32.2
148
128
  - - "<"
149
129
  - !ruby/object:Gem::Version
150
130
  version: '2.0'
@@ -548,6 +528,7 @@ files:
548
528
  - lib/rubocop/cop/lint/useless_assignment.rb
549
529
  - lib/rubocop/cop/lint/useless_else_without_rescue.rb
550
530
  - lib/rubocop/cop/lint/useless_method_definition.rb
531
+ - lib/rubocop/cop/lint/useless_numeric_operation.rb
551
532
  - lib/rubocop/cop/lint/useless_rescue.rb
552
533
  - lib/rubocop/cop/lint/useless_ruby2_keywords.rb
553
534
  - lib/rubocop/cop/lint/useless_setter_call.rb
@@ -860,6 +841,7 @@ files:
860
841
  - lib/rubocop/cop/style/redundant_heredoc_delimiter_quotes.rb
861
842
  - lib/rubocop/cop/style/redundant_initialize.rb
862
843
  - lib/rubocop/cop/style/redundant_interpolation.rb
844
+ - lib/rubocop/cop/style/redundant_interpolation_unfreeze.rb
863
845
  - lib/rubocop/cop/style/redundant_line_continuation.rb
864
846
  - lib/rubocop/cop/style/redundant_parentheses.rb
865
847
  - lib/rubocop/cop/style/redundant_percent_q.rb
@@ -1035,12 +1017,12 @@ licenses:
1035
1017
  - MIT
1036
1018
  metadata:
1037
1019
  homepage_uri: https://rubocop.org/
1038
- changelog_uri: https://github.com/rubocop/rubocop/releases/tag/v1.65.1
1020
+ changelog_uri: https://github.com/rubocop/rubocop/releases/tag/v1.66.1
1039
1021
  source_code_uri: https://github.com/rubocop/rubocop/
1040
- documentation_uri: https://docs.rubocop.org/rubocop/1.65/
1022
+ documentation_uri: https://docs.rubocop.org/rubocop/1.66/
1041
1023
  bug_tracker_uri: https://github.com/rubocop/rubocop/issues
1042
1024
  rubygems_mfa_required: 'true'
1043
- post_install_message:
1025
+ post_install_message:
1044
1026
  rdoc_options: []
1045
1027
  require_paths:
1046
1028
  - lib
@@ -1055,8 +1037,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
1055
1037
  - !ruby/object:Gem::Version
1056
1038
  version: '0'
1057
1039
  requirements: []
1058
- rubygems_version: 3.3.7
1059
- signing_key:
1040
+ rubygems_version: 3.4.22
1041
+ signing_key:
1060
1042
  specification_version: 4
1061
1043
  summary: Automatic Ruby code style checking tool.
1062
1044
  test_files: []