Skip to content

Instantly share code, notes, and snippets.

@hsbt
Last active August 28, 2017 04:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hsbt/b09c7c7b4d09d7f8f7684359354f4818 to your computer and use it in GitHub Desktop.
Save hsbt/b09c7c7b4d09d7f8f7684359354f4818 to your computer and use it in GitHub Desktop.

(Translated by Google :))

If you try to use some default gems with 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.

$ ruby -ropenssl -e 'p OpenSSL::VERSION'
"2.0.5"

At this time, for example, suppose the user really wants to use openssl 2.0.4 and wrote the following Gemfile.

> cat Gemfile
# frozen_string_literal: true
source "https://rubygems.org"

gem 'openssl', '2.0.4'

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 extention 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.

Consult @hsbt and @indirect, for example

require_for_bundler 'json', '2.0.2'

Once I talked that it could be avoided if json-2.0.2 (which is the version shipped with ruby 2.4.1) is 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?

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