rbenv:没有 gemsets 生存 [英] rbenv: Surviving without gemsets

查看:11
本文介绍了rbenv:没有 gemsets 生存的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

TL;DR

  • 不要为宝石而烦恼;可以同时安装多个版本的 gem.
  • 必要时,使用 $ gem-based-binary _version_ args 表示法指定要执行的版本.
  • 当你有一个 Gemfile 指定版本时,使用 bundle exec.
  • Don't bother with gemsets; multiple versions of a gem may be installed concurrently.
  • When necessary, specify which version to execute using $ gem-based-binary _version_ args notation.
  • Use bundle exec when you have a Gemfile specifying the version.
gem install rails -v 3.2.13
rails _3.2.13_ new Project2
cd Project2
bundle exec rails server

<小时>

更新: 2015-06-04


UPDATE: 2015-06-04

我三年前写了这个问题.部分原因是基于错误的假设,部分情况从那时起发生了变化.感谢@indirect 的原始答案,我想提请注意@kelvin 的更新(较少赞成)答案,总结在上面.

I wrote this question three years ago. Partly, it was based on a false assumption, and partly the situation has changed since then. With appreciation to @indirect for his original answer, I want to call attention to @kelvin's newer (less upvoted) answer, summarized above.

我的错误假设:一次只能安装一个 gem 版本,因此需要 gemset 来隔离命名空间.不对.可以同时安装多个版本的 gem.从命令行调用时将使用最新的,除非您有一个 Gemfile 指定版本约束并通过 bundle exec 调用命令,或者将版本指定为其第一个参数.

My false assumption: Only a single version of a gem could be installed at a time, hence the need for gemsets to isolate the namespace. Not true. Multiple versions of a gem may be installed concurrently. The most recent one will be used when invoked from a command line, unless you have a Gemfile specifying the version constraints and invoke the command via bundle exec, or specify the version as its first argument.

另请参阅 如何从命令行调用旧版本的 gem? re:下划线版本表示法.

See also How can I call an older version of a gem from the commandline? re: the underscore-version notation.

原问题:

我有多个项目正在使用不同版本的 Rails.我有一个工作流程(如下所述),用于使用特定版本的 rails 创建项目,并使项目彼此隔离.我想尝试其他工作流程,特别是使用 rbenv 而不是 RVM,但不清楚如何去做.

I have multiple projects going on using different versions of Rails. I have a workflow (described below) for creating projects using specific versions of rails, and keeping the projects isolated from each other. I'd like to experiment with other workflows, in particular, using rbenv instead of RVM, but it's not clear how to do so.

问题:在使用 rbenv当前最佳实践是什么?> 和 bundler,而不是 rbenv-gemset 或 rvm?

QUESTION: What is the best current practice for creating multiple rails projects, each using a different version of rails, when making use of rbenv and bundler, as opposed to rbenv-gemset or rvm?

用例:我有两个 Rails 项目,分别称为 ProjectA 和 ProjectB.ProjectA 是使用一个版本的 rails(RailsA")开发的,而 ProjectB 使用不同的版本(RailsB").如何管理同时安装这两个版本?

USE CASE: I have two rails projects, called ProjectA and ProjectB. ProjectA is developed using one version of rails ("RailsA"), whereas ProjectB uses a different version ("RailsB"). How do I manage having both versions installed?

GEMSETS 方法:当我第一次开始使用 Rails 开发时,我使用 RVM.除了支持 ruby​​ 的多个并发安装之外,RVM 还支持具有多个 命名 Gem 集.每个项目都有自己独立的 gems 集合(包括 rails 本身),称为 gemset:

THE GEMSETS APPROACH: When I first started with Rails development, I used RVM. In addition to supporting multiple, concurrent installations of ruby, RVM supports having multiple Named Gem Sets. Each project has its own independent collection of gems (including rails itself) called a gemset:

