通过Rails 3模板设置RVM gemset

时间:2010-08-30 20:40:34

标签: ruby-on-rails ruby-on-rails-3 rvm

我正在尝试通过Rails 3模板设置RVM gemset,然后通过模板中的命令开始使用gemset并将gem安装到新的gemset(以app命名)。这似乎不正常。新宝石没有安装到gemset中,事实上gemset根本没有创建。

以下是从模板文件中提取的一些相关代码:

rvmrc = <<-RVMRC
rvm_gemset_create_on_use_flag=1
rvm_trust_rvmrcs=1
rvm gemset use #{app_name}
RVMRC

create_file ".rvmrc", rvmrc

然后,继续前进:

run "cd path/to/new/app"
run 'gem install bundler --pre'
run 'bundle install'

我也试过了不同的版本:

inside app_name do 
  run 'gem install bundler --pre'
  run 'bundle install'
end

第三个版本:

inside app_name do 
  run "rvm gemset create #{app_name} && rvm gemset use #{app_name}"
  run 'gem install bundler --pre'
  run 'bundle install'
end

如果我只是在模板运行之后进入控制台中的新app文件夹,它的效果非常好。我收到了RVM消息:“info:现在使用gemset'test_app'。”如果我在那时运行bundle install命令,那么gem会正确地安装到新的gemset中,但是如果我只是从模板文件中运行那些命令,我​​就无法得到相同的结果。

应用生成器的日志说明了这一点:

 run    cd ~/rails3_sites/test_app from "."
 run    gem install bundler --pre from "./test_app"
 run    bundle install from "./test_app"

我错过了什么?任何帮助是极大的赞赏。顺便说一下,我正在使用ruby 1.9.2。

谢谢,

~Andrea

4 个答案:

答案 0 :(得分:6)

你可以不使用rvm ruby​​ api来实现。这是我们模板的片段

current_ruby = %x{rvm list}.match(/^=>\s+(.*)\s\[/)[1].strip
run "rvm gemset create #{app_name}"
run "rvm #{current_ruby}@#{app_name} gem install bundler"
run "rvm #{current_ruby}@#{app_name} -S bundle install"

file ".rvmrc", <<-END
rvm use #{current_ruby}@#{app_name}
END

这将找到当前选择的ruby,创建一个具有该名称的gemset,然后将bundler安装到其中。最后安装Gemfile中指定的gem并创建一个.rvmrc文件。

您可以在我的github存储库https://github.com/andyh/Template

中看到整个模板

答案 1 :(得分:3)

我最近重新审视了这个问题。它可以使用RVM Ruby API完成。我将调用API放在一个独立于我的模板的Ruby文件中,如下所示:

rvm_lib_path = "#{`echo $rvm_path`.strip}/lib"
$LOAD_PATH.unshift(rvm_lib_path) unless $LOAD_PATH.include?(rvm_lib_path)
require 'rvm'

rvm_ruby = ARGV[0]
app_name = ARGV[1]

unless rvm_ruby
  puts "\n You need to specify a which rvm rubie to use."
end

unless app_name
  puts "\n You need to name your app."
end

@env = RVM::Environment.new(rvm_ruby)

puts "Creating gemset #{app_name} in #{rvm_ruby}"
@env.gemset_create(app_name)
puts "Now using gemset #{app_name}"
@env.gemset_use!(app_name)

puts "Installing bundler gem."
puts "Successfully installed bundler" if @env.system("gem", "install", "bundler")
puts "Installing rails gem."
puts "Successfully installed rails" if @env.system("gem", "install", "rails")

template_file = File.join(File.expand_path(File.dirname(__FILE__)), 'templater.rb')
system("rails new #{app_name} -JT -d mysql -m #{template_file}")

如果有人有兴趣,我已经写了一篇关于Rails 3模板的博客文章,更详细地介绍了这一点:

Cooking Up A Custom Rails 3 Template

答案 2 :(得分:0)

Andrea,出色的方法和精彩的blog文章。但是,RVM引导程序不起作用。

以下是创建新gemset的大致相同的步骤:

ree-1.8.7-2010.02 > require 'rvm'
true
ree-1.8.7-2010.02 > @env = RVM::Environment.new('ree')
#<RVM::Environment environment_name="ree">
ree-1.8.7-2010.02 > @env.gemset_create('some_gemset')
true
ree-1.8.7-2010.02 > @env.gemset_use!('some_gemset')
true
ree-1.8.7-2010.02 > @env.gemset_name
nil
ree-1.8.7-2010.02 > 

注意最后一行尝试读取当前的gemset,即nil(终端会话使用默认的gemset,因此它是空的)。我希望它能显示'some_gemset'。在运行脚本时,我基本上会得到相同的行为:它将gems安装到我运行脚本时碰巧遇到的任何gemset中。

对这种奇怪行为的任何想法或建议?

答案 3 :(得分:0)

rvm_lib_path = "#{`echo $rvm_path`.strip}/lib"
$LOAD_PATH.unshift(rvm_lib_path) unless $LOAD_PATH.include?(rvm_lib_path)
require 'rvm'

rvm_ruby = ARGV[0]
app_name = ARGV[1]

unless rvm_ruby
  puts "\n You need to specify a which rvm rubie to use."
end

unless app_name
  puts "\n You need to name your app."
end

@env = RVM::Environment.new(rvm_ruby)
ENV['RVM_RUBY'] = rvm_ruby

puts "Creating gemset #{app_name} in #{rvm_ruby}"
@env.gemset_create(app_name)
puts "Now using gemset #{app_name}"
@env = RVM::Environment.new("#{rvm_ruby}@#{app_name}")


puts "Installing bundler gem."
puts "Successfully installed bundler" if @env.system("gem install bundler --no-ri --no-rdoc")
puts "Installing rails gem."
puts "Successfully installed rails" if @env.system("gem install rails --no-ri --no-rdoc")

template_file = File.join(File.expand_path(File.dirname(__FILE__)), 'template.rb')
system("rvm #{rvm_ruby}@#{app_name} exec rails new #{app_name} -JT -d mysql -m #{template_file}")

system("mv #{app_name} #{app_name}.git")

作品。

rvm存在一个错误,使用gemset_use无法正确设置@rvm_environment实例变量!因此,如果您执行@ env.send(:instance_variable_get,:@rvm_environment),它不会反映更新的gemset,因此当您调用系统时,它不会在正确的环境/ gemset中执行。将@env var重新设置为新的RVM :: Environment实例可以解决问题。