Open ngan opened 1 year ago
Here is the minimum repo to reproduce the issue: https://github.com/tubaxenor/bundler-test
I may be mistaken, but I don't think this is fixable. Bundler must run to setup the environment, which means it can't load itself at a different version after loading the environment. Bundler is one of the few gems that must be installed in the system in order to run any ruby program that uses a Gemfile.
Bundler has some trampolining behavior, where it will re'exec to the locked version of itself as soon as it finds that the locked version is different than the running version. But maybe this is not quite working for this particular case. I'd like to have a closer look at it, so let me reopen @martinemde if that's fine. I'll close if I find this is not fixable or not worth fixing.
Ah yes, so I was mistaken. Thanks @deivid-rodriguez!
this is to uninstall the higher version of bundler from your system gems. It should be installed into vendor/bundle already
@ngan Why do you think bundler should be installed in vendor/bundle
when it is not part of the Gemfile itself? Bundler vendors only gems included in your bundle (listed in Gemfile.lock
).
Bundler currently already installs the locked version of Bundler in the Gemfile.lock
file into vendor/bundle
(or whatever path is configured). That way it is able to automatically re-exec using that version the next time.
The problem is that in the particular case where the locked version of Bundler is already running because of being installed globally, this was not happen, so subsequent runs fail to run the proper version if the locked version stops being available globally.
On the latest version of bundler (2.4.18), but I think this applies to all versions, we noticed a bug(?) wherein if you have path configured, a binstub (using
require "bundler/setup"
) boots into the wrong version of Bundler. More specifically, it just uses your system bundler instead of the higher versioned bundler installed (into say,vendor/bundle
) and specified by yourGemfile.lock
.We noticed this problem in our Docker image where Ruby 3.2.2 comes with Bundler 2.4.10. We install gems in our docker image to
vendor/bundle
. If you runbin/rails
(or any binstub) andputs Bundler::VERSION
inside the process, you'll get2.4.10
instead of2.4.18
.This is easily reproducible locally:
bundle install --path vendor/bundle
gem uninstall bundler
(this is to uninstall the higher version of bundler from your system gems. It should be installed intovendor/bundle
already).bin/rails runner "puts Bundler::VERSION"
I thought that this was by design since I don't even see how we would load Bundler (whichever one is available), then realize that we've installed gems into a custom path, then switch over to the right version of bundler all within the same process. But then I saw @indirect's blog post: Never
bundle exec
again and thought, maybe this is an oversight.