为什么捆绑器使用多个 gem 位置?
Why does bundler use more than one gem location?
这发生在 Puppet's 捆绑包中。
Gemfile
specifies
gem "puppet", :path => File.dirname(__FILE__), :require => false
但是我在$GEM_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 将加载 Puppet 3.7.5
而不是 3.7.3
我从 git 存储库中检出。
$ 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
会如实报告错误值,从而摆脱捆绑程序。这可能是正在发生的事情吗?
更新 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.
前提是您在尝试 bundle exec
之前删除了 Gemfile.lock
并删除了 gem 的所有其他版本...虽然没有明确定义相同的问题,但这是一个Bundler
的已知问题检查一下:
它应该在这个合并的合并请求中得到修复:
这将使您的 "preferred source" 受到青睐和使用。
(链接用作答案,因为这指的是现有活动,而不是我可以放在答案中的解决方案。不是 link-唯一的答案。)
试试这个:
source "file://home/puppy/puppet-git-clone"
gem "puppet", "3.4.2", :path => "/home/puppy/puppet-git-clone"
为什么需要 require false?
按照你在我之前的回答中所说的,试试这个:
将 gemspec
添加到靠近顶部的 Gemfile
。
如果您这样做,后续的 gem ...
调用将覆盖最终设置版本的 gemspec
。
在此处添加:
source ENV['GEM_SOURCE'] || "https://rubygems.org"
gemspec # and let me know if this fixes it
正如我最近所说,我在自己的项目中发现了与您相同的问题。我已经通过解决方法解决了它。这个想法本身就是我在这里给出的,我并不是说它是最有效或无错误的方式。这种方法的变体对我有用。
它涉及劫持 Gemfile
,也许 gemspec
,具体取决于现实中的罪犯 - 这部分仍然未知。我最近的回答,我给出的第二种方法已经可以解决这个问题。如果没有,您可能需要一个解决方法。 Bundler 面临许多僵局。
作为解决方法,请插入策展人。
我建议,在 Gemfile
的末尾插入一个这样的处理器,自己管理 Bundler::Dsl
。我们可以完全专注于您要解决的 gem,但它可以针对所有 gem 解决。
例如...这主要是一个概念,它可能 运行,但它可能有一个错误。你需要加强它。这将删除除您期望的版本之外的所有内容:
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
这似乎应该是默认行为,因此捆绑程序中可能存在错误。
我过去也遇到过同样的问题,我想你可以在没有 'require: false' 参数的情况下指定 gem,它会查找 Gemfile 特定版本。
gem "puppet", "3.4.2", :path => "/home/puppy/puppet-git-clone"
如果您使用 'gem' 指定 'require' 选项,使用 bundle exec irb
指定 运行 irb 命令,它总是加载 gem 的最新版本已使用 require: false
选项声明。
这发生在 Puppet's 捆绑包中。
Gemfile
specifies
gem "puppet", :path => File.dirname(__FILE__), :require => false
但是我在$GEM_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 将加载 Puppet 3.7.5
而不是 3.7.3
我从 git 存储库中检出。
$ 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
会如实报告错误值,从而摆脱捆绑程序。这可能是正在发生的事情吗?
更新 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.
前提是您在尝试 bundle exec
之前删除了 Gemfile.lock
并删除了 gem 的所有其他版本...虽然没有明确定义相同的问题,但这是一个Bundler
的已知问题检查一下:
它应该在这个合并的合并请求中得到修复:
这将使您的 "preferred source" 受到青睐和使用。
(链接用作答案,因为这指的是现有活动,而不是我可以放在答案中的解决方案。不是 link-唯一的答案。)
试试这个:
source "file://home/puppy/puppet-git-clone"
gem "puppet", "3.4.2", :path => "/home/puppy/puppet-git-clone"
为什么需要 require false?
按照你在我之前的回答中所说的,试试这个:
将 gemspec
添加到靠近顶部的 Gemfile
。
如果您这样做,后续的 gem ...
调用将覆盖最终设置版本的 gemspec
。
在此处添加:
source ENV['GEM_SOURCE'] || "https://rubygems.org"
gemspec # and let me know if this fixes it
正如我最近所说,我在自己的项目中发现了与您相同的问题。我已经通过解决方法解决了它。这个想法本身就是我在这里给出的,我并不是说它是最有效或无错误的方式。这种方法的变体对我有用。
它涉及劫持 Gemfile
,也许 gemspec
,具体取决于现实中的罪犯 - 这部分仍然未知。我最近的回答,我给出的第二种方法已经可以解决这个问题。如果没有,您可能需要一个解决方法。 Bundler 面临许多僵局。
作为解决方法,请插入策展人。
我建议,在 Gemfile
的末尾插入一个这样的处理器,自己管理 Bundler::Dsl
。我们可以完全专注于您要解决的 gem,但它可以针对所有 gem 解决。
例如...这主要是一个概念,它可能 运行,但它可能有一个错误。你需要加强它。这将删除除您期望的版本之外的所有内容:
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
这似乎应该是默认行为,因此捆绑程序中可能存在错误。
我过去也遇到过同样的问题,我想你可以在没有 'require: false' 参数的情况下指定 gem,它会查找 Gemfile 特定版本。
gem "puppet", "3.4.2", :path => "/home/puppy/puppet-git-clone"
如果您使用 'gem' 指定 'require' 选项,使用 bundle exec irb
指定 运行 irb 命令,它总是加载 gem 的最新版本已使用 require: false
选项声明。