Skip to content

Commit

Permalink
Drop support for Ruby 2.3
Browse files Browse the repository at this point in the history
### Summary

This PR drops support for Ruby 2.3.

It is discussed in #6945.
And this suggestion would mean that RuboCop 1.0 (and pre-release)
requires Ruby 2.4 or higher.

The following is a plan after this PR.
There was a build error report for a dependent jaro_winkler gem.
#5989, #6754, #7447, and #7564. And #7673 was trying to solve it.

After dropping Ruby 2.3, replace jaro_winkler with did_you_mean.
did_you_mean is written in Ruby, so the build error due to native
extensions no longer occur. That change opens as anther PR.

### Other Information

The latest did_you_mean (1.4.0) supports Ruby 2.5 or higher,
so it needs to be confirmed old versions it works with Ruby 2.4.
  • Loading branch information
koic authored and bbatsov committed Apr 12, 2020
1 parent fa9a0c4 commit 5873894
Show file tree
Hide file tree
Showing 53 changed files with 280 additions and 368 deletions.
31 changes: 1 addition & 30 deletions .circleci/config.yml
Expand Up @@ -44,29 +44,6 @@ rubocop_steps: &rubocop_steps
jobs:

# Ruby 2.3
ruby-2.3-spec:
docker:
- image: circleci/ruby:2.3
environment:
<<: *common_env
steps:
*spec_steps
ruby-2.3-ascii_spec:
docker:
- image: circleci/ruby:2.3
environment:
<<: *common_env
steps:
*ascii_spec_steps
ruby-2.3-rubocop:
docker:
- image: circleci/ruby:2.3
environment:
<<: *common_env
steps:
*rubocop_steps

# Ruby 2.4
ruby-2.4-spec:
docker:
Expand Down Expand Up @@ -240,7 +217,7 @@ jobs:
- run:
name: Upload coverage results to Code Climate
command: |
./tmp/cc-test-reporter sum-coverage tmp/codeclimate.*.json --parts 6 --output tmp/codeclimate.total.json
./tmp/cc-test-reporter sum-coverage tmp/codeclimate.*.json --parts 5 --output tmp/codeclimate.total.json
./tmp/cc-test-reporter upload-coverage --input tmp/codeclimate.total.json
# Miscellaneous tasks
Expand All @@ -265,11 +242,6 @@ workflows:
jobs:
- documentation-checks
- cc-setup
- ruby-2.3-spec:
requires:
- cc-setup
- ruby-2.3-ascii_spec
- ruby-2.3-rubocop
- ruby-2.4-spec:
requires:
- cc-setup
Expand Down Expand Up @@ -303,7 +275,6 @@ workflows:

- cc-upload-coverage:
requires:
- ruby-2.3-spec
- ruby-2.4-spec
- ruby-2.5-spec
- ruby-2.6-spec
Expand Down
2 changes: 1 addition & 1 deletion .rubocop.yml
Expand Up @@ -12,7 +12,7 @@ AllCops:
- 'spec/fixtures/**/*'
- 'tmp/**/*'
- '.git/**/*'
TargetRubyVersion: 2.3
TargetRubyVersion: 2.4

