From: "Eregon (Benoit Daloze)" <noreply@...>
Date: 2022-10-28T17:20:05+00:00
Subject: [ruby-core:110539] [Ruby master Feature#19089] Load bundler/setup in gem_prelude.rb when "bundle exec" is used

Issue #19089 has been updated by Eregon (Benoit Daloze).


I believe this feature hurts startup time optimizations, so from that point of view it's not great.
For instance TruffleRuby loads `did_you_mean` ahead of time, during context pre-initialization.
Similarly, CRuby could for instance store the bytecode of `did_you_mean`/`error_highlight` in the CRuby binary or some more other efficient access than parsing Ruby code.
But those optimizations cannot be applied if another version of did_you_mean/error_highlight can be loaded.

I think it would make more sense to only allow loading a different did_you_mean / error_highlight version when `--disable-did-you-mean`/`--disable-error-highlight`/`--disable-gem` is passed.
Then it's clear it's loaded later.

----------------------------------------
Feature #19089: Load bundler/setup in gem_prelude.rb when "bundle exec" is used
https://bugs.ruby-lang.org/issues/19089#change-99865

* Author: mame (Yusuke Endoh)
* Status: Open
* Priority: Normal
----------------------------------------
### Problem

Currently, we cannot specify the version of did_you_mean by using Gemfile.

For example, Ruby master bundles with did_you_mean 1.6.1 by default:

```
$ ruby -e 'p DidYouMean::VERSION'
"1.6.1"
```

Consider that we want to use did_you_mean 1.5.0 with this version of ruby:

```
$ cat Gemfile
source "https://rubygems.org"
gem "did_you_mean", "= 1.5.0"
```

But the attempt fails:

```
$ bundle exec ruby -e 'p DidYouMean::VERSION'
/home/mame/work/ruby/local/lib/ruby/gems/3.2.0+3/gems/bundler-2.3.19/lib/bundler/runtime.rb:308:in `check_for_activated_spec!': You have already activated did_you_mean 1.6.1, but your Gemfile requires did_you_mean 1.5.0. Since did_you_mean is a default gem, you can either remove your dependency on it or try updating to a newer version of bundler that supports did_you_mean as a default gem. (Gem::LoadError)
...
```

This issue is not only with did_you_mean, but also with error_highlight and syntax_suggest which are automatically loaded at the interpreter startup.

This example is specifying an older version of did_you_mean, but typically you will want to specify a newer version. Actually, in https://github.com/rails/rails/pull/45818, I wanted to use error_highlight 0.4.0 with Ruby 3.1. (Note that Ruby 3.1 bundles with error_highlight 0.3.0.)

The cause of this problem is that `bundle exec` makes the interpreter load `bundler/setup` using `RUBYOPT=-rbundler/setup`, but this load is too late.

### Proposed solution

Let's load `bundler/setup` in gem_prelude.rb when `bundle exec` is used.

```diff
diff --git a/gem_prelude.rb b/gem_prelude.rb
index f382021ca3..825508f571 100644
--- a/gem_prelude.rb
+++ b/gem_prelude.rb
@@ -6,6 +6,10 @@
   warn "`RubyGems' were not loaded."
 end if defined?(Gem)

+if ENV["BUNDLE_BIN_PATH"]
+  require File.join(File.dirname(ENV["BUNDLE_BIN_PATH"], 2), "lib/bundler/setup")
+end
+
 begin
   require 'error_highlight'
 rescue LoadError
```

The key is that bundler/setup is loaded immediately after rubygems is loaded, and before error_highlight and did_you_mean are loaded. This patch allows to specify the version of did_you_mean gem by Gemfile:

```
$ cat Gemfile
source "https://rubygems.org"
gem "did_you_mean", "= 1.5.0"

$ bundle exec ruby -e 'p DidYouMean::VERSION'
"1.5.0"
```

@deivid What do you think?



-- 
https://bugs.ruby-lang.org/

Unsubscribe: <mailto:ruby-core-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>