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

Gemspec/RequiredRubyVersion errors with only upper bounded requirement #12714

Closed
Maimer opened this issue Feb 26, 2024 · 0 comments · Fixed by #12715
Closed

Gemspec/RequiredRubyVersion errors with only upper bounded requirement #12714

Maimer opened this issue Feb 26, 2024 · 0 comments · Fixed by #12715
Labels

Comments

@Maimer
Copy link

Maimer commented Feb 26, 2024

Expected behavior

The Gemspec/RequiredRubyVersion cop should pass with only an upper bounded limit as the value.

Example:

spec.required_ruby_version = Gem::Requirement.new('< 3.4')

Actual behavior

The following error is raised:

An error occurred while Gemspec/RequiredRubyVersion cop was inspecting /test_gem.gemspec:18:2.
undefined method `str_content' for nil
/gems/ruby-3.3.0/gems/rubocop-1.60.2/lib/rubocop/cop/gemspec/required_ruby_version.rb:113:in `extract_ruby_version'
/gems/ruby-3.3.0/gems/rubocop-1.60.2/lib/rubocop/cop/gemspec/required_ruby_version.rb:86:in `on_send'
/gems/ruby-3.3.0/gems/rubocop-1.60.2/lib/rubocop/cop/commissioner.rb:143:in `public_send'
/gems/ruby-3.3.0/gems/rubocop-1.60.2/lib/rubocop/cop/commissioner.rb:143:in `block (2 levels) in trigger_restricted_cops'
/gems/ruby-3.3.0/gems/rubocop-1.60.2/lib/rubocop/cop/commissioner.rb:171:in `with_cop_error_handling'
/gems/ruby-3.3.0/gems/rubocop-1.60.2/lib/rubocop/cop/commissioner.rb:142:in `block in trigger_restricted_cops'
/gems/ruby-3.3.0/gems/rubocop-1.60.2/lib/rubocop/cop/commissioner.rb:141:in `each'
/gems/ruby-3.3.0/gems/rubocop-1.60.2/lib/rubocop/cop/commissioner.rb:141:in `trigger_restricted_cops'
/gems/ruby-3.3.0/gems/rubocop-1.60.2/lib/rubocop/cop/commissioner.rb:70:in `on_send'
/gems/ruby-3.3.0/gems/rubocop-ast-1.30.0/lib/rubocop/ast/traversal.rb:137:in `block in on_dstr'
/gems/ruby-3.3.0/gems/rubocop-ast-1.30.0/lib/rubocop/ast/traversal.rb:137:in `each'
/gems/ruby-3.3.0/gems/rubocop-ast-1.30.0/lib/rubocop/ast/traversal.rb:137:in `on_dstr'
/gems/ruby-3.3.0/gems/rubocop-1.60.2/lib/rubocop/cop/commissioner.rb:71:in `on_begin'
/gems/ruby-3.3.0/gems/rubocop-ast-1.30.0/lib/rubocop/ast/traversal.rb:158:in `on_block'
/gems/ruby-3.3.0/gems/rubocop-1.60.2/lib/rubocop/cop/commissioner.rb:71:in `on_block'
/gems/ruby-3.3.0/gems/rubocop-ast-1.30.0/lib/rubocop/ast/traversal.rb:137:in `block in on_dstr'
/gems/ruby-3.3.0/gems/rubocop-ast-1.30.0/lib/rubocop/ast/traversal.rb:137:in `each'
/gems/ruby-3.3.0/gems/rubocop-ast-1.30.0/lib/rubocop/ast/traversal.rb:137:in `on_dstr'
/gems/ruby-3.3.0/gems/rubocop-1.60.2/lib/rubocop/cop/commissioner.rb:71:in `on_begin'
/gems/ruby-3.3.0/gems/rubocop-ast-1.30.0/lib/rubocop/ast/traversal.rb:20:in `walk'
/gems/ruby-3.3.0/gems/rubocop-1.60.2/lib/rubocop/cop/commissioner.rb:87:in `investigate'
/gems/ruby-3.3.0/gems/rubocop-1.60.2/lib/rubocop/cop/team.rb:156:in `investigate_partial'
/gems/ruby-3.3.0/gems/rubocop-1.60.2/lib/rubocop/cop/team.rb:98:in `investigate'
/gems/ruby-3.3.0/gems/rubocop-1.60.2/lib/rubocop/runner.rb:345:in `block in inspect_file'
/gems/ruby-3.3.0/gems/rubocop-1.60.2/lib/rubocop/runner.rb:344:in `each'
/gems/ruby-3.3.0/gems/rubocop-1.60.2/lib/rubocop/runner.rb:344:in `flat_map'
/gems/ruby-3.3.0/gems/rubocop-1.60.2/lib/rubocop/runner.rb:344:in `inspect_file'
/gems/ruby-3.3.0/gems/rubocop-1.60.2/lib/rubocop/runner.rb:287:in `block in do_inspection_loop'
/gems/ruby-3.3.0/gems/rubocop-1.60.2/lib/rubocop/runner.rb:321:in `block in iterate_until_no_changes'
<internal:kernel>:187:in `loop'
/gems/ruby-3.3.0/gems/rubocop-1.60.2/lib/rubocop/runner.rb:314:in `iterate_until_no_changes'
/gems/ruby-3.3.0/gems/rubocop-1.60.2/lib/rubocop/runner.rb:283:in `do_inspection_loop'
/gems/ruby-3.3.0/gems/rubocop-1.60.2/lib/rubocop/runner.rb:164:in `block in file_offenses'
/gems/ruby-3.3.0/gems/rubocop-1.60.2/lib/rubocop/runner.rb:189:in `file_offense_cache'
/gems/ruby-3.3.0/gems/rubocop-1.60.2/lib/rubocop/runner.rb:163:in `file_offenses'
/gems/ruby-3.3.0/gems/rubocop-1.60.2/lib/rubocop/runner.rb:154:in `process_file'
/gems/ruby-3.3.0/gems/rubocop-1.60.2/lib/rubocop/runner.rb:135:in `block in each_inspected_file'
/gems/ruby-3.3.0/gems/rubocop-1.60.2/lib/rubocop/runner.rb:134:in `each'
/gems/ruby-3.3.0/gems/rubocop-1.60.2/lib/rubocop/runner.rb:134:in `reduce'
/gems/ruby-3.3.0/gems/rubocop-1.60.2/lib/rubocop/runner.rb:134:in `each_inspected_file'
/gems/ruby-3.3.0/gems/rubocop-1.60.2/lib/rubocop/runner.rb:120:in `inspect_files'
/gems/ruby-3.3.0/gems/rubocop-1.60.2/lib/rubocop/runner.rb:73:in `run'
/gems/ruby-3.3.0/gems/rubocop-1.60.2/lib/rubocop/cli/command/execute_runner.rb:26:in `block in execute_runner'
/gems/ruby-3.3.0/gems/rubocop-1.60.2/lib/rubocop/cli/command/execute_runner.rb:52:in `with_redirect'
/gems/ruby-3.3.0/gems/rubocop-1.60.2/lib/rubocop/cli/command/execute_runner.rb:25:in `execute_runner'
/gems/ruby-3.3.0/gems/rubocop-1.60.2/lib/rubocop/cli/command/execute_runner.rb:17:in `run'
/gems/ruby-3.3.0/gems/rubocop-1.60.2/lib/rubocop/cli/command.rb:11:in `run'
/gems/ruby-3.3.0/gems/rubocop-1.60.2/lib/rubocop/cli/environment.rb:18:in `run'
/gems/ruby-3.3.0/gems/rubocop-1.60.2/lib/rubocop/cli.rb:118:in `run_command'
/gems/ruby-3.3.0/gems/rubocop-1.60.2/lib/rubocop/cli.rb:125:in `execute_runners'
/gems/ruby-3.3.0/gems/rubocop-1.60.2/lib/rubocop/cli.rb:51:in `block in run'
/gems/ruby-3.3.0/gems/rubocop-1.60.2/lib/rubocop/cli.rb:77:in `profile_if_needed'
/gems/ruby-3.3.0/gems/rubocop-1.60.2/lib/rubocop/cli.rb:43:in `run'
/gems/ruby-3.3.0/gems/rubocop-1.60.2/exe/rubocop:19:in `block in <top (required)>'
/rubies/ruby-3.3.0/lib/ruby/3.3.0/benchmark.rb:313:in `realtime'
/gems/ruby-3.3.0/gems/rubocop-1.60.2/exe/rubocop:19:in `<top (required)>'
/gems/ruby-3.3.0/bin/rubocop:25:in `load'
/gems/ruby-3.3.0/bin/rubocop:25:in `<main>'
/gems/ruby-3.3.0/bin/ruby_executable_hooks:22:in `eval'
/gems/ruby-3.3.0/bin/ruby_executable_hooks:22:in `<main>'

Steps to reproduce the problem

Update a gem's gemspec to use only an upper bounded limit for the required_ruby_version:

spec.required_ruby_version = Gem::Requirement.new('< 3.4')

The problem lies here: https://github.com/rubocop/rubocop/blob/master/lib/rubocop/cop/gemspec/required_ruby_version.rb#L100-L114

The regex used is /[>=]/ and therefore it doesn't match < and therefore returns nil. This regex can be updated to /[>=<]/, but then the it adds an offense here: https://github.com/rubocop/rubocop/blob/master/lib/rubocop/cop/gemspec/required_ruby_version.rb#L89 for the Ruby version not matching the version in the .rubocop.yml, which we wouldn't want in this case. I am not entirely sure the best way to solve that problem, otherwise I would have submitted a Pull Request to update the regex.

RuboCop version

1.60.2 (using Parser 3.3.0.5, rubocop-ast 1.30.0, running on ruby 3.3.0) [x86_64-darwin22]
  - rubocop-minitest 0.34.5
@Maimer Maimer changed the title Gemspec/RequiredRubyVersion does not work with upper bounded requirement Gemspec/RequiredRubyVersion does not work with upper bounded requirement Feb 26, 2024
@Maimer Maimer changed the title Gemspec/RequiredRubyVersion does not work with upper bounded requirement Gemspec/RequiredRubyVersion errors with only upper bounded requirement Feb 26, 2024
@koic koic added the bug label Feb 27, 2024
koic added a commit to koic/rubocop that referenced this issue Feb 27, 2024
Fixes rubocop#12714.

This PR fixes an error for `Gemspec/RequiredRubyVersion`
when `required_ruby_version` is specified with `Gem::Requirement.new`
and is higher than `TargetRubyVersion`.

When specifying only an upper version limit, an offense is registered
because lower Ruby version that matches `TargetRubyVersion` is unknown.
bbatsov pushed a commit that referenced this issue Feb 27, 2024
Fixes #12714.

This PR fixes an error for `Gemspec/RequiredRubyVersion`
when `required_ruby_version` is specified with `Gem::Requirement.new`
and is higher than `TargetRubyVersion`.

When specifying only an upper version limit, an offense is registered
because lower Ruby version that matches `TargetRubyVersion` is unknown.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants