Rails可选的gem配置

时间:2010-01-22 18:29:46

标签: ruby-on-rails rubygems

如果您想使用gem进行开发/测试而不想强迫其他开发人员使用,您会怎么做?现在我有

begin
  require 'redgreen'
rescue LoadError
end
test_helper.rb中的

并且没有gem配置,但这似乎是一种笨拙的方法,虽然是功能性的。我想做类似以下的事情:

config.gem "redgreen", :optional => true

还有其他建议吗?或者我应该只提供那些非常肤浅的宝石......?

修改

要说清楚,我只讨论那些特定的宝石,比如redgreen,它们实际上并没有在功能代码中使用,而只是在编码 process 中。除了避免条件要求外,根本不需要提供这些服务。

7 个答案:

答案 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)

我在这里回答了类似的问题

User-level bundler Gemfile

实现此目的的一种方法是创建不同的环境

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