【问题标题】:Setting up RVM gemset via Rails 3 template通过 Rails 3 模板设置 RVM gemset
【发布时间】:2010-08-30 20:40:34
【问题描述】:

我正在尝试通过 Rails 3 模板设置 RVM gemset,然后通过模板中的命令开始使用 gemset 并将 gems 安装到新的 gemset(以应用程序命名)中。这似乎无法正常工作。新的 gem 没有安装到 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

如果我只是在模板运行后 cd 到控制台中的新应用程序文件夹,它会完美运行。我收到 RVM 消息:“信息:现在使用 gemset 'test_app'。”如果我此时运行 bundle install 命令,gems 会正确安装到新的 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。

谢谢,

~安德烈亚

【问题讨论】:

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


    【解决方案1】:

    您可以在不使用 rvm ruby​​ api 的情况下做到这一点。这是我们模板中的一个 sn-p

    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

    【讨论】:

    • 您可能希望rvm list 正则表达式为/^=(?:\*|&gt;)\s+(.*)\s\[/,它与“当前”Ruby 或“当前&& 默认”Ruby 匹配。
    【解决方案2】:

    我最近重新审视了这个问题。它可以使用 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

    【讨论】:

    • 谢谢你!这太棒了,我还需要先更新 rvm 才能正常工作
    • RVM 的最新版本已将 ruby​​ api 提取到单独的 gem 中,并且会在此处的第 2 行抱怨 unshift 调用。您可以安全地删除前两行。
    【解决方案3】:

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

    以下是在 irb 中创建新 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”。运行脚本时,我基本上得到了相同的行为:它将 gem 安装到我在运行脚本时碰巧在的任何 gemset 中。

    对这种奇怪的行为有什么想法或建议吗?

    【讨论】:

    • 您好 Jeff,我无法重现您描述的行为。但是,我使用的是 Ruby 1.9.2 (@env = RVM::Environment.new('ruby-1.9.2-p0'))。它可能与您正在使用的特定版本的 Ruby 甚至与 RVM 的版本有关。尝试运行“rvm update”将 RVM 升级到最新版本。让我知道这是否仍然存在。我想确保脚本没有绑定到特定版本的 Ruby。
    【解决方案4】:
    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 存在一个错误,其中@rvm_environment 实例变量没有使用 gemset_use 正确设置!因此,如果您执行 @env.send(:instance_variable_get, :@rvm_environment) 它不会反映更新的 gemset,因此当您调用系统时,它不会在正确的环境/gemset 中执行。将 @env var 重新设置为新的 RVM::Environment 实例可以解决问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多