为具有原生扩展名

时间:2017-09-08 17:57:44

标签: rubygems bundler gemspecs

我在一个工程师团队中工作,他们使用本机可执行文件开发gem。出于合同原因,重要的是当我们部署到新环境时,所有依赖项都使用与我们测试过的完全相同的版本。 Gemfile只能维护一阶依赖版本,而不能维护递归版本。出于这个原因,我们历史上一直将我们的锁文件保存到github中,但是自从1.14发布以来,这阻止了我们升级bundler。问题是我们有OSX和Linux的开发机器,从1.14开始,gem存储库中lockfile的开头改为:

PATH
  remote: .
  specs:
    engine (21.2.13)
      <gemspec dependencies here>

PATH
  remote: .
  specs:
    engine (21.2.13-x86_64-linux)
      <gemspec dependencies here>

这是一个问题,因为当开发人员在OSX上提取仓库并运行bundle install时,它将更改锁定文件的内容。然后,当一个linux开发人员做同样的事情时,它会再次改变,在lockfile的git历史中创建一堆虚假的变化!

我尝试运行bundle lock --add-platform x86_64-linuxbundle lock --add-platform x86_64-darwin,希望这会说服捆绑商为不同平台维护两个条目,而不是在它们之间进行翻转。 确实为锁文件的GEM部分中的某些宝石生成了重复的条目,但是PATH\n specs:部分中没有。

目前,我们的Gemfile包含以下行:

gemspec name: "engine"

加载engine.gemspec。该文件包含:

Gem::Specification.new do |spec|
  ...
  spec.platform = Gem::Platform::CURRENT
  ...
end

我怀疑是问题所在。我尝试在Gemfile中包含gemspec 两次,并使用全局变量指定要使用的平台,但是Bundler只在第一次加载它,并跳过第二次尝试。

有没有人知道一个解决方案,它允许我们将两个平台特定的gem版本保存在同一个锁文件中?

或者,有没有办法关闭Bundler的新行为,将平台名称附加到gem版本?在过去,当lockfile简单地指定“21.2.13”并且我们的gemserver包含每个版本的两个副本(使用为这两个平台构建的二进制文件)时,bundler从来没有解决当前机器的正确版本的任何问题,所以这似乎就像存储多余信息的锁文件一样。我能以某种方式告诉它停止吗?

1 个答案:

答案 0 :(得分:0)

我听说过各种各样的建议,不建议也不建议将你的锁文件保存在版本控制中,但是从来没有完全理解原因。这似乎是问题的根源!

我经常看到的建议(虽然这可能总是可能),但是对于gem来说,锁文件永远不应该受版本控制,但是对于独立的应用程序。我们的想法是gem是可移植的,因此它的依赖性应该具有一定的灵活性。重要的是,这种灵活性不会阻止我们的开发环境保持一致,前提是所有测试都不在gem存储库中,而是在使用gem的独立应用程序的存储库中。

该独立应用程序的锁文件已经跟踪了我们认为我们正在使用gem的锁定文件进行跟踪的依赖关系,并且在部署应用程序时,所有gem的依赖关系都在应用程序内修复,而不是在gem中。

for (i = 0; i < btn.length; i++) { var btnVal = btn[i].value; btn[i].addEventListener("click", function() { displayNumber(btnVal) }, false); } function displayNumber(param) { displayedNum.innerHTML = param; } 的“spec”部分应该仅存在于gem repo中,并且此部分以与平台相关的方式命名gems这一事实不是问题,因为gem是由a引用的使用它的应用程序的lockfile中与平台无关的名称。