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

时间:2015-04-17 20:53:41

标签: ruby gem rubygems bundler puppet

这发生在Puppet's捆绑包中。

Gemfile specifies

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

但我在$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
...

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

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

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

更新

可能涉及木偶.gemspec。关于指定版本是clever。我现在担心Rubygems实际上会加载已安装的3.7.5 gem,以便Puppet.version真实地报告错误的值,抛弃bundler。这可能是发生了什么?

更新2

根据评论中的建议,我尝试在Gemfile中静态设置路径和版本。

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

至于结果,至少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.

4 个答案:

答案 0 :(得分:4)

快速解决方法是将<div id="wrapper" > <ul id="bote" data-position="left" class="animBlock"> <li class="animBlock_left"> <svg x="0px" y="0px" viewBox="135 994 417 522" > <g> <g> <path fill="#BCBEC0" d="M153.1,1489.8c0,14,11.4,25.4,25.4,25.4H509c13.9,0,25.4-11.4,25.4-25.4v-406.9H153.1V1489.8z"/> <path fill="#D1D3D4" d="M447.8,1125.6c0-7,5.7-12.7,12.7-12.7h20.8c7,0,12.7,5.7,12.7,12.7v345.2c0,7-5.7,12.7-12.7,12.7h-20.8 c-7,0-12.7-5.7-12.7-12.7V1125.6z"/> <path fill="#D1D3D4" d="M363,1125.6c0-7,5.7-12.7,12.7-12.7h20.8c7,0,12.7,5.7,12.7,12.7v345.2c0,7-5.7,12.7-12.7,12.7h-20.8 c-7,0-12.7-5.7-12.7-12.7V1125.6z"/> <path fill="#D1D3D4" d="M278.2,1125.6c0-7,5.7-12.7,12.7-12.7h20.8c7,0,12.7,5.7,12.7,12.7v345.2c0,7-5.7,12.7-12.7,12.7h-20.8 c-7,0-12.7-5.7-12.7-12.7V1125.6z"/> <path fill="#D1D3D4" d="M193.4,1125.6c0-7,5.7-12.7,12.7-12.7h20.8c7,0,12.7,5.7,12.7,12.7v345.2c0,7-5.7,12.7-12.7,12.7h-20.8 c-7,0-12.7-5.7-12.7-12.7V1125.6z"/> </g> <path fill="#A7A9AC" d="M539.4,1019.2h-121v-13.1c0-7-5.7-12.7-12.7-12.7h-124c-7,0-12.7,5.7-12.7,12.7v13.1H148 c-7,0-12.7,5.7-12.7,12.7v38.3c0,7,5.7,12.7,12.7,12.7h391.4c7,0,12.7-5.7,12.7-12.7v-38.3C552.1,1024.9,546.4,1019.2,539.4,1019.2 z"/> </g> </svg> </li> <li id="boteTxt" data-position="right" class="animBlock_right"> <h3>The New Product</h3> <p>some deescription about the product</p> </li> </ul> </div>添加到ruby命令:

-Ilib

如果我们比较加载路径,您可以看到添加$ 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 导致3.7.5不存在于第二个加载路径中:

-Ilib

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

答案 1 :(得分:1)

如果您在尝试Gemfile.lock之前删除了bundle exec并删除了所有其他版本的gem ...虽然没有明确定义同一问题,但这是{{1的已知问题检查一下:

在合并的Pull Request中应该修复它:

这将使您的“首选来源”受到青睐和使用。

(链接用作答案,因为这是指现有的活动,而不是我可以在答案中提出的解决方案。不是仅链接答案。)

答案 2 :(得分:1)

试试这个:

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

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

为什么你需要虚假?

答案 3 :(得分:1)

就像我最近说过的那样,在我自己的项目中,我发现了同样的问题。我通过解决方法解决了这个问题。这个想法本身就是我在这里给出的,我并不是说它是最有效或无错误的方式。这种方法的一种变体对我有用。

它涉及劫持Gemfilegemspec,取决于现实中的罪犯 - 该部分仍然未知。我最近的回答,我给出的第二种方法可以解决这个问题。如果没有,您可能需要一个解决方法。 Bundler有许多常见的僵局。

作为解决方法,请插入一位策展人。

我建议,在Gemfile末尾插入一个像这样的处理器来自己策划Bundler::Dsl。我们可以完全专注于您希望解决的宝石,但它可以为任何和所有宝石完成。

例如......这主要是一个概念,它可能会运行,但它可能有一个bug。你需要强化它。除了您期望的版本之外,这将删除所有内容:

PUPPET_VERSION = 'version desired'
until(current = self.dependencies.find { |d| d.name == 'puppet' }) == 1
    current.each { |gem|
        if !gem.version == PUPPET_VERSION
            self.dependencies.delete(current)
        end
    }
end

我不确定你真正想要的版本。提到了三个版本,3.7.33.7.5 ...只需插入您想要的版本。任何其他版本都将从Bundler正在使用的依赖项中清除。