【问题标题】:Bundler installing gem that's already installedBundler 安装已安装的 gem
【发布时间】:2015-03-13 13:10:40
【问题描述】:

我相信我误解了 bundler 的工作方式,但从 bundle install documentation 看来,这似乎表明 bundler 将使用本地安装的系统 gem。

...

--system: 安装到系统位置($BUNDLE_PATH 或 $GEM_HOME),即使该捆绑包之前已为此应用程序安装在其他位置

...

--system 选项是默认选项。如下所述,在使用 --path 选项后将其传递给切换回来。

我没有使用 rbenv/rvm 或任何其他 Ruby 版本管理器。我使用 ChefDK 作为我的主要开发环境,它附带 Ruby 和一堆预安装的 gem。

Gemfile的全部内容,还没有Gemfile.lock。

source 'https://rubygems.org'

gem 'nokogiri', '1.6.3.1'

已安装本地 nokogiri

$ gem list --local | grep nokogiri
nokogiri (1.6.6.2, 1.6.3.1, 1.5.5)

系统 Gem 位置已安装 nokogiri 1.6.3.1

$ echo $GEM_HOME
/Users/arthur/.chefdk/gem/ruby/2.1.0
$ find /Users/arthur/.chefdk/gem/ruby/2.1.0 | grep nokogiri | grep 1.6.3.1
/Users/arthur/.chefdk/gem/ruby/2.1.0/cache/nokogiri-1.6.3.1.gem
/Users/arthur/.chefdk/gem/ruby/2.1.0/extensions/x86_64-darwin-12/2.1.0/nokogiri-1.6.3.1
/Users/arthur/.chefdk/gem/ruby/2.1.0/extensions/x86_64-darwin-12/2.1.0/nokogiri-1.6.3.1/mkmf.log
/Users/arthur/.chefdk/gem/ruby/2.1.0/gems/nokogiri-1.6.3.1
/Users/arthur/.chefdk/gem/ruby/2.1.0/gems/nokogiri-1.6.3.1/.autotest
/Users/arthur/.chefdk/gem/ruby/2.1.0/gems/nokogiri-1.6.3.1/.editorconfig
...

但是,当我运行捆绑安装时,它会尝试为 nokogiri 安装和编译 libxml2。

$ bundle install
Fetching gem metadata from https://rubygems.org/.........
Resolving dependencies...
Using mini_portile 0.6.0
Building nokogiri using packaged libraries.
Building libxml2-2.8.0 for nokogiri with the following patches applied:
  - 0001-Fix-parser-local-buffers-size-problems.patch
  - 0002-Fix-entities-local-buffers-size-problems.patch
  - 0003-Fix-an-error-in-previous-commit.patch
  - 0004-Fix-potential-out-of-bound-access.patch
  - 0005-Detect-excessive-entities-expansion-upon-replacement.patch
  - 0006-Do-not-fetch-external-parsed-entities.patch
  - 0007-Enforce-XML_PARSER_EOF-state-handling-through-the-pa.patch
  - 0008-Improve-handling-of-xmlStopParser.patch
  - 0009-Fix-a-couple-of-return-without-value.patch
  - 0010-Keep-non-significant-blanks-node-in-HTML-parser.patch
  - 0011-Do-not-fetch-external-parameter-entities.patch
************************************************************************
IMPORTANT!  Nokogiri builds and uses a packaged version of libxml2.
...

我错过了什么?如何强制捆绑器使用已安装的 nokogiri 1.6.3.1(随 ChefDK 提供)?我试图避免让 nokogiri 编译 libxml2,因为这在许多不同的开发人员/操作工作站上始终失败并且造成了无尽的悲痛。谢谢。

编辑

感谢 Tim Moore,使用 bundle env 我在输出中注意到捆绑器已禁用共享 gem。

$ bundle env
Bundler 1.7.12
Ruby 2.1.4 (2014-10-27 patchlevel 265) [x86_64-darwin12.0]
Rubygems 2.4.4
GEM_HOME /Users/arthur/.chefdk/gem/ruby/2.1.0
GEM_PATH /Users/arthur/.chefdk/gem/ruby/2.1.0:/opt/chefdk/embedded/lib/ruby/gems/2.1.0

Bundler settings
  disable_shared_gems
    Set for the current user (/Users/arthur/.bundle/config): "1"


Gemfile
source 'https://rubygems.org'
...

查看~/.bundle/config,果然设置了全局配置。

---
BUNDLE_DISABLE_SHARED_GEMS: '1'

一旦删除,Bundler 会正确解析 nokogiri 1.6.3.1,并且不会尝试重新安装它。默认情况下,此设置不应该存在,默认情况下捆绑程序使用--system 安装。我一定是在几个月前设置了这个设置,但我忘记了。

