有没有办法打包所有的宝石我的宝石取决于我的宝石?

时间:2013-07-09 12:25:04

标签: ruby-on-rails ruby rubygems bundler gemspecs

我正在编写一个有几个gem依赖项的gem,其中一个依赖于一个在新版本中破坏了向后兼容性的gem。这让我思考 - 我不希望我正在构建的宝石成为“那个宝石”,这让人们很难更新他们的应用程序。我也不想强迫使用我的宝石的人必须在其他应用程序中使用它所依赖的特定版本的宝石。

一方面,我可以重写这些依赖项中的所有代码,将它们与我的gem捆绑在一起,并将所有依赖项一起删除,但这似乎有点单调乏味。有没有办法让我直接在我的gem中包含gem依赖项,然后将它们包装在一个模块中,这样我的打包版本就不会与应用程序其余部分使用的版本冲突?

2 个答案:

答案 0 :(得分:1)

我不认为你想要的是通过现有的Ruby工具。但是,如果依赖于依赖项的向后兼容性纯粹是语法/使用问题,而不是版本之间的低级别差异,那么您不必导入和维护旧的gem代码。您还有另一种选择:在gem中创建一个“shim”图层,从依赖项的新旧界面提供所需的功能。

在实践中它可能看起来像这样,假设它是Thingy类的构造函数已经改变:

module DependencyShim

  def new_Thingy( new_style_args )
    if thingy_is_new
      Thingy.new( new_style_args )
    else
      Thingy.new( convert_args_to_old_style( new_style_args ) )
    end
  end

  # convert_args_to_old_style() not shown

  private

  def thingy_is_old
    Thingy::VERSION < '1.3.4'
  end

  def thingy_is_new
    Thingy::VERSION >= '1.3.4'
  end
end

很可能有更好的抽象,但很难预测,因为我不知道新旧差异的性质,以及代码与依赖关系的紧密程度。

如果版本之间存在根本性的变化,那么这显然很痛苦,并且您自己的gem会大量使用依赖项。但即便如此,它仍然可能比重新实现和维护自己的gem中的依赖更少痛苦。

我建议您考虑让您的gem 与最新版本的依赖项兼容,并根据您对用户的了解,长期不再支持旧的依赖项基础。所有参与者都可能有充分的理由摆脱旧的依赖。

答案 1 :(得分:0)

假设您正在使用bundler,您可以在Gemfile中指定依赖项的版本,如下所示:

gem "my_dependency", "0.6.1"

还有一大堆其他选项,例如“版本大于X”等。请阅读bundler docs以获取更多信息。