rvm gemset create RailsA
rvm gemset use RailsA
# RailsA.  Note: My question is not version-specific.
gem install rails --version 3.0
rails new ProjectA
cd ProjectA
rvm --rvmrc use `rvm current`
vi Gemfile
bundle install
cd ..
## Now do the same for ProjectB
rvm gemset create RailsB
rvm gemset use RailsB
gem install rails --version 3.2
rails new ProjectB
cd ProjectB
rvm --rvmrc use `rvm current`
vi Gemfile
bundle install

注意:项目文件夹的创建应该通过rails new命令使用所需版本的rails来完成(恕我直言),因为骨架文件会随着版本的变化而变化.(也许我应该重新审视这个前提?)

Note: The very creation of the project folders should be done (IMHO) by a rails new command using the desired version of rails, since the skeleton files change from version to version. (Perhaps I should revisit this premise?)

捆绑器方法:我一直在使用 rbenv而不是 RVM,但我不太清楚工作流程.在 README.md 中,Sam Stephenson 写道:rbenv 不......管理 gemsets.Bundler 是管理应用程序依赖项的更好方法."有一个插件 (rbenv-gemset) 可以获得与 rvm 的 gemsets 相同的结果,但是 Sam显然更倾向于使用 Bundler.不幸的是,他没有详细说明工作流程会是什么样子.甚至 Bundler 网站也没有明确地将如何将一个项目与另一个项目隔离开来.几个博客 gists 来救场,提示如下 ~/.bundle/config 文件:

THE BUNDLER APPROACH: I've been playing with using rbenv instead of RVM, but I don't understand the workflow as clearly. In the README.md, Sam Stephenson writes that "rbenv does not ... manage gemsets. Bundler is a better way to manage application dependencies." There is a plugin (rbenv-gemset) for getting the same results as rvm's gemsets, but Sam clearly favors using Bundler instead. Unfortunately, he doesn't elaborate on what the workflow would look like. Even the Bundler website doesn't explicitly connect all the dots of how to isolate one project from another. Several blogs and gists come to the rescue, suggesting the following ~/.bundle/config file:

---
BUNDLE_PATH: vendor/bundle