【问题讨论】:

  • 这可能是因为其他一些 gem 正在将不同版本的 nokogiri 作为依赖项拉取吗?
  • 但是 Gemfile 中只有一个 gem。
  • 嗯.. 这就是完整的 Gemfile。对不起,不知道。
  • 你能发布锁定文件吗? gemfile 锁有什么版本差异吗?
  • @0v3rc10ck3d 我已经删除了锁定文件,只是想从头开始构建。

标签: ruby gem chef-infra bundler


【解决方案1】:

尝试运行bundle env 以验证安装位置是否符合您的预期。

如果没有,请检查是否存在覆盖安装路径的 .bundle/config~/.bundle/config 文件。 bundle env 的输出将告诉您它正在使用什么配置以及它是如何确定的(即它在哪个文件中,或者它是否是从环境变量中提取的)。

【讨论】:

  • 我在输出中得到这个:Bundler settings disable_shared_gems Set for the current user (/Users/arthur/.bundle/config): "1",是这样吗?
  • 该设置确实禁用了--system 的默认值,但如果没有path 设置,它通常不会单独出现。尝试显式运行 bundle install --system 以重置为默认行为。
  • 就是这样!!就是这样的设定! --system 是默认设置,这就是为什么我从没想过 Bundler 会做一些不同的事情。显然在某些时候我把BUNDLE_DISABLE_SHARED_GEMS: '1' 放在我的~/.bundle/config 中,这就是为什么--system 没有启用。这完全解释了它,非常感谢!
  • Bundler 有点令人困惑的是它会保存标志,所以即使 --system 是干净项目中的默认值,如果您使用任何其他标志运行 bundle install,这些标志也会存储在配置文件并有效地更改未来运行的默认值。
  • 是的,那一定是很久以前发生的,并造成了所有这些混乱。再次感谢您解决这个问题!
【解决方案2】:

尝试删除 gemfile.lock 文件的所有内容。保存文件。再次运行捆绑安装。

【讨论】:

  • 不幸的是,这是在没有 Gemfile.lock 的情况下运行 bundle install
【解决方案3】:

有几种方法。在 gemfile 中,您可以指定从那里强制使用 bundle 的路径。

gem "my_gem", :path => "path to gem"

正如我所见,问题在于此处的默认路径。尝试这样做。

【讨论】:

  • 感谢您的建议,不幸的是 nokogiri 没有include a gemspec。所以我得到Could not find gem 'nokogiri (>= 0) ruby' in source at /opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/nokogiri-1.6.3.1.
【解决方案4】:

ChefDK 不会全局安装 gem,它会将它们安装在 /opt/chefdk 下,因此它们不会干扰“您的”全局 gem。我建议您将 ChefDK gems 保持原样。

【讨论】:

  • 我使用 Chef 作为主要开发环境,所有本地安装的 gem 都进入 ~/.chefdk。我的目标是尝试明确使用 ChefDK 安装的 nokogiri,因此当其他 Chef 开发人员执行 bundle install 时,Bundler 不会尝试安装 nokogiri(从而导致编译过程失败),而是使用nokogiri 已经在那里了。
【解决方案5】:

您需要使用正确的bundlergem。如果您使用的是 ChefDK,那么它包含自己的 bundlergem 可执行文件。它们应该在/opt/chefdk 目录中,我相信在/opt/chefdk/embedded 下(我不使用chefdk,所以我可以100% 确定)。

要在该 ruby​​ 安装中 100% 工作,您需要确保 chefdk 二进制文件在其他 ruby​​ 相关二进制文件之前位于您的路径中。您可以使用 which ruby which gemwhich bundle 进行验证。

说了这么多,你真的不应该为 chefdk 的 ruby​​ 安装搞乱。它被嵌入是有原因的,这样你就不会不小心把它搞砸了。我建议您为自己的工作坚持使用系统 ruby​​,并让 Chef 处理它的 ruby​​。

【讨论】:

【解决方案6】:

来自 Bundler docs:

--path:指定与系统默认路径不同的路径($BUNDLE_PATH 或 $GEM_HOME)。 Bundler 会记住这个值以供以后安装 这台机器

您的捆绑器可能缓存了 --path 指定的安装命令。 试试:

bundle install --system

这将告诉 bundler 使用系统安装的 gem,而不是将新的 gem 副本下载到特定文件夹的 gem 集合中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-04-02
    • 1970-01-01
    • 2015-03-05
    • 2011-04-20
    • 1970-01-01
    • 2013-05-02
    • 1970-01-01
    相关资源
    最近更新 更多