Skip to content

Commit

Permalink
Fix required_ruby_version issue when using Gem::Requirement (#9037)
Browse files Browse the repository at this point in the history
This fixes an issue when the `required_ruby_version` uses `Gem::Requirement` to define the Ruby version.

e.g.

```
s.required_ruby_version = Gem::Requirement.new('< 3.0.0')
```

Related to #8761
  • Loading branch information
cetinajero committed Nov 13, 2020
1 parent 1affc7c commit 9e83b37
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 4 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## master (unreleased)

### Bug fixes

* [#9037](https://github.com/rubocop-hq/rubocop/pull/9037): Fix `required_ruby_version` issue when using `Gem::Requirement`. ([@cetinajero][])

## 1.3.0 (2020-11-12)

### New features
Expand Down
16 changes: 12 additions & 4 deletions lib/rubocop/target_ruby.rb
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,10 @@ class GemspecFile < Source
(send _ :required_ruby_version= $_)
PATTERN

def_node_matcher :gem_requirement?, <<~PATTERN
(send (const(const _ :Gem):Requirement) :new $str)
PATTERN

def name
"`required_ruby_version` parameter (in #{gemspec_filename})"
end
Expand All @@ -136,10 +140,9 @@ def find_version
version = version_from_gemspec_file(file)
return if version.nil?

if version.array_type?
versions = version.children.map { |v| version_from_str(v.str_content) }
return versions.compact.min
end
requirement = version.children.last
return version_from_array(version) if version.array_type?
return version_from_array(requirement) if gem_requirement? version

version_from_str(version.str_content)
end
Expand All @@ -161,6 +164,11 @@ def version_from_gemspec_file(file)
required_ruby_version(processed_source.ast).first
end

def version_from_array(array)
versions = array.children.map { |v| version_from_str(v.is_a?(String) ? v : v.str_content) }
versions.compact.min
end

def version_from_str(str)
str.match(/^(?:>=|<=)?\s*(?<version>\d+(?:\.\d+)*)/) do |md|
md[:version].to_f
Expand Down
47 changes: 47 additions & 0 deletions spec/rubocop/target_ruby_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,53 @@
end
end

context 'when file contains `required_ruby_version` as a requirement' do
let(:base_path) { configuration.base_dir_for_path_parameters }
let(:gemspec_file_path) { File.join(base_path, 'example.gemspec') }

it 'sets target_ruby from required_ruby_version from exact requirement version' do
content =
<<-HEREDOC
Gem::Specification.new do |s|
s.name = 'test'
s.required_ruby_version = Gem::Requirement.new('2.7.4')
s.licenses = ['MIT']
end
HEREDOC

create_file(gemspec_file_path, content)
expect(target_ruby.version).to eq 2.7
end

it 'sets target_ruby from required_ruby_version from inclusive requirement range' do
content =
<<-HEREDOC
Gem::Specification.new do |s|
s.name = 'test'
s.required_ruby_version = Gem::Requirement.new('>= 3.0.0')
s.licenses = ['MIT']
end
HEREDOC

create_file(gemspec_file_path, content)
expect(target_ruby.version).to eq 3.0
end

it 'sets default target_ruby from exclusive requirement range' do
content =
<<-HEREDOC
Gem::Specification.new do |s|
s.name = 'test'
s.required_ruby_version = Gem::Requirement.new('< 3.0.0')
s.licenses = ['MIT']
end
HEREDOC

create_file(gemspec_file_path, content)
expect(target_ruby.version).to eq default_version
end
end

context 'when file contains `required_ruby_version` as an array' do
let(:base_path) { configuration.base_dir_for_path_parameters }
let(:gemspec_file_path) { File.join(base_path, 'example.gemspec') }
Expand Down

0 comments on commit 9e83b37

Please sign in to comment.