2012-07-18 58 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

相關問題