Naming/PredicateName:
# Method define macros for dynamically generated method.
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Expand Up @@ -16,6 +16,10 @@
* [#7834](https://github.com/rubocop-hq/rubocop/issues/7834): Fix `Lint/UriRegexp` to register offense with array arguments. ([@tejasbubane][])
* [#7841](https://github.com/rubocop-hq/rubocop/issues/7841): Fix an error for `Style/TrailingCommaInBlockArgs` when lambda literal (`->`) has multiple arguments. ([@koic][])

### Changes

* [#7840](https://github.com/rubocop-hq/rubocop/pull/7840): **(BREAKING)** Drop support for Ruby 2.3. ([@koic][])

## 0.81.0 (2020-04-01)

### New features
Expand Down
2 changes: 1 addition & 1 deletion README.md
Expand Up @@ -73,7 +73,7 @@ You can read a lot more about RuboCop in its [official docs](https://docs.ruboco

RuboCop supports the following Ruby implementations:

* MRI 2.3+
* MRI 2.4+
* JRuby 9.2+

## Team
Expand Down
4 changes: 2 additions & 2 deletions config/default.yml
Expand Up @@ -133,7 +133,7 @@ AllCops:
# followed by the Gemfile.lock or gems.locked file. (Although the Ruby version
# is specified in the Gemfile or gems.rb file, RuboCop reads the final value
# from the lock file.) If the Ruby version is still unresolved, RuboCop will
# use the oldest officially supported Ruby version (currently Ruby 2.3).
# use the oldest officially supported Ruby version (currently Ruby 2.4).
TargetRubyVersion: ~

#################### Bundler ###############################
Expand Down Expand Up @@ -2831,7 +2831,7 @@ Style/FrozenStringLiteralComment:
# `always` will always add the frozen string literal comment to a file
# regardless of the Ruby version or if `freeze` or `<<` are called on a
# string literal. If you run code against multiple versions of Ruby, it is
# possible that this will create errors in Ruby 2.3.0+.
# possible that this will create errors in Ruby 2.4.0+.
- always
# `always_true` will add the frozen string literal comment to a file,
# similarly to the `always` style, but will also change any disabled
Expand Down
10 changes: 5 additions & 5 deletions lib/rubocop/config_loader.rb
Expand Up @@ -79,10 +79,8 @@ def merge(base_hash, derived_hash)
# user's home directory is checked. If there's no .rubocop.yml
# there either, the path to the default file is returned.
def configuration_file_for(target_dir)
find_project_dotfile(target_dir) ||
find_user_dotfile ||
find_user_xdg_config ||
DEFAULT_FILE
find_project_dotfile(target_dir) || find_user_dotfile ||
find_user_xdg_config || DEFAULT_FILE
end

def configuration_from_file(config_file)
Expand Down Expand Up @@ -208,7 +206,9 @@ def existing_configuration(config_file)
def write_config_file(file_name, file_string, rubocop_yml_contents)
File.open(file_name, 'w') do |f|
f.write "inherit_from:#{file_string}\n"
f.write "\n#{rubocop_yml_contents}" if rubocop_yml_contents =~ /\S/
if /\S/.match?(rubocop_yml_contents)
f.write "\n#{rubocop_yml_contents}"
end
end
end

Expand Down
4 changes: 2 additions & 2 deletions lib/rubocop/cop/correctors/alignment_corrector.rb
Expand Up @@ -51,7 +51,7 @@ def autocorrect_line(corrector, line_begin_pos, expr, column_delta,
unless range.resize(1).source == "\n"
corrector.insert_before(range, ' ' * column_delta)
end
elsif range.source =~ /\A[ \t]+\z/
elsif /\A[ \t]+\z/.match?(range.source)
remove(range, corrector)
end
end
Expand Down Expand Up @@ -112,7 +112,7 @@ def remove(range, corrector)
corrector.remove(range)
rescue RuntimeError
range = range_between(range.begin_pos + 1, range.end_pos + 1)
retry if range.source =~ /^ +$/
retry if /^ +$/.match?(range.source)
ensure
$stderr = original_stderr
end
Expand Down
4 changes: 2 additions & 2 deletions lib/rubocop/cop/layout/end_of_line.rb
Expand Up @@ -75,8 +75,8 @@ def offense_message(line)
style
end
case effective_style
when :lf then MSG_DETECTED if line =~ /\r$/
else MSG_MISSING if line !~ /\r$/
when :lf then MSG_DETECTED if /\r$/.match?(line)
else MSG_MISSING unless /\r$/.match?(line)
end
end

Expand Down
26 changes: 16 additions & 10 deletions lib/rubocop/cop/layout/first_array_element_indentation.rb
Expand Up @@ -125,21 +125,15 @@ def check(array_node, left_parenthesis)

def check_right_bracket(right_bracket, left_bracket, left_parenthesis)
# if the right bracket is on the same line as the last value, accept
return if right_bracket.source_line[0...right_bracket.column] =~ /\S/
if /\S/.match?(right_bracket.source_line[0...right_bracket.column])
return
end

expected_column = base_column(left_bracket, left_parenthesis)
@column_delta = expected_column - right_bracket.column
return if @column_delta.zero?

msg = if style == :align_brackets
'Indent the right bracket the same as the left bracket.'
elsif style == :special_inside_parentheses && left_parenthesis
'Indent the right bracket the same as the first position ' \
'after the preceding left parenthesis.'
else
'Indent the right bracket the same as the start of the line' \
' where the left bracket is.'
end
msg = msg(left_parenthesis)
add_offense(right_bracket, location: right_bracket, message: msg)
end

Expand All @@ -161,6 +155,18 @@ def message(base_description)
base_description: base_description
)
end

def msg(left_parenthesis)
if style == :align_brackets
'Indent the right bracket the same as the left bracket.'
elsif style == :special_inside_parentheses && left_parenthesis
'Indent the right bracket the same as the first position ' \
'after the preceding left parenthesis.'
else
'Indent the right bracket the same as the start of the line' \
' where the left bracket is.'
end
end
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion lib/rubocop/cop/layout/first_hash_element_indentation.rb
Expand Up @@ -128,7 +128,7 @@ def check(hash_node, left_parenthesis)

def check_right_brace(right_brace, left_brace, left_parenthesis)
# if the right brace is on the same line as the last value, accept
return if right_brace.source_line[0...right_brace.column] =~ /\S/
return if /\S/.match?(right_brace.source_line[0...right_brace.column])

expected_column = base_column(left_brace, left_parenthesis)
@column_delta = expected_column - right_brace.column
Expand Down
2 changes: 1 addition & 1 deletion lib/rubocop/cop/layout/leading_comment_space.rb
Expand Up @@ -56,7 +56,7 @@ class LeadingCommentSpace < Cop

def investigate(processed_source)
processed_source.each_comment do |comment|
next unless comment.text =~ /\A#+[^#\s=:+-]/
next unless /\A#+[^#\s=:+-]/.match?(comment.text)
next if comment.loc.line == 1 && allowed_on_first_line?(comment)
next if doxygen_comment_style?(comment)
next if gemfile_ruby_comment?(comment)
Expand Down
2 changes: 1 addition & 1 deletion lib/rubocop/cop/layout/line_length.rb
Expand Up @@ -145,7 +145,7 @@ def breakable_range_after_semicolon(semicolon_token)
return nil unless next_range.line == range.line

next_char = next_range.source
return nil if /[\r\n]/ =~ next_char
return nil if /[\r\n]/.match?(next_char)
return nil if next_char == ';'

next_range
Expand Down
2 changes: 1 addition & 1 deletion lib/rubocop/cop/layout/space_around_block_parameters.rb
Expand Up @@ -47,7 +47,7 @@ def autocorrect(target)
else
corrector.insert_after(target, ' ')
end
elsif target.source =~ /^\s+$/
elsif /^\s+$/.match?(target.source)
corrector.remove(target)
else
corrector.insert_after(target, ' ')
Expand Down
2 changes: 1 addition & 1 deletion lib/rubocop/cop/layout/space_around_operators.rb
Expand Up @@ -175,7 +175,7 @@ def offense_message(type, operator, with_space, right_operand)
return if with_space.is?(operator.source)

"Space around operator `#{operator.source}` detected."
elsif with_space.source !~ /^\s.*\s$/
elsif !/^\s.*\s$/.match?(with_space.source)
"Surrounding space missing for operator `#{operator.source}`."
elsif excess_leading_space?(type, operator, with_space) ||
excess_trailing_space?(right_operand, with_space)
Expand Down
4 changes: 2 additions & 2 deletions lib/rubocop/cop/layout/space_inside_block_braces.rb
Expand Up @@ -117,7 +117,7 @@ def check_inside(node, left_brace, right_brace)
range = range_between(left_brace.end_pos, right_brace.begin_pos)
inner = range.source

if inner =~ /\S/
if /\S/.match?(inner)
braces_with_contents_inside(node, inner)
elsif style_for_empty_braces == :no_space
offense(range.begin_pos, range.end_pos,
Expand All @@ -142,7 +142,7 @@ def braces_with_contents_inside(node, inner)
end

def check_left_brace(inner, left_brace, args_delimiter)
if inner =~ /\A\S/
if /\A\S/.match?(inner)
no_space_inside_left_brace(left_brace, args_delimiter)
else
space_inside_left_brace(left_brace, args_delimiter)
Expand Down
2 changes: 1 addition & 1 deletion lib/rubocop/cop/layout/space_inside_range_literal.rb
Expand Up @@ -53,7 +53,7 @@ def check(node)
# account for multiline range literals
expression.sub!(/#{escaped_op}\n\s*/, op)

return unless expression =~ /(\s#{escaped_op})|(#{escaped_op}\s)/
return unless /(\s#{escaped_op})|(#{escaped_op}\s)/.match?(expression)

add_offense(node)
end
Expand Down
2 changes: 1 addition & 1 deletion lib/rubocop/cop/lint/debugger.rb
Expand Up @@ -69,7 +69,7 @@ def message(node)
end

def binding_irb?(node)
target_ruby_version >= 2.4 && binding_irb_call?(node)
binding_irb_call?(node)
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion lib/rubocop/cop/lint/implicit_string_concatenation.rb
Expand Up @@ -81,7 +81,7 @@ def string_literals?(node1, node2)
end

def display_str(node)
if node.source =~ /\n/
if /\n/.match?(node.source)
str_content(node).inspect
else
node.source
Expand Down
2 changes: 1 addition & 1 deletion lib/rubocop/cop/lint/interpolation_check.rb
Expand Up @@ -25,7 +25,7 @@ def on_str(node)

parent = node.parent
return if parent && (parent.dstr_type? || parent.regexp_type?)
return unless node.source.scrub =~ /(?<!\\)#\{.*\}/
return unless /(?<!\\)#\{.*\}/.match?(node.source.scrub)

add_offense(node)
end
Expand Down
2 changes: 1 addition & 1 deletion lib/rubocop/cop/lint/percent_string_array.rb
Expand Up @@ -48,7 +48,7 @@ def autocorrect(node)
match = range.source.match(TRAILING_QUOTE)
corrector.remove_trailing(range, match[0].length) if match

if range.source =~ LEADING_QUOTE
if LEADING_QUOTE.match?(range.source)
corrector.remove_leading(range, 1)
end
end
Expand Down
2 changes: 0 additions & 2 deletions lib/rubocop/cop/lint/unified_integer.rb
Expand Up @@ -33,8 +33,6 @@ def on_const(node)
end

def autocorrect(node)
return false if target_ruby_version <= 2.3

lambda do |corrector|
corrector.replace(node.loc.name, 'Integer')
end
Expand Down
2 changes: 1 addition & 1 deletion lib/rubocop/cop/mixin/trailing_comma.rb
Expand Up @@ -135,7 +135,7 @@ def on_same_line?(range1, range2)

def avoid_comma(kind, comma_begin_pos, extra_info)
range = range_between(comma_begin_pos, comma_begin_pos + 1)
article = kind =~ /array/ ? 'an' : 'a'
article = /array/.match?(kind) ? 'an' : 'a'
msg = format(
MSG,
command: 'Avoid',
Expand Down
2 changes: 1 addition & 1 deletion lib/rubocop/cop/naming/class_and_module_camel_case.rb
Expand Up @@ -22,7 +22,7 @@ class ClassAndModuleCamelCase < Cop
MSG = 'Use CamelCase for classes and modules.'

def on_class(node)
return unless node.loc.name.source =~ /_/
return unless /_/.match?(node.loc.name.source)

add_offense(node, location: :name)
end
Expand Down
3 changes: 2 additions & 1 deletion lib/rubocop/cop/naming/constant_name.rb
Expand Up @@ -45,8 +45,9 @@ def on_casgn(node)
# SomeClass = Class.new(...)
# SomeClass = Struct.new(...)
return if allowed_assignment?(value)
return if SNAKE_CASE.match?(const_name)

add_offense(node, location: :name) if const_name !~ SNAKE_CASE
add_offense(node, location: :name)
end

private
Expand Down
2 changes: 1 addition & 1 deletion lib/rubocop/cop/naming/heredoc_delimiter_naming.rb
Expand Up @@ -39,7 +39,7 @@ def on_heredoc(node)
def meaningful_delimiters?(node)
delimiters = delimiter_string(node)

return false unless delimiters =~ /\w/
return false unless /\w/.match?(delimiters)

forbidden_delimiters.none? do |forbidden_delimiter|
delimiters =~ Regexp.new(forbidden_delimiter)
Expand Down
2 changes: 1 addition & 1 deletion lib/rubocop/cop/style/and_or.rb
Expand Up @@ -136,7 +136,7 @@ def whitespace_before_arg(node)
end_paren = begin_paren
# Increment position of parenthesis, unless message is a predicate
# method followed by a non-whitespace char (e.g. is_a?String).
end_paren += 1 unless node.source =~ /\?\S/
end_paren += 1 unless /\?\S/.match?(node.source)
range_between(begin_paren, end_paren)
end
end
Expand Down
2 changes: 1 addition & 1 deletion lib/rubocop/cop/style/copyright.rb
Expand Up @@ -55,7 +55,7 @@ def verify_autocorrect_notice!
raise Warning, AUTOCORRECT_EMPTY_WARNING if autocorrect_notice.empty?

regex = Regexp.new(notice)
return if autocorrect_notice =~ regex
return if autocorrect_notice&.match?(regex)

raise Warning, "AutocorrectNotice '#{autocorrect_notice}' must " \
"match Notice /#{notice}/"
Expand Down
8 changes: 4 additions & 4 deletions lib/rubocop/cop/style/exponential_notation.rb
Expand Up @@ -74,11 +74,11 @@ def scientific?(node)

def engineering?(node)
mantissa, exponent = node.source.split('e')
return false unless exponent =~ /^-?\d+$/
return false unless /^-?\d+$/.match?(exponent)
return false unless (exponent.to_i % 3).zero?
return false if mantissa =~ /^-?\d{4}/
return false if mantissa =~ /^-?0\d/
return false if mantissa =~ /^-?0.0/
return false if /^-?\d{4}/.match?(mantissa)
return false if /^-?0\d/.match?(mantissa)
return false if /^-?0.0/.match?(mantissa)

true
end
Expand Down

0 comments on commit 5873894

Please sign in to comment.