[DRE-maint] Bug#830958: ruby-bundler: System-wide ruby packages get predecedence over local ones (in some cases)
Gabriel Corona
gabriel.corona at enst-bretagne.fr
Wed Jul 13 09:41:03 UTC 2016
Package: ruby-bundler
Version: 1.12.5-2
Severity: normal
Dear Maintainer,
When installing gem with Debian-packages Bundler, in some cases (when
using bundle exec) the system-wide version is used before the
Bundler-shipped version:
cat > Gemfile <<EOF
source 'https://rubygems.org'
gem 'puppet', '~> 3.7.2'
gem 'hiera', '~> 1.3.4'
gem 'hiera-puppet', '~> 1.0.0'
gem 'r10k', '~> 1.1.4'
EOF
bundle install --path vendor/bundle --binstubs
puppet --version # 4.5.2, this comes from Debian
./bin/puppet --version # 3.7.2, this comes from Bundler
bundle exec puppet --version # 4.5.2, this comes from Debian
I'd expect `bundle exec puppet` to use the Bundler version instead.
The manpage of bundle-exec [2] claims that:
> If you use the `--binstubs` flag in `bundle install(1)`, Bundler
> will automatically create a directory (which defaults to
> `app_root/bin`) containing all of the executables available from
> gems in the bundle.
>
> After using `--binstubs`, <b>`bin/rspec spec/my_spec.rb` is
> identical to `bundle exec rspec spec/my_spec.rb`</b>.
So I'd expect the two last commands to behave the same.
It turns out [1] that Bundler adds its base directory
(/usr/lib/ruby/vendor_ruby) in RUBYLIB in order to make
RUBYOPT=-rbundler/setup work:
def set_rubylib
rubylib = (ENV["RUBYLIB"] || "").split(File::PATH_SEPARATOR)
rubylib.unshift File.expand_path("../..", __FILE__)
ENV["RUBYLIB"] = rubylib.uniq.join(File::PATH_SEPARATOR)
end
The two methods of execution lead to a different $LOAD_PATH. With
./bin/puppet, we have:
["/home/foo/bar/vendor/bundle/ruby/2.3.0/gems/r10k-1.1.4/lib", "/home/foo/bar/vendor/bundle/ruby/2.3.0/gems/systemu-2.5.2/lib", "/home/foo/bar/vendor/bundle/ruby/2.3.0/gems/puppet-3.7.5/lib", "/home/foo/bar/vendor/bundle/ruby/2.3.0/gems/log4r-1.1.10/lib", "/home/foo/bar/vendor/bundle/ruby/2.3.0/gems/hiera-puppet-1.0.0/lib", "/home/foo/bar/vendor/bundle/ruby/2.3.0/gems/hiera-1.3.4/lib", "/home/foo/bar/vendor/bundle/ruby/2.3.0/gems/json_pure-2.0.1/lib", "/home/foo/bar/vendor/bundle/ruby/2.3.0/gems/facter-2.4.6/lib", "/home/foo/bar/vendor/bundle/ruby/2.3.0/gems/cri-2.4.1/lib", "/home/foo/bar/vendor/bundle/ruby/2.3.0/gems/colored-1.2/lib", "/usr/lib/ruby/vendor_ruby/gems/bundler-1.12.5/lib", "/usr/local/lib/site_ruby/2.3.0", "/usr/local/lib/x86_64-linux-gnu/site_ruby", "/usr/local/lib/site_ruby", "/usr/lib/ruby/vendor_ruby/2.3.0", "/usr/lib/x86_64-linux-gnu/ruby/vendor_ruby/2.3.0", "/usr/lib/ruby/vendor_ruby", "/usr/lib/ruby/2.3.0", "/usr/lib/x86_64-linux-gnu/ruby/2.3.0"]
In this case, Bundler sets RUBYLIB (in require "bundler/setup") but
the Ruby interpreter is already initialized and it is not prepended to
$LOAD_PATH.
With bundle exec, we have:
["/usr/lib/ruby/vendor_ruby", "/home/foo/bar/vendor/bundle/ruby/2.3.0/gems/r10k-1.1.4/lib", "/home/foo/bar/vendor/bundle/ruby/2.3.0/gems/systemu-2.5.2/lib", "/home/foo/bar/vendor/bundle/ruby/2.3.0/gems/puppet-3.7.5/lib", "/home/foo/bar/vendor/bundle/ruby/2.3.0/gems/log4r-1.1.10/lib", "/home/foo/bar/vendor/bundle/ruby/2.3.0/gems/hiera-puppet-1.0.0/lib", "/home/foo/bar/vendor/bundle/ruby/2.3.0/gems/hiera-1.3.4/lib", "/home/foo/bar/vendor/bundle/ruby/2.3.0/gems/json_pure-2.0.1/lib", "/home/foo/bar/vendor/bundle/ruby/2.3.0/gems/facter-2.4.6/lib", "/home/foo/bar/vendor/bundle/ruby/2.3.0/gems/cri-2.4.1/lib", "/home/foo/bar/vendor/bundle/ruby/2.3.0/gems/colored-1.2/lib", "/usr/lib/ruby/vendor_ruby/gems/bundler-1.12.5/lib", "/usr/local/lib/site_ruby/2.3.0", "/usr/local/lib/x86_64-linux-gnu/site_ruby", "/usr/local/lib/site_ruby", "/usr/lib/ruby/vendor_ruby/2.3.0", "/usr/lib/x86_64-linux-gnu/ruby/vendor_ruby/2.3.0", "/usr/lib/ruby/2.3.0", "/usr/lib/x86_64-linux-gnu/ruby/2.3.0"]
In this case, Bundlet sets RUBYLIB and then exec a new Ruby
interpreter. This Ruby interpreter sees RUBYLIB and prepends it to
$LOAD_PATH.
The problem is that in this case, all the Debian-packaged ruby libs
are used in preference to the Bundler-provided ones which is probably
not what the user intends to do.
Using a local version of bundler fixes the issue:
gem install --user-install bundler
~/.gem/ruby/2.3.0/bin/bundle exec puppet --version # 3.7.5
[1] https://github.com/bundler/bundler/issues/4780
[2] http://bundler.io/v1.12/man/bundle-exec.1.html
-- System Information:
Debian Release: stretch/sid
APT prefers stable-updates
APT policy: (500, 'stable-updates'), (500, 'testing'), (500, 'stable'), (90, 'unstable'), (1, 'experimental')
Architecture: amd64 (x86_64)
Foreign Architectures: i386
Kernel: Linux 4.6.0-1-amd64 (SMP w/4 CPU cores)
Locale: LANG=fr_FR.utf8, LC_CTYPE=fr_FR.utf8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash
Init: systemd (via /run/systemd/system)
Versions of packages ruby-bundler depends on:
ii ruby 1:2.3.0+4
ii ruby-molinillo 0.5.0-1
ii ruby-net-http-persistent 2.9.4-1
ii ruby-thor 0.19.1-2
ii ruby2.1 [ruby-interpreter] 2.1.5-2+deb8u2
ii rubygems-integration 1.10
ruby-bundler recommends no packages.
ruby-bundler suggests no packages.
-- no debconf information
More information about the Pkg-ruby-extras-maintainers
mailing list