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 development dependencies duplicated in gemspec vs Gemfile #6014

Merged
merged 1 commit into from
Nov 10, 2023

Conversation

deivid-rodriguez
Copy link
Member

@deivid-rodriguez deivid-rodriguez commented Oct 25, 2022

What was the end-user or developer problem that led to this PR?

If a Gemfile duplicates a development dependency also defined in a local gemspec with a different requirement, the requirement in the local gemspec will be silently ignored.

This surprised me.

What is your fix for the problem, implemented in this PR?

I think we should either:

  • Make sure both requirements are considered, like it happens for runtime dependencies (I added a spec to illustrate the current behavior here).

  • Add a warning that the requirement in the gemspec will be ignored.

I think the former is slightly preferable, but it may cause some bundle's that previously resolved to no longer resolver.

I went with the latter but the more I think about it, the more this seems like it should behave like the former.

Make sure the following tasks are checked

@simi
Copy link
Member

simi commented Nov 9, 2023

Thinking about this again after hitting this today (open-telemetry/opentelemetry-ruby-contrib#716) I would suggest warning as a good start in here.

@simi simi marked this pull request as ready for review November 9, 2023 19:49
bundler/lib/bundler/dsl.rb Outdated Show resolved Hide resolved
If a Gemfile duplicates a development dependency also defined in a local
gemspec with a different requirement, the requirement in the local
gemspec will be silently ignored.

This surprised me.

I think we should either:

* Make sure both requirements are considered, like it happens for
  runtime dependencies (I added a spec to illustrate the current behavior
  here).

* Add a warning that the requirement in the gemspec will be ignored.

I think the former is slightly preferable, but it may cause some
bundle's that previously resolve to no longer resolver.

I went with the latter but the more I think about it, the more this
seems like it should behave like the former.
@simi simi merged commit 41bd546 into master Nov 10, 2023
92 checks passed
@simi simi deleted the prefer-most-specific-constraint branch November 10, 2023 13:31
@simi
Copy link
Member

simi commented Nov 10, 2023

What about release? Is patch bump ok since it just introduces warning? 🤔

@deivid-rodriguez
Copy link
Member Author

I think patch should be fine, yes?

@simi
Copy link
Member

simi commented Nov 13, 2023

I think patch should be fine, yes?

I'm ok with patch.

@sambostock
Copy link
Contributor

👋 Something in the last couple days broke Ruby HEAD CI in Shopify/job-iteration

Neither of those PRs touches dependencies, so it must be something upstream, and I'm not positive, but this PR seems related.

In job-iteration, we have a CI matrix in GitHub Actions between Ruby versions and various Gemfiles which specify different version requirements for activejob and activerecord.

# gemfiles/rails_edge.gemfile (for example)
eval_gemfile "../Gemfile"

gem "activejob", github: "rails/rails", branch: "main"
gem "activerecord", github: "rails/rails", branch: "main"
# Gemfile
# ...
gemspec
# ...
# job-iteration.gemspec
# ...
  spec.add_development_dependency("activerecord")
  spec.add_dependency("activejob", ">= 5.2")
end

The error we're now seeing is

...
> bundle install
/home/runner/.rubies/ruby-head/bin/bundle config --local path /home/runner/work/job-iteration/job-iteration/vendor/bundle
/home/runner/.rubies/ruby-head/bin/bundle lock

[!] There was an error parsing `rails_edge.gemfile`: You cannot specify the same gem twice coming from different sources.
You specified that activerecord (>= 0) should come from an unspecified source and https://github.com/rails/rails. Bundler cannot continue.

 #  from /home/runner/work/job-iteration/job-iteration/gemfiles/rails_edge.gemfile:6
 #  -------------------------------------------
 #  gem "activejob", github: "rails/rails", branch: "main"
 >  gem "activerecord", github: "rails/rails", branch: "main"
 #  -------------------------------------------
Error: The process '/home/runner/.rubies/ruby-head/bin/bundle' failed with exit code 4

I've tentatively opened Shopify/job-iteration#438 to change our approach, in case the way we were doing it was technically incorrect (and we'll probably merge it even if it isn't), but I wanted to flag this so we can identify if this PR is the cause of the error or not, and if it is, to surface that it may not be a safe change to make as a patch version update.

@simi
Copy link
Member

simi commented Nov 15, 2023

@sambostock can you extract and share minimal steps to reproduce this? There should be warning, not failure.

@sambostock
Copy link
Contributor

sambostock commented Nov 16, 2023

@simi I've created a minimal repo which reproduces the failure in this CI run. Note matrix statuses:

  • ✅ Ruby 3.2.2 & Gemfile
  • ✅ Ruby 3.2.2 & gemfiles/rails_edge.gemfile
  • ✅ Ruby HEAD & Gemfile
  • ❌ Ruby HEAD & gemfiles/rails_edge.gemfile

I chose "rails_edge" and activesupport as the example dependency, but I don't believe it's specific to the dependency – it's just the change in behaviour to how the difference between the development dependency in gemspec vs in gemfiles/*.gemfile is handled. Previously it worked, but now it's an error.

I should emphasize I'm not confident it's due to this PR, this is just the most relevant looking change I was able to find so far, and the timeline (this commit appeared in ruby/ruby on November 12 at 21:06 EST) makes it seem possibly related, as this approach was working on Ruby HEAD just a few days ago (as early as earlier on November 12 at 12:15 EST).

@deivid-rodriguez
Copy link
Member Author

Thanks for the report, will look into this before releasing this PR 👍.

@tagliala
Copy link

tagliala commented Nov 28, 2023

Probably I ran into the same issue here:

https://github.com/ifad/chronomodel/actions/runs/7021550132/job/19103883939

The use case is similar to the above one, we're using specific gemfiles to test across several rails versions

relevant rails_7.1.gemfile:

gem "rails", "~> 7.1.0"

relevant gemspec:

  gem.add_development_dependency 'rails'

@deivid-rodriguez
Copy link
Member Author

This is next on my list, thanks for the examples!

@deivid-rodriguez
Copy link
Member Author

Reproduced! Looking into it now.

@deivid-rodriguez
Copy link
Member Author

#7215 fixes this. Thanks for diligently reporting the problem so early ❤️.

@WesleyW
Copy link

WesleyW commented Dec 20, 2023

Hi @deivid-rodriguez!

I'm running into the same issue as this comment. We're using Appraisal to test that our gem works with multiple versions of a gem (e.g. Rails). This means our Gemfile + gemspec look something like this when we're testing:

# Gemfile
gem "rails", "~> 7.0.8"
# gemspec
  spec.add_development_dependency 'rails'

OR like this:

# Gemfile
gem "rails", "~> 7.0.8"
# gemspec
  spec.add_development_dependency 'rails', '>= 5'

From the wording of this issue, it seems like our use case is discouraged, but it should just warn rather than error outright. Could you clarify what the best practice for us would be or if this could be fixed?

Edit:
I created a barebones repo of what I'm talking about. Running bundle with Ruby 3.2.2 and bundler 2.5.1 will result in this error:

[!] There was an error parsing `Gemfile`: You cannot specify the same gem twice with different version requirements.
You specified: rails (~> 7.0.8) and rails (>= 0). Bundler cannot continue.

 #  from /private/tmp/bundle-gemfile-error/Gemfile:5
 #  -------------------------------------------
 #  
 >  gemspec
 #  -------------------------------------------

@deivid-rodriguez
Copy link
Member Author

@WesleyW Seems like a similar bug, I'll try to fix it for final ruby release.

@deivid-rodriguez
Copy link
Member Author

I think in your case the warning is intended (at least when both Gemfile and gemspec specify some requirement). The way to silence the warning would be to remove either of them.

@deivid-rodriguez
Copy link
Member Author

Fixed by #7319, thanks for letting us know!

@WesleyW
Copy link

WesleyW commented Dec 21, 2023

Amazing! Tried it out locally and confirmed it works. Thank you for such a quick fix!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants