如果您想使用gem进行开发/测试而不想强迫其他开发人员使用,您会怎么做?现在我有
begin
require 'redgreen'
rescue LoadError
end
test_helper.rb
中的并且没有gem配置,但这似乎是一种笨拙的方法,虽然是功能性的。我想做类似以下的事情:
config.gem "redgreen", :optional => true
还有其他建议吗?或者我应该只提供那些非常肤浅的宝石......?
修改
要说清楚,我只讨论那些特定的宝石,比如redgreen,它们实际上并没有在功能代码中使用,而只是在编码 process 中。除了避免条件要求外,根本不需要提供这些服务。
答案 0 :(得分:7)
特定于您的开发环境的宝石应安装在您的宝石集或本地宝石中,但不应安装在Gemfile
中。
一个典型的例子是Rubymine调试所需的ruby-debug-base19x
。它安装在您的本地gemset中,但不安装在Gemfile
中,因为并非所有编码器都使用Rubymine。
[编辑]
实际上,所有内容都在捆绑的上下文中运行,并且外部宝石无法访问。确实存在一些变通方法。他们中的大多数都很脏:)。
我在bundler issue找到了很多好的解决方案。
最好的解决方案是将其添加到.irbrc
:
# Add all gems in the global gemset to the $LOAD_PATH so they can be used even
# in places like 'rails console'.
if defined?(::Bundler)
global_gemset = ENV['GEM_PATH'].split(':').grep(/ruby.*@global/).first
if global_gemset
all_global_gem_paths = Dir.glob("#{global_gemset}/gems/*")
all_global_gem_paths.each do |p|
gem_path = "#{p}/lib"
$LOAD_PATH << gem_path
end
end
end
require 'irb/completion'
require 'rubygems'
require 'wirble'
Wirble.init
Wirble.colorize
如果您随后将wirble
安装到global
gemset,则可以找到它。
原始来源:https://gist.github.com/794915
希望这有帮助。
答案 1 :(得分:2)
我在这里回答了类似的问题
实现此目的的一种方法是创建不同的环境
group :scott do
end
然后
bundle --with-env = scott
答案 2 :(得分:1)
好的,我想我想出了点什么。基本上,这个想法是只在执行Rails应用程序时执行辅助Gemfile。为此,我们添加两件事:
首先,我们稍微修改一下rails脚本:
# in ./script/rails
Kernel::IN_RAILS_APP = true
APP_PATH = File.expand_path('../../config/application', __FILE__)
require File.expand_path('../../config/boot', __FILE__)
require 'rails/commands'
其次,如果我们在rails应用程序中存在辅助文件,我们会告诉bundler引入辅助Gemfile:
# Gemfile
if Kernel.const_defined?(:IN_RAILS_APP)
local_gemfile = File.dirname(__FILE__) + "/Gemfile.local"
if File.exists?(local_gemfile)
puts 'using local gemfile'
self.instance_eval(Bundler.read_file(local_gemfile))
end
end
现在,您可以向项目添加Gemfile.local
并在每台计算机上运行特定的gem。 bundle install
正常工作,因为IN_RAILS_APP
常量不存在。
**确保将Gemfile.local添加到.gitignore。
答案 3 :(得分:1)
在我看来,这就是环境的用途。幸运的是,还有一种方法可以用你的Gemfile中的内容来实现,这也是rails使用它的方式:groups
使用环境的方式与rails使用的方式相同。您可以在Gemfile中找到以下内容:
group :test do
# Pretty printed test output
gem 'turn', :require => false
end
以下是您在config / application.rb
中可以找到的内容Bundler.require(:default, Rails.env) if defined?(Bundler)
您需要做的就是更改本地环境设置,除非他们决定,否则与您合作的其他人不会受到影响。一切都得到了承诺,没有任何东西丢失。
这里有一些链接: http://yehudakatz.com/2010/05/09/the-how-and-why-of-bundler-groups/ http://gembundler.com/groups.html
答案 4 :(得分:0)
如果您希望它是可选的,最好将gem冻结为插件。但是,使用不同于开发团队其他人的宝石并不是一个好主意,因为它会在代码库中产生一些难以跟踪的不一致。我想把它添加到config.gem,然后告诉其他开发人员:
rake gems:install
你已经完成了。
答案 5 :(得分:0)
这就是我在Rails 3.1下解决同样问题的方法。在我的Gemfile中:
if File.exists? './tmp/eric_dev_gems'
gem 'redgreen'
gem 'awesome_print'
gem 'wirble'
gem 'wirb'
gem 'hirb'
end
在您选择的./tmp/
(或您的.gitignore中的某个文件夹中)创建一个文件。我用了eric_dev_gems
。这应该被git忽略,并且只会在您的系统上存在,除非您的一个队友决定他也想创建该文件。
答案 6 :(得分:0)
我把它放在我的宝石文件中解决了它:
$gem_names ||= ENV['GEM_PATH'].split(':').map{|g| Dir.glob("#{g}/gems/*").map{|p|p.split('/gems/').last}}.flatten
gem 'redgreen' if $gem_names.any?{|n| n=~/redgreen/ }
这样,只有在您的系统上手动安装gem时才会使用gem。
这很有效,但它的缺点是它将gem名称放在Gemfile.lock中。这没什么影响,因为gem没有安装bundle install
,但它确实使你的锁文件有点乱,并且可能导致锁文件从一个开发人员改变到下一个开发人员。
如果这对您来说是个问题,另一个选择是保持gemfile干净并且需要gem的完整路径,或者您可以为该gem添加路径。像这样:
$gem_paths ||= ENV['GEM_PATH'].split(':').map{|g| Dir.glob("#{g}/gems/*")}.flatten
$gem_paths.grep(/redgreen/).each {|p|$LOAD_PATH << p+'/lib'}
require 'redgreen' rescue nil