(顺便说一句,我不确定---"是什么意思.文档没有提到它,而且似乎没有什么区别.)

(BTW, I'm not sure what the "---" is about. The docs make no mention of it and it doesn't seem to make a difference.)

这有效地为每个 Rails 项目提供了自己的 gemset,将 gem 存储在 ProjectX/vendor/bundle/中.实际上,一旦我运行 bundle install,rails 本身就会(重新)安装在那里,使项目完全独立于我的环境的其余部分.

This effectively gives each rails project its own gemset, storing the gems in ProjectX/vendor/bundle/. In fact, rails itself will be (re-)installed there, making the project completely independent of the rest of my environment, once I run bundle install.

但是房间里的大象是首先创建rails项目文件夹的先有鸡还是先有蛋的问题!!为了使用 RailsA 创建 ProjectA 文件夹,我需要安装 rails(及其众多依赖项)首先.但是当我想创建 ProjectB 时,我必须切换到使用 RailsB.如果没有 gemset,我必须进行一些认真的升级/降级.不酷.

But the elephant in the room is the chicken-and-egg problem of creating the rails project folder in the first place!! In order to create the ProjectA folder using RailsA, I need to install rails (and its numerous dependencies) first. But when I want to create ProjectB, I must then switch to using RailsB. Without gemsets, I must do some serious upgrading/downgrading. Not cool.

一个可能的解决方案就是不用担心我使用什么版本的 rails 来创建 ProjectX 文件夹.如果我然后使用 rails 3.0 创建一个 3.2 项目,我可以手动创建应用程序/资产树.但这让我很恼火.没有更好的办法吗?

A possible solution is simply not to worry about what version of rails I use to create the ProjectX folder. If I then use rails 3.0 to create a 3.2 project, I could just manually create the app/assets tree. But that just irks me. Ain't there a better way?

推荐答案

假设你安装了 rails 3.1.0,但是你想使用没有安装的 rails 3.2.13 创建一个新项目.

Suppose you have rails 3.1.0 installed, but you want to create a new project using rails 3.2.13 which is not installed.

假设您希望新项目位于 ~/projects/Project2 中.

Let's say you want the new project to be in ~/projects/Project2.

gem install rails -v 3.2.13
cd ~/projects
rails _3.2.13_ new Project2

这将为您创建 Gemfile,锁定到您在命令行中指定的 Rails 版本.

This will create the Gemfile for you, locked to the version of rails you specified on the command-line.

我故意省略了为新项目保留单独的 gem 副本的想法,因为这违背了 Bundler 的理念,即将所有的 gem 安装在一个地方.当您运行 rails 时,Bundler 会从该中心位置自动选择正确的 gem 版本.这意味着一个项目可以共享 gem,而不是为自己安装一个新的副本.(但是请注意,您安装的每个 ruby​​ 版本都有自己的 gem.这是一件好事,因为本机扩展可能无法跨 ruby​​ 版本工作.)

I deliberately omitted the idea of keeping a separate copy of gems for the new project, because that goes against the Bundler philosophy, which is to have all gems installed in one place. When you run rails, Bundler will pick the correct gem versions automatically from that central location. That means a project can share gems instead of installing a fresh copy for itself. (Note, however that each version of ruby you install will have its own gems. This is a good thing because native extensions likely won't work across ruby versions.)

您必须更加注意,因为大多数命令,如 rake,将加载您已安装的最新版本的 rake.您需要运行 bundle exec rake ... 以确保加载了正确的版本.通常我会为除了 rails 之外的所有命令运行 bundle exec.您可以创建一个别名以使其更短(我使用 bex).要使用 gem 可执行文件自动执行此操作,您可以使用 rbenv-binstubs,但您仍然必须请注意,运行像 rubyirb 这样的非 gem 可执行文件不会自动使用 Gemfile.

You do have to be a bit more aware, because most commands, like rake, will load the newest version of rake that you have installed. You'll need to run bundle exec rake ... to make sure the correct version is loaded. Usually I'll run bundle exec for all commands except rails. You can create an alias to make it shorter (I use bex). To automate this with gem executables, you can use rbenv-binstubs, but you still have to be aware that running non-gem executables like ruby and irb won't automatically use the Gemfile.

旁注:rails new 将运行bundle install,它将检查最新版本的依赖项.如果您希望 bundler 尝试使用当前安装的满足依赖要求的 gem,您可以使用 rails new --skip-bundle 跳过 bundle install,然后运行 ​​捆绑检查在应用程序目录中.

Sidenote: rails new will run bundle install, which will check for the newest version of the dependencies. If you want bundler to try to use currently installed gems that satisfy the dependency requirements, you can skip the bundle install with rails new --skip-bundle, then run bundle check in the app dir.

旁注 2:假设您想为 Project2 使用不同于默认(例如 2.3.0)的 ruby​​ 版本(例如 2.1.8).在这种情况下,按照上面指定的方式运行 gem install 会在 2.3.0 下安装 gem,这是浪费时间,因为您需要在 2.1.8 下再次安装 gem.为了解决这个问题,您可以通过环境变量强制命令使用首选版本:

Sidenote 2: suppose you want to use a ruby version for Project2 (e.g. 2.1.8) that's different from the default (e.g. 2.3.0). In that case, running gem install as specified above will install the gems under 2.3.0, which is a waste of time because you'll need to install the gems again under 2.1.8. To solve that problem, you can force the commands to use the preferred version via environment variable:

RBENV_VERSION=2.1.8  gem install rails -v 3.2.13
cd ~/projects
RBENV_VERSION=2.1.8  rails _3.2.13_ new Project2
echo 2.1.8 > Project2/.ruby-version

可以使用 rbenv shell 来设置变量,但我只建议如果您不希望 rbenv 在该 shell 期间基于 .ruby-version 文件自动切换.很容易忘记您已经设置了变量,并且当您 cd 到不同的项目时,它不会使用您期望的版本.

You could use rbenv shell to set the variable, but I only recommend that if you don't want rbenv to auto-switch based on .ruby-version files for the duration of that shell. It's very easy to forget that you have the variable set, and when you cd to a different project, it won't be using the version you expect.

这篇关于rbenv:没有 gemsets 生存的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