Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does bundler use more than one gem location?

This is happening in Puppet's bundle.

The Gemfile specifies

gem "puppet", :path => File.dirname(__FILE__), :require => false

But one of the gems I installed in $GEM_HOME appears in $: after all.

$ bundle exec ruby -e 'puts $:'
...
/home/puppy/puppet-git-clone/lib
...
/usr/lib/ruby/vendor_ruby
...
/home/puppy/gems/gems/puppet-3.7.5/lib
...

This is not a problem in and of itself, but apparently Ruby will load Puppet 3.7.5 instead of the 3.7.3 I checked out of the git repo.

$ bundle exec irb
irb(main):001:0> require 'puppet'
=> true
irb(main):002:0> Facter.value(:puppetversion)
=> "3.7.5"

Why is Puppet not loaded from the git tree and how can I debug this further?

Update

Puppets .gemspec might be involved. It's clever about specifying the version. I now worry that Rubygems does in fact load the installed 3.7.5 gem so that Puppet.version would truthfully report a wrong value, throwing off bundler. Could that be what's happening?

Update 2

As suggested in the comments, I tried settings the path and version statically in the Gemfile.

gem "puppet", "3.4.2", :path => "/home/puppy/puppet-git-clone", :require => false

As for the result, well - at least bundler is consistent in its views ;-)

Could not find gem 'puppet (= 3.4.2) ruby' in source at /home/ffrank/git/puppet.
Source contains 'puppet' at: 3.7.3
Run `bundle install` to install missing gems.
like image 230
Felix Frank Avatar asked Apr 17 '15 20:04

Felix Frank


People also ask

Where does bundler install gems?

A Gemfile describes the gem dependencies required to execute associated Ruby code. Place the Gemfile in the root of the directory containing the associated code. For instance, in a Rails application, place the Gemfile in the same directory as the Rakefile .

Why bundle install is installing gems in vendor bundle?

In deployment, isolation is a more important default. In addition, the user deploying the application may not have permission to install gems to the system, or the web server may not have permission to read them. As a result, bundle install --deployment installs gems to the vendor/bundle directory in the application.

What is the difference between bundle and bundler?

The executables bundle & bundler have the same functionality and therefore can be used interchangeably. You can see in the bundler/exe directory that the bundler executable just loads the bundle executable. It seems to me that the bundle command is more commonly used than the bundler command.

What is the difference between Gemfile and Gemfile lock?

The Gemfile is where you specify which gems you want to use, and lets you specify which versions. The Gemfile. lock file is where Bundler records the exact versions that were installed. This way, when the same library/project is loaded on another machine, running bundle install will look at the Gemfile.


3 Answers

The quick fix is to add -Ilib to your ruby command:

$ bundle exec ruby -e "require 'puppet'; puts Facter.value(:puppetversion)"
3.7.5

$ bundle exec ruby -Ilib -e "require 'puppet'; puts Facter.value(:puppetversion)"
3.7.3

If we compare the load paths, you can see that adding -Ilib results in 3.7.5 not being present in the second load path:

$ diff <(bundle exec ruby -e 'puts $:') <(bundle exec ruby -Ilib -e 'puts $:') | grep 'puppet-'
< /Library/Ruby/Gems/2.0.0/gems/puppet-3.7.5/lib

It seems like this should be the default behavior, so there may be a bug in bundler.

like image 142
Nick Urban Avatar answered Oct 05 '22 23:10

Nick Urban


Provided you've deleted your Gemfile.lock and removed all other versions of the gem before trying bundle exec ... although not explicitly defined by the same problem, this is a known problem with Bundler check this out:

  • https://github.com/bundler/bundler/issues/3585

And it ought to be fixed as of this merged Pull Request:

  • https://github.com/bundler/bundler/pull/3592

This will cause your "preferred source" to be favored, and used.

( Links used as answer because this refers to existing activities, not a solution I could put here in the answer. Not link-only answer. )

like image 39
digitalextremist Avatar answered Oct 05 '22 23:10

digitalextremist


try this :

source "file://home/puppy/puppet-git-clone"

gem "puppet", "3.4.2", :path => "/home/puppy/puppet-git-clone"

why do you need require false?

like image 24
WebQube Avatar answered Oct 05 '22 21:10

WebQube