rubocop 1.65.1 → 1.66.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) 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 +8 -4
  6. data/lib/rubocop/config.rb +20 -4
  7. data/lib/rubocop/config_loader_resolver.rb +1 -2
  8. data/lib/rubocop/config_validator.rb +9 -5
  9. data/lib/rubocop/cop/base.rb +4 -0
  10. data/lib/rubocop/cop/correctors/line_break_corrector.rb +2 -0
  11. data/lib/rubocop/cop/documentation.rb +18 -1
  12. data/lib/rubocop/cop/internal_affairs/empty_line_between_expect_offense_and_correction.rb +2 -1
  13. data/lib/rubocop/cop/internal_affairs/undefined_config.rb +11 -1
  14. data/lib/rubocop/cop/layout/block_alignment.rb +30 -12
  15. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +2 -1
  16. data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +8 -3
  17. data/lib/rubocop/cop/layout/first_array_element_indentation.rb +0 -3
  18. data/lib/rubocop/cop/layout/line_length.rb +14 -14
  19. data/lib/rubocop/cop/lint/empty_conditional_body.rb +27 -6
  20. data/lib/rubocop/cop/lint/float_comparison.rb +1 -3
  21. data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +4 -2
  22. data/lib/rubocop/cop/lint/useless_assignment.rb +18 -11
  23. data/lib/rubocop/cop/lint/useless_numeric_operation.rb +77 -0
  24. data/lib/rubocop/cop/lint/void.rb +30 -8
  25. data/lib/rubocop/cop/metrics/block_length.rb +6 -5
  26. data/lib/rubocop/cop/metrics/class_length.rb +6 -5
  27. data/lib/rubocop/cop/metrics/method_length.rb +6 -5
  28. data/lib/rubocop/cop/metrics/module_length.rb +6 -5
  29. data/lib/rubocop/cop/mixin/annotation_comment.rb +0 -2
  30. data/lib/rubocop/cop/mixin/frozen_string_literal.rb +19 -9
  31. data/lib/rubocop/cop/mixin/line_length_help.rb +7 -2
  32. data/lib/rubocop/cop/mixin/string_literals_help.rb +12 -0
  33. data/lib/rubocop/cop/naming/accessor_method_name.rb +5 -0
  34. data/lib/rubocop/cop/naming/predicate_name.rb +1 -1
  35. data/lib/rubocop/cop/style/alias.rb +1 -1
  36. data/lib/rubocop/cop/style/arguments_forwarding.rb +8 -3
  37. data/lib/rubocop/cop/style/empty_else.rb +5 -5
  38. data/lib/rubocop/cop/style/empty_heredoc.rb +1 -14
  39. data/lib/rubocop/cop/style/empty_literal.rb +32 -23
  40. data/lib/rubocop/cop/style/format_string_token.rb +2 -2
  41. data/lib/rubocop/cop/style/guard_clause.rb +2 -0
  42. data/lib/rubocop/cop/style/identical_conditional_branches.rb +1 -1
  43. data/lib/rubocop/cop/style/if_with_semicolon.rb +38 -6
  44. data/lib/rubocop/cop/style/in_pattern_then.rb +6 -2
  45. data/lib/rubocop/cop/style/magic_comment_format.rb +8 -3
  46. data/lib/rubocop/cop/style/map_into_array.rb +11 -2
  47. data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +2 -2
  48. data/lib/rubocop/cop/style/multiple_comparison.rb +3 -11
  49. data/lib/rubocop/cop/style/numeric_predicate.rb +2 -2
  50. data/lib/rubocop/cop/style/one_line_conditional.rb +1 -1
  51. data/lib/rubocop/cop/style/parallel_assignment.rb +5 -4
  52. data/lib/rubocop/cop/style/quoted_symbols.rb +0 -2
  53. data/lib/rubocop/cop/style/redundant_condition.rb +3 -2
  54. data/lib/rubocop/cop/style/redundant_interpolation_unfreeze.rb +46 -0
  55. data/lib/rubocop/cop/style/redundant_regexp_argument.rb +4 -1
  56. data/lib/rubocop/cop/style/safe_navigation.rb +2 -2
  57. data/lib/rubocop/cop/team.rb +6 -2
  58. data/lib/rubocop/formatter/junit_formatter.rb +70 -23
  59. data/lib/rubocop/lockfile.rb +6 -4
  60. data/lib/rubocop/remote_config.rb +5 -1
  61. data/lib/rubocop/result_cache.rb +2 -8
  62. data/lib/rubocop/rspec/shared_contexts.rb +2 -2
  63. data/lib/rubocop/server/cache.rb +1 -1
  64. data/lib/rubocop/target_ruby.rb +7 -3
  65. data/lib/rubocop/version.rb +1 -1
  66. data/lib/rubocop.rb +2 -1
  67. 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.0'
7
7
 
8
8
  MSG = '%<version>s (using %<parser_version>s, ' \
9
9
  'rubocop-ast %<rubocop_ast_version>s, ' \
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.0
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-08-31 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.1
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.1
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.0
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: []