2012-09-02 32 views
20

將bundler與一般項目和Rails專門一起使用時,只能訪問Gemfile中定義的gem。雖然這是有道理的,但它可能是有限的。大多數情況下,當我想使用某個RSpec格式化器時,我發現它是有限的,而其餘的團隊不使用它。除非它在Gemfile中,否則它是不可訪問的。如何在使用捆綁器時使用不在Gemfile中的gem?

任何方式,否則我必須將它添加到Gemfile?

更新:我的問題不是Bundler而是Spork。在沒有Spork的情況下運行RSpec時,我沒有使用任何我想要的格式化程序的問題。

更新#2:它看起來像使用Bundler仍然是問題的原因。使用Spork和不使用Spork的不同之處在於,在不使用Spork的情況下運行RSpec時,它會在加載項目並進入Bundler「沙箱」之前加載格式化程序。

隨着捆紮機:

$ bundle exec irb 
>> require 'fivemat' 
LoadError: cannot load such file -- fivemat 

from (irb):1:in `require' 
from (irb):1 
from /Users/arikfr/.rvm/rubies/ruby-1.9.3-p194/bin/irb:16:in `<main>' 

沒有捆紮機:

$ irb 
>> require 'fivemat' 
=> true 
+0

你爲什麼不fivemat添加到您的的Gemfile? –

+4

「當我想使用某個RSpec格式化程序時,大多數情況下我發現它是有限的,而其餘的團隊不使用它。」這就是爲什麼。有時候我也想使用在OS/X上支持但在Ubuntu上不支持的gem(反之亦然)。 – arikfr

+0

的OS X/Linux的問題可以在Gemfile中通過檢查Ruby平臺https://github.com/carlhuda/bundler/issues/663#issuecomment-2849045 –

回答

10

我認爲沒有回答這些問題,因爲他們不這樣做解決問題的一個偉大的工作,被選爲正確的:具有您可以使用默認不需要對文件進行任何更改額外的寶石已經在存儲庫中實現了。也就是說,您不必修改任何文件,而且您不必記住不檢查本地更改。這是我如何做到的。

這個想法基本上顛倒了Holger答案的依賴關係,因此不需要修改共享的Gemfile。 Bundler允許指定which file is to be used as the gemfile,但奇怪的是記錄的方法do not apparently work with its configuration file and will not be fixed。 Bundler的功能有些模糊,任何配置選項都可以在環境變量中設置或在命令行上傳遞。運行所有命令bundle [command] --gemfile [yourgemfile]BUNDLE_GEMFILE="[yourgemfile]" bundle [command]將導致Bundler讀取您想要的任何gem文件。我強烈建議使用環境變量方法,併爲當前會話創建別名或導出變量,特別是因爲我無法通過「exec」命令使用命令行開關。

因此,我運行這樣的rspec:BUNDLE_GEMFILE="[mygemfile]" bundle exec rspec [filename],我在我的bashrc中將這個別名的第一部分作爲bem。奇蹟般有效。

然後,您應該設置您的源代碼管理來忽略您的Gemfile,無論是在項目的.gitignore中,還是保持項目完全衛生而不會更改其.gitignore到您的個人全局忽略文件(默認爲~/.config/git/ignore,並具有與項目的gitignore文件相同的格式)。其他

有一點要注意的是,捆紮機將創建一個基於Gemfile文件名稱的鎖文件。這非常方便,因爲它可以防止覆蓋項目的Gemfile.lock(如果它已簽入),但是您還需要忽略此新鎖定文件。如果您的gemfile爲Foo.bar,請查找Foo.bar.lock

最後,你可以做你的自定義的Gemfile類似霍爾格的建議的內容:

source "http://rubygems.org" 
gem "fivemat" 
instance_eval(File.read(File.dirname(__FILE__) + "/Gemfile")) 

,你是好去的,你只要記得指定的Gemfile。

+0

這種方法是我所知道的最好的方法,但不幸的是,它並不保留所包含的Gemfile的Gemfile.lock中的gem版本。我很想看到一個解決方案。 –

+0

您可以使用'bundle --gemfile Gemfile'來更新Gemfile.lock(而不是Foo.bar.lock)。 – Ritchie

+0

我已經創建了[this repo](https://github.com/ritchiey/play-nice)which您可以在您的應用程序中將其克隆到克隆目錄**中以獲得大部分功能。 – Ritchie

0

如果你還是決定這樣做(可怕的想法):

你可以到你的Gemfile添加Ruby代碼來加載一個〜/ .gemfile(或這樣的)如果它存在。

喜歡的東西:

eval(IO.read('~/.gemfile'), binding) if FileTest.exists?("~/.gemfile") 
+0

也有類似的想法,我不能只是:require_relative'〜/ .gemfile'而不是eval? – arikfr

13

ChiliProject我們允許用戶創建其納入對負荷的主要Gemfile一個Gemfile.local。這允許用戶指定額外的寶石,而不必更改我們的Gemfile以簡化更新。

爲此,我們添加了以下代碼at the bottom of our Gemfile

gemfile_local = File.expand_path('Gemfile.local', __dir__) 
if File.readable?(gemfile_local) 
    puts "Loading #{gemfile_local}..." if $DEBUG 
    instance_eval(File.read(gemfile_local)) 
end 

Gemfile.local本身是從儲存庫通過.gitignore排除。

+0

不錯,優雅的解決方案! –

+0

這對我來說非常合適!這應該是被接受的答案。 :) –

+5

在這個解決方案中'Gemfile.lock'受'Gemfile.local'影響,所以對於VCS跟蹤'Gemfile.lock'的項目來說效果不好。 – user1614572

1

您可以使用這樣的事情在你的Gemfile:

gem 'foo' if ENV['ENABLE_FOO_GEM'] 

然後,只需設置ENABLE_FOO_GEM在您的環境。

export ENABLE_FOO_GEM=1 

默認情況下,gem將被禁用,但很容易被任何想使用它的人打開(永久)。

0

添加到的.gitignore

Gemfile.local 
Gemfile.local.lock 

添加到項目中的Gemfile.local.sample文件,內容如下:

# Include gems that are note meant to be part of the project but for development purposes 
# That's why Gemfile.local and Gemfile.local.lock must be git-ignored 

# To use these gems: 
# 1. Create a "Gemfile.local" file (at same level of "Gemfile") 
# 2. Prepend "BUNDLE_GEMFILE=Gemfile.local" before "bundle install" or "bundle exec rails c" and so forth. 

eval_gemfile "./Gemfile" 

group :development, :test do 
    # Suggested gems 
    gem "awesome_print", require:"ap" 
    gem "hirb" 
    gem "pry" 
    gem "pry-byebug" 
    gem "pry-rails" 
    gem "meta_request" 

    # My gems 
    gem "fivemat" 
end 
相關問題