Skip to content

Commit

Permalink
Merge pull request #8310 from eugeneius/required_major_ruby_version
Browse files Browse the repository at this point in the history
Handle major version requirements in Gemspec/RequiredRubyVersion
  • Loading branch information
koic committed Jul 12, 2020
2 parents 19d534c + 6fc2461 commit eda147e
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 9 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -20,6 +20,7 @@
* [#7776](https://github.com/rubocop-hq/rubocop/issues/7776): Fix crash for `Layout/MultilineMethodCallBraceLayout` when comment is present before closing braces. ([@shekhar-patil][])
* [#8282](https://github.com/rubocop-hq/rubocop/issues/8282): Fix `Style/IfUnlessModifier` bad precedence detection. ([@tejasbubane][])
* [#8289](https://github.com/rubocop-hq/rubocop/issues/8289): Fix `Style/AccessorGrouping` to not register offense for accessor with comment. ([@tejasbubane][])
* [#8310](https://github.com/rubocop-hq/rubocop/pull/8310): Handle major version requirements in `Gemspec/RequiredRubyVersion`. ([@eugeneius][])

### Changes

Expand Down
5 changes: 5 additions & 0 deletions docs/modules/ROOT/pages/cops_gemspec.adoc
Expand Up @@ -187,6 +187,11 @@ end
Gem::Specification.new do |spec|
spec.required_ruby_version = ['>= 2.5.0', '< 2.7.0']
end
# good
Gem::Specification.new do |spec|
spec.required_ruby_version = '~> 2.5'
end
----

=== Configurable attributes
Expand Down
7 changes: 6 additions & 1 deletion lib/rubocop/cop/gemspec/required_ruby_version.rb
Expand Up @@ -35,6 +35,11 @@ module Gemspec
# Gem::Specification.new do |spec|
# spec.required_ruby_version = ['>= 2.5.0', '< 2.7.0']
# end
#
# # good
# Gem::Specification.new do |spec|
# spec.required_ruby_version = '~> 2.5'
# end
class RequiredRubyVersion < Cop
MSG = '`required_ruby_version` (%<required_ruby_version>s, ' \
'declared in %<gemspec_filename>s) and `TargetRubyVersion` ' \
Expand Down Expand Up @@ -68,7 +73,7 @@ def extract_ruby_version(required_ruby_version)
end
end

required_ruby_version.str_content.match(/(\d\.\d)/)[1]
required_ruby_version.str_content.scan(/\d/).first(2).join('.')
end

def message(required_ruby_version, target_ruby_version)
Expand Down
68 changes: 60 additions & 8 deletions spec/rubocop/cop/gemspec/required_ruby_version_spec.rb
Expand Up @@ -2,8 +2,7 @@

RSpec.describe RuboCop::Cop::Gemspec::RequiredRubyVersion, :config do
context 'target ruby version > 2.7', :ruby27 do
it 'registers an offense when `required_ruby_version` is lower than ' \
'`TargetRubyVersion`' do
it 'registers an offense when `required_ruby_version` is specified with >= and is lower than `TargetRubyVersion`' do
expect_offense(<<~RUBY, '/path/to/foo.gemspec')
Gem::Specification.new do |spec|
spec.required_ruby_version = '>= 2.6.0'
Expand All @@ -12,6 +11,15 @@
RUBY
end

it 'registers an offense when `required_ruby_version` is specified with ~> and is lower than `TargetRubyVersion`' do
expect_offense(<<~RUBY, '/path/to/foo.gemspec')
Gem::Specification.new do |spec|
spec.required_ruby_version = '~> 2.6.0'
^^^^^^^^^^ `required_ruby_version` (2.6, declared in foo.gemspec) and `TargetRubyVersion` (2.7, which may be specified in .rubocop.yml) should be equal.
end
RUBY
end

describe 'false negatives' do
it 'does not register an offense when `required_ruby_version` ' \
'is assigned as a variable (string literal)' do
Expand All @@ -37,36 +45,60 @@
end

context 'target ruby version > 2.5', :ruby25 do
it 'registers an offense when `required_ruby_version` is higher than ' \
'`TargetRubyVersion`' do
it 'registers an offense when `required_ruby_version` is specified with >= and is higher than `TargetRubyVersion`' do
expect_offense(<<~RUBY, '/path/to/bar.gemspec')
Gem::Specification.new do |spec|
spec.required_ruby_version = '>= 2.6.0'
^^^^^^^^^^ `required_ruby_version` (2.6, declared in bar.gemspec) and `TargetRubyVersion` (2.5, which may be specified in .rubocop.yml) should be equal.
end
RUBY
end

it 'registers an offense when `required_ruby_version` is specified with ~> and is higher than `TargetRubyVersion`' do
expect_offense(<<~RUBY, '/path/to/bar.gemspec')
Gem::Specification.new do |spec|
spec.required_ruby_version = '~> 2.6.0'
^^^^^^^^^^ `required_ruby_version` (2.6, declared in bar.gemspec) and `TargetRubyVersion` (2.5, which may be specified in .rubocop.yml) should be equal.
end
RUBY
end
end

context 'target ruby version > 2.6', :ruby26 do
it 'does not register an offense when `required_ruby_version` equals ' \
'`TargetRubyVersion`' do
it 'does not register an offense when `required_ruby_version` is specified with >= and equals `TargetRubyVersion`' do
expect_no_offenses(<<~RUBY)
Gem::Specification.new do |spec|
spec.required_ruby_version = '>= 2.6.0'
end
RUBY
end

it 'does not register an offense when `required_ruby_version` ' \
'(omit patch version) equals `TargetRubyVersion`' do
it 'does not register an offense when `required_ruby_version` is specified with ~> and equals `TargetRubyVersion`' do
expect_no_offenses(<<~RUBY)
Gem::Specification.new do |spec|
spec.required_ruby_version = '~> 2.6.0'
end
RUBY
end

it 'does not register an offense when `required_ruby_version` is specified with >= without a patch version and ' \
'equals `TargetRubyVersion`' do
expect_no_offenses(<<~RUBY)
Gem::Specification.new do |spec|
spec.required_ruby_version = '>= 2.6'
end
RUBY
end

it 'does not register an offense when `required_ruby_version` is specified with ~> without a patch version and ' \
'equals `TargetRubyVersion`' do
expect_no_offenses(<<~RUBY)
Gem::Specification.new do |spec|
spec.required_ruby_version = '~> 2.6'
end
RUBY
end

it 'does not register an offense when lowest version of ' \
'`required_ruby_version` equals `TargetRubyVersion`' do
expect_no_offenses(<<~RUBY)
Expand All @@ -75,5 +107,25 @@
end
RUBY
end

it 'registers an offense when `required_ruby_version` is specified with >= without a minor version and is lower ' \
'than `TargetRubyVersion`' do
expect_offense(<<~RUBY, 'bar.gemspec')
Gem::Specification.new do |spec|
spec.required_ruby_version = '>= 2'
^^^^^^ `required_ruby_version` (2, declared in bar.gemspec) and `TargetRubyVersion` (2.6, which may be specified in .rubocop.yml) should be equal.
end
RUBY
end

it 'registers an offense when `required_ruby_version` is specified with ~> without a minor version and is lower ' \
'than `TargetRubyVersion`' do
expect_offense(<<~RUBY, 'bar.gemspec')
Gem::Specification.new do |spec|
spec.required_ruby_version = '~> 2'
^^^^^^ `required_ruby_version` (2, declared in bar.gemspec) and `TargetRubyVersion` (2.6, which may be specified in .rubocop.yml) should be equal.
end
RUBY
end
end
end

0 comments on commit eda147e

Please sign in to comment.