2012-07-18 37 views
3

我的问题如何结合来自多个Gemfiles的宝石来运行一个Ruby程序?

假设我有一个目录结构是这样的:

app/ 
    core/ 
     bin/ 
      runner 
     Gemfile 
     ... 
    Gemfile 
    lib/ 

“核心”是有其自身的Gemfile和Gemfile.lock的应用程序。我不想以任何方式修改核心。 app/Gemfile是我的核心插件的一部分,它也有一个Gemfile(列出了它自己的依赖关系,它是core/Gemfile的附加物)。

我可以从app/core /和app /目录“捆绑安装”。

如何从应用程序/目录运行core/bin/runner,使其包含来自app/core/Gemfile和app/Gemfile的所有Ruby gems?

背景

我写Logstash一个插件,用C红宝石。 Logstash包含它自己的Gemfile;一旦所有的依赖被提取,总的包大小约为40MB。

我想在Heroku中运行Logstash。为了避免把40MB的东西放到Git中,我分叉了Ruby buildpack(https://github.com/inscitiv/heroku-buildpack-logstash)并修改它以下载Logstash,解压缩它,并使用它的Gemfile。

这工作正常,但我坚持Logstash提供的Gemfile。对于我的插件,我想添加我的插件将使用的新依赖项;我真的不想分叉Logstash并更改其Gemfile以完成此操作。我想将Logstash解压到它自己的目录(logstash /)中,然后我想将我的插件代码(包括依赖关系的Gemfile)覆盖在它上面。然后我想运行一个Heroku“worker”进程,它将运行logstash,指定“。”。作为插件目录,并且可以访问来自两个Gemfiles的所有宝石。

回答

2

答案是顶层Gemfile应该包含子目录Gemfiles。

像这样(从管理平台2.0的Gemfile)

# Load plugins' Gemfiles 
Dir.glob File.expand_path("../plugins/*/Gemfile", __FILE__) do |file| 
    puts "Loading #{file} ..." if $DEBUG # `ruby -d` or `bundle -v` 
    instance_eval File.read(file) 
end 
1

为了使bundler能够正确地获得所有gem依赖关系,它确实需要将它们全部放在一个文件中。你可以让你的插件成为宝石,并让你的部署例程添加一个宝石到父Gemfile?然后,您自己的宝石可以列出可以融入整体的依赖关系。

+1

一个问题是,Heroku的要求Gemfile.lock的存在并且是最新的。所以我将不得不分叉Logstash并更新Gemfile和Gemfile.lock;我试图避免。 – kgilpin 2012-07-18 17:06:49

+1

这就是Bundler和Gemfiles的全部内容 - 它将开发时的依赖树锁定在一起,甚至在放入源代码控制之前。然后在部署时,它将安装完全相同的环境。它这样做的唯一方法意味着顶级Gemfile.lock必须事先列出所有依赖关系。这听起来就像你试图在飞机上安装新的飞机上的门。 – DGM 2012-07-18 17:19:49

相关问题