Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle major version requirements in Gemspec/RequiredRubyVersion #8310

Merged
merged 1 commit into from Jul 12, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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