构建ruby gem并有条件地指定依赖项

wor*_*ing 19 ruby gem conditional dependencies

我正在研究一个gem,它需要在安装gem时有条件地设置依赖项.我做了一些挖掘

看起来我并不孤单.

Rubygems:如何添加特定于平台的依赖项?

这是一个很长的线索

http://www.ruby-forum.com/topic/957999

我可以看到向gem添加依赖项的唯一方法是在.gemspec文件中的Gem :: Specifiction块中使用add_dependency方法

Gem::Specification.new do |s|

  # ... standard setup stuff

  # conditionally set dependencies
  s.add_dependency "rb-inotify", "~> 0.8.8" if RUBY_PLATFORM =~ /linux/i
  s.add_dependency "rb-fsevent", "~> 0.4.3.1" if RUBY_PLATFORM =~ /darwin/i
  s.add_dependency "rb-fchange", "~> 0.0.5" if RUBY_PLATFORM =~ /mswin|mingw/i

end
Run Code Online (Sandbox Code Playgroud)

基于我在网上找到的所有文档和线程,我希望如果你安装gem

  • 那么,Linux,rb-inotify将是一个依赖项并自动安装
  • 将安装Mac-rb-fsevent
  • Windows-rb-fchange将被安装

但是,似乎并非如此.块中的"if"语句在构建和打包gem时进行评估.因此,如果您在Linux上构建并打包gem,那么,rb-inotify将作为依赖项添加,然后是rb-fsevent,Windows-rb-fchange.

仍然需要一个解决方案,我在rubygems代码中挖掘出来,似乎以下内容是对发生的事情的广泛描述.

  • 为你的gem构建所有代码:foo.gem
  • 创建一个foo.gemspec文件
  • 构建,打包并将gem发布到gem服务器,例如rubygems.org
  • 让大家知道
  • 开发人员通过以下方式在本地安装:gem install foo
  • 下载,解压缩并安装foo.gem文件.也安装了所有依赖项.
  • 一切都应该设置,我们可以使用宝石.

看来,当宝石是建立和释放的foo.gemspec文件被加载并在宝石::规格块被评估并转换为YAML,压缩为metadata.gz,并包含在foo.gem.ruby代码被压缩成data.tar.gz并包含在内.当gem安装在本地开发人员机器上时,YAML从metadata.gz中提取并转换回Gem :: Specification块,但是,它不会转换回原始块.

相反,你会看到如下内容:

Gem::Specification.new do |s|

  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_runtime_dependency(%q<rb-inotify>, ["~> 0.8.8"])
    else
      s.add_dependency(%q<rb-inotify>, ["~> 0.8.8"])
    end
  else
    s.add_dependency(%q<rb-inotify>, ["~> 0.8.8"])
  end

end
Run Code Online (Sandbox Code Playgroud)

好.因此,我对该过程有一个鸟瞰图,但这并没有改变我构建单个gem的愿望,并有条件地为一系列OS目标指定依赖关系.

如果有人有解决方案,而不是为每个目标操作系统构建多个.gemspec文件...我都是耳朵!

pho*_*oet 1

我自己从来没有这样做过,但是有一些 gem 在特定于平台的版本中可用:http://rubygems.org/gems/libv8/versions

据我了解,这只是一个命名问题,可以通过设置 gemspec 的平台选项来配置。看看文档: http: //guides.rubygems.org/specification-reference/#platform=