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
Only parse target Ruby from gemspec if array elements are strings #12756
Only parse target Ruby from gemspec if array elements are strings #12756
Conversation
066f293
to
e0d060c
Compare
cc @Earlopain (Thank you for connecting the dots here between that issue #12579 and my recent PR #12732 !) |
spec/rubocop/target_ruby_spec.rb
Outdated
content = <<~HEREDOC | ||
Gem::Specification.new do |s| | ||
s.name = 'test' | ||
s.required_ruby_version = [">= \#{File.read('.ruby-version').rstrip}"] | ||
s.licenses = ['MIT'] | ||
end | ||
HEREDOC |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
content = <<~HEREDOC | |
Gem::Specification.new do |s| | |
s.name = 'test' | |
s.required_ruby_version = [">= \#{File.read('.ruby-version').rstrip}"] | |
s.licenses = ['MIT'] | |
end | |
HEREDOC | |
content = <<~'HEREDOC' | |
Gem::Specification.new do |s| | |
s.name = 'test' | |
s.required_ruby_version = [">= #{File.read('.ruby-version').rstrip}"] | |
s.licenses = ['MIT'] | |
end | |
HEREDOC |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@koic : Thank you for the review and the good suggestion! I have applied your suggestion both to the spec that I am adding in this PR (as you suggested) and also to the similar spec just above, which I added in #12732. (Unfortunately, this makes the diff in GitHub look a little bit more complicated/confusing than necessary/ideal.)
This fixes an issue mentioned in [this comment](#12579 (comment)) on issue #12579. (I believe that the main/original issue mentioned in issue #12579 has already been fixed by #12732.) This change is a related/similar followup to #12732 (5026393). That PR avoided an exception that was occurring in the `RuboCop::TargetRuby::GemspecFile` target Ruby finder when a project's gemspec determines the value of `required_ruby_version` in some dynamic way (such as by reading from a `.ruby-version` file). However, #12732 did not handle a case where the dynamic value for the gemspec's `required_ruby_version` is wrapped within an array, and, in such a case, currently, an exception like the following will occur: ``` Gem::Requirement::BadRequirementError: Illformed requirement [">= \#{File.read('.ruby-version').rstrip}"] ./lib/rubocop/target_ruby.rb:123:in `new' ./lib/rubocop/target_ruby.rb:123:in `find_default_minimal_known_ruby' ./lib/rubocop/target_ruby.rb:83:in `find_version' ./lib/rubocop/target_ruby.rb:29:in `initialize' ./lib/rubocop/target_ruby.rb:259:in `new' ``` (As with the scenario that _was_ fixed by #12732, I believe that this is essentially a "latent" issue that is now occurring in more projects than previously, due to #12645 having increased the precedence of the `GemspecFile` target Ruby finder in the `RuboCop::TargetRuby::SOURCES` list.) This change avoids this exception by only attempting to parse a target Ruby version from an array value for a gemspec's `required_ruby_version` if every value in the array is a string. When the values within the `required_ruby_version` array are _not_ all strings, now, rather than raising an unhandled exception, the `GemspecFile` finder will return `nil` for the target Ruby version, and so we will continue on to the other TargetRuby finder classes, in order to find a target Ruby version.
e0d060c
to
bf4d1e0
Compare
I'd also suggest expanding the docs here a bit https://docs.rubocop.org/rubocop/1.62/configuration.html#setting-the-target-ruby-version (the section about the target version discovery is pretty short, so it might not be clear to people how this is expected to work exactly) |
context 'when file reads the required_ruby_version from another file' do | ||
it 'uses the default target ruby version' do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(This is an existing spec that I only modified to have a heredoc without interpolation; it is otherwise unchanged.)
context 'when file reads the required_ruby_version from another file in an array' do | ||
it 'uses the default target ruby version' do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the new spec that I am adding for this change. Unfortunately (due to how it looks similar to the spec changed above), GitHub is actually not even including the whole new spec in its rendering of this diff. You'll have to click the down arrow to see the last few lines of this new spec, which GitHub is rendering as if they are preexisting lines.
I had pasted the wrong link (updated) - the right one is https://docs.rubocop.org/rubocop/1.62/configuration.html#setting-the-target-ruby-version Basically I'm referring to:
Would be good to clarify when can RuboCop actually extract a version from the gemspec or the Gemfile.lock. We can also clarify which is the default value that will be used if inference fails. |
@bbatsov : I made an effort to expand the documentation a bit in 64ca11b (before reading your latest comment). I have a tendency to be too verbose, and I'm not sure I touched on the key points in the best way. Feel free to suggest any additions, deletions, or changes, or to simply make those changes on this branch yourself, if that's easier/preferable. (I have granted you permission to do so.) |
@bbatsov : I had thought about adding that, but I didn't want to put that as a maintenance burden on you or to have that be something that we might forget to update and which would be prone to maybe becoming outdated and inaccurate. I can add that, if you'd like me to, though (or, again, feel free to add it yourself, if that's easier). |
64ca11b
to
699a65e
Compare
Great work!
Fair point, although I don't expect many changes in this area going forward. Time will tell. :-) |
This fixes an issue mentioned in this comment on issue #12579. (I believe that the main/original issue mentioned in issue #12579 has essentially already been fixed by #12732.)
This change is a related/similar followup to #12732 (5026393). That PR avoided an exception that was occurring in the
RuboCop::TargetRuby::GemspecFile
target Ruby finder when a project's gemspec determines the value ofrequired_ruby_version
in some dynamic way (such as by reading from a.ruby-version
file).However, #12732 did not handle a case where the dynamic value for the gemspec's
required_ruby_version
is wrapped within an array, and, in such a case, currently, an exception like the following will occur:(As with the scenario that was fixed by #12732, I believe that this is essentially a "latent" issue that is now occurring in more projects than previously, due to #12645 having increased the precedence of the
GemspecFile
target Ruby finder in theRuboCop::TargetRuby::SOURCES
list.)This change avoids this exception by only attempting to parse a target Ruby version from an array value for a gemspec's
required_ruby_version
if every value in the array is a string. When the values within therequired_ruby_version
array are not all strings, now, rather than raising an unhandled exception, theGemspecFile
finder will returnnil
for the target Ruby version, and so we will continue on to the other TargetRuby finder classes, in order to find a target Ruby version.Before submitting the PR make sure the following are checked:
[Fix #issue-number]
(if the related issue exists).master
(if not - rebase it).bundle exec rake default
. It executes all tests and runs RuboCop on its own code.{change_type}_{change_description}.md
if the new code introduces user-observable changes. See changelog entry format for details.