【问题标题】:How to require a specific gem version in rails gemfile?如何在 rails gemfile 中要求特定的 gem 版本?
【发布时间】:2015-07-07 08:09:31
【问题描述】:

在 Rails 4 中通过 bundle install 安装 gem 时,出现以下错误:

Bundler could not find compatible versions for gem "tzinfo":

  In Gemfile:
    rails (= 4.2.0) ruby depends on
      actionmailer (= 4.2.0) ruby depends on
        actionpack (= 4.2.0) ruby depends on
          activesupport (= 4.2.0) ruby depends on
            tzinfo (~> 1.1) ruby

    eventbrite-client (>= 0) ruby depends on
      tzinfo (~> 0.3.22) ruby

我尝试使用 bundle update 解决此问题,但解决了同样的问题。

现在的问题是,如何使 gem eventbrite-client 依赖于 tzinfo 的 0.3.22 版本。我无法弄清楚我尝试过的语法:

gem 'eventbrite-client', :require => 'tzinfo','0.3.22'

这可能吗?

【问题讨论】:

  • 如果我理解正确,那么 rails 4.2 的依赖链部分依赖于 tzinfo v1.1。所以我认为不可能像 v0.3.22 那样使用它的旧版本(我不知道在一个应用程序中拥有两个版本的相同 gem 的任何方法)。因此,我想在这种情况下,您必须选择哪个对您更重要-让 rails 4.2 工作或 eventbrite-client :)
  • 删除 Gemfile.lock 并通过在您的 gemfile 中添加特定版本再次运行 bundle install...试试看

标签: ruby-on-rails ruby-on-rails-4 bundler gemfile


【解决方案1】:

如果您想让 event-brite 客户端以某种方式工作,那么您可以简单地在 eventbrite gemspec 文件中增加 tzinfo 依赖项的版本。

首先克隆以下仓库

git clone git@github.com:ryanjarvinen/eventbrite-client.rb.git

然后将 eventbrite-client.gemspec 文件的内容替换为以下内容。

Gem::Specification.new do |s|
  s.name = %q{eventbrite-client}
  s.version = "0.1.3"

  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
  s.authors = ["Ryan Jarvinen"]
  s.date = %q{2011-08-28}
  s.description = %q{A tiny EventBrite API client. (http://developer.eventbrite.com)}
  s.email = %q{ryan.jarvinen@gmail.com}
  s.extra_rdoc_files = [
    "LICENSE",
    "README.md"
  ]
  s.files = [
    ".document",
    "LICENSE",
    "README.md",
    "Rakefile",
    "VERSION",
    "eventbrite-client.gemspec",
    "lib/eventbrite-client.rb",
  ]
  s.homepage = %q{http://github.com/ryanjarvinen/eventbrite-client.rb}
  s.require_paths = ["lib"]
  s.rubygems_version = %q{1.6.2}
  s.summary = %q{A tiny EventBrite API client}

  if s.respond_to? :specification_version then
    s.specification_version = 3

    if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
      s.add_development_dependency(%q<rspec>, ["~> 1.3.0"])
      s.add_runtime_dependency(%q<httparty>, ["~> 0.8.0"])
      s.add_runtime_dependency(%q<tzinfo>, ["~> 1.1"])
    else
      s.add_dependency(%q<rspec>, ["~> 1.3.0"])
      s.add_dependency(%q<httparty>, ["~> 0.8.0"])
      s.add_dependency(%q<tzinfo>, ["~> 1.1"])
    end
  else
    s.add_dependency(%q<rspec>, ["~> 1.3.0"])
    s.add_dependency(%q<httparty>, ["~> 0.8.0"])
    s.add_dependency(%q<tzinfo>, ["~> 1.1"])
  end
end

然后你可以用

重建gem
gem build eventbrite-client.gemspec

使用安装它

gem install ./name_of_the_gem.gem

【讨论】:

  • 如果您只是覆盖依赖项gem 版本,那么新版本的gem 可能不支持旧版本gem 的所有功能总是存在风险。因此它可能会刹车。此外,如果您对 dependency-gem 的 repo-code 进行了更改并且不再将其向上推(假设较新的 dependency-gem 版本确实没有刹车),那么其他从 repo 中提取 -your- 应用程序的人不会获得相同的更改依赖项宝石版本,因此他们的应用程序仍然损坏。
  • 做到了,似乎正在启动。将检查该功能是否有效。如果确实如此,也将提交更改。 ty
  • @AndresEhrenpreis 是的,你说的是对的,但是大多数时候在构建 gem 时,开发人员会添加可用的最新版本作为依赖项,如果 gem 可以正常工作,可以尝试使用上述方法只需升级 gem 依赖项。如果可行,他可以分叉并推送这些更改,并将 git 路径添加到 gem 文件中,以便其他将拉他的应用程序的人可以使用它。
  • 当您遇到类似的问题并注意到 gem 的依赖项被定义为缩小时,您可能会考虑针对原始 gem 进行 PR。
【解决方案2】:

我认为您的想法是不可能的(如果您想同时拥有一个有效的rails 4.2)。正如 bundler 所说,rails 4.2 需要tzinfo v1.1,因此旧版本的 Rails 不能接受。不允许在一个工作应用程序中使用相同 gem 的 2 个不同版本,因为代码将如何影响使用哪一个?

关于在一个应用程序中同时拥有两个不同版本的 gem 可能是一个有用的答案:Can you have multiple versions of a gem in a Gemfile?

另一个关于 2 个 gem 具有冲突的依赖关系和解决问题的可能性的答案:How to override gem dependency? 但我想在你的情况下这是不可能的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-09
    • 1970-01-01
    • 2011-11-11
    • 1970-01-01
    • 2011-05-28
    相关资源
    最近更新 更多