Ruby 为什么bundler使用多个gem位置?
这是捆绑式的Ruby 为什么bundler使用多个gem位置?,ruby,gem,rubygems,bundler,puppet,Ruby,Gem,Rubygems,Bundler,Puppet,这是捆绑式的 Gemfile 但是我在$GEM\u HOME中安装的一个GEM毕竟出现在$:中 $ 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将加载Puppet3.7.5,而不是我从git回购中签出的3.7.3 $ bu
Gemfile
但是我在$GEM\u HOME
中安装的一个GEM毕竟出现在$:
中
$ 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将加载Puppet3.7.5
,而不是我从git回购中签出的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树加载的,我如何进一步调试它
更新
木偶.gempec
可能涉及其中。它是关于指定版本的。我现在担心Rubygems实际上加载了安装的3.7.5
gem,这样Puppet.version
就会如实地报告错误的值,从而抛出bundler。这就是发生的事吗
更新2
正如评论中所建议的,我尝试在Gemfile
中静态设置路径和版本
gem "puppet", "3.4.2", :path => "/home/puppy/puppet-git-clone", :require => false
就结果而言,well-至少bundler的观点是一致的;-)
如果您在尝试
bundle exec
之前删除了Gemfile.lock
并删除了所有其他版本的gem,则。。。虽然未明确定义为同一问题,但这是捆绑机的已知问题检查:
source "file://home/puppy/puppet-git-clone"
gem "puppet", "3.4.2", :path => "/home/puppy/puppet-git-clone"
为什么需要输入false?在我上一个答案中所说的内容之后,尝试以下方法: 将
gempec
添加到顶部附近的Gemfile
。
如果执行此操作,后续的gem…
调用将覆盖最终设置版本的gempec
将其添加到此处:
就像我最近说的,我在我自己的项目中发现了与你相同的问题。我已经解决了这个问题。这个想法本身就是我在这里给出的,我并不是说这是最有效或没有bug的方法。这种方法的一种变体对我有效 它包括劫持
Gemfile
,也许还包括gempec
,这取决于罪犯的实际身份——这一部分还不清楚。我最近的回答,我给出的第二种方法已经可以解决这个问题了。如果没有,您可能需要解决方法。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.3
,3.7.5
。。。只要插上你想要的。任何其他版本都将从Bundler使用的依赖项中清除。快速修复方法是将-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
如果我们比较加载路径,您可以看到添加-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
$diff我过去也遇到过同样的问题,我认为您可以在不使用'require:false'参数的情况下指定gem,它将查找特定于Gemfile的版本
gem "puppet", "3.4.2", :path => "/home/puppy/puppet-git-clone"
如果您使用“gem”指定“require”选项,并使用bundle exec irb
运行irb命令,它将始终加载使用require:false
选项声明的gems的最新版本。您使用的bundler版本是什么?这听起来像是bundler在2个带标签的版本之前出现的一个已知问题。@ChaseGilliam我可以用bundler1.7.4
和1.9.4
复制,不幸的是。尝试给它一个像gem“puppet”这样的绝对路径:path=>“/home/pupper/puppet git clone”@ChaseGilliam同样的效果。我使用bundle update--verbose
四处搜索,并将用一个小发现更新问题。以这种方式报告版本是相当典型的,我怀疑这是问题所在。可以尝试在GEM文件中指定版本。:require
来自上游。移除它对结果没有影响。好主意,我有一种潜移默化的怀疑,那就是hiera
gem,它依赖于puppet
gem。但是,将该修补程序应用于bundler1.9.4
并不能解决该问题。删除Gemfile.lock
无效。未删除3.7
gem。如果没有安装不同版本的gem,那么整个问题就不存在了。很抱歉听到的不是这个答案。在遇到类似问题后,我发布了另一个我想到的。我喜欢它的简单性。当不直接调用ruby时,也会这样做:RUBYLIB=lib bundle exec puppet代理--version
-但这种变通方法感觉是多余的。如果没有其他答案,我就要了。有趣。还是坏了,但是现在我得到了这个警告:lib/puppet/version.rb:10:warning:constant PUPPETVERSION已经初始化了,来自git repo中的文件。感谢所有的努力,但是由于没有解决方案,我不能公平地授予你奖杯。祝你下次好运<代码>未定义的局部变量或Gemfile的方法“dsl”
更新了该方法。它实际上是self
而不是dsl
。很抱歉。它是Bundler::Dsl
的一个实例,产生了一个错误。使用--verbose
它说Gemfile:85:in'eval_Gemfile:#(NoMethodError)
来自$HOME/gems/gems/bundler-1.9.4/lib/bundler/dsl.rb:32:in'instance_eval'
这基本上是WebQube的答案。这样做是不可能的
$ 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
$ 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
gem "puppet", "3.4.2", :path => "/home/puppy/puppet-git-clone"