Feature #13847
closedGem activated problem for default gems
Description
If you try to use some default gems with a fixed version using Bundler, there are cases where the current RubyGems/Bundler/Ruby specification can not be used with the version specified by the user.
For example
$ ruby -v
ruby 2.4.1p111 (2017-03-22 revision 58053) [x86_64-darwin17]
$ gem list | grep openssl
openssl (2.0.5, 2.0.4, default: 2.0.3)
In the environment such as require 'openssl', the version that is activated when openssl is searched with openssl is the version found first, ie 2.0.5.
At this time, for example, suppose the user really wants to use openssl 2.0.4 and wrote the following Gemfile.
Unfortunately, since rubygems has required openssl before the bundler runs it will result in an activated error like this:
> bundle exec ruby -ropenssl -e 'p OpenSSL::VERSION'
/path/to/2.4.1/lib/ruby/gems/2.4.0/gems/bundler-1.15.4/lib/bundler/runtime.rb:317:in `check_for_activated_spec!': You have already activated openssl 2.0.5, but your Gemfile requires openssl 2.0.4. Prepending `bundle exec` to your command may solve this. (Gem::LoadError)
This problem can be avoided by bundling it as a vendoring library under bundler's repository if it is a default gem implemented with pure ruby.
Https://github.com/bundler/bundler/blob/master/lib/bundler/vendor/fileutils/lib/fileutils.rb
In the case of bundler, by separating the namespace as Bundler::FileUtils, even the version specified by the user is made available without conflict at the time of activate. However, this method can not be used with C extension library.
Since we want to use json/psych from the bundler team with rubygems/bundler to serialize data, we need about whether we can implement a way to avoid some kind of C extension on Ruby itself.
I discussed with @indirect who is maintainer of RubyGems/Bundler. We can resolve this problem like following feature of ruby.
When we declared above require_for_bundler, We put a json-2.0.2 to placed in a namespace like Bundler::JSON. There were similar issues in the past as well.
https://bugs.ruby-lang.org/issues/10320
I think that the way of writing require 'json', version: '2.0.2', into: :Bundler which extended the method like this issue seems like that. Also, in this use case, it seems to be enough to use require 'json', version: :default, into: :Bundler which forces the use of default gem.
Matz, How do you think about this feature?