为什么bundler使用多个gem位置?

Fel*_*ank 11 ruby gem rubygems puppet bundler

这是在Puppet的捆绑中发生.

Gemfile 指定

gem "puppet", :path => File.dirname(__FILE__), :require => false
Run Code Online (Sandbox Code Playgroud)

但是我安装的其中一颗宝石毕竟$GEM_HOME出现了$:.

$ 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
...
Run Code Online (Sandbox Code Playgroud)

这本身并不是问题,但显然Ruby会加载Puppet 3.7.5而不是3.7.3我检出的git repo.

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

为什么Puppet没有从git树加载,我该如何进一步调试呢?

更新

木偶.gemspec可能会参与其中.它在指定版本方面很聪明.我现在担心Rubygems实际上会加载已安装的3.7.5gem,以便Puppet.version真实地报告错误的值,抛弃bundler.这可能是发生了什么?

更新2

正如评论中所建议的那样,我尝试静态设置路径和版本Gemfile.

gem "puppet", "3.4.2", :path => "/home/puppy/puppet-git-clone", :require => false
Run Code Online (Sandbox Code Playgroud)

至于结果,至少bundler在其观点中是一致的;-)

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.
Run Code Online (Sandbox Code Playgroud)

Nic*_*ban 4

快速修复方法是添加-Ilib到您的 ruby​​ 命令中:

$ 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
Run Code Online (Sandbox Code Playgroud)

如果我们比较加载路径,您可以看到添加-Ilib结果 3.7.5 不存在于第二个加载路径中:

$ 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
Run Code Online (Sandbox Code Playgroud)

看起来这应该是默认行为,因此捆绑器中可能存在错误。