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

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

问题描述

TL; DR




  • 不要打扰宝石;
  • 必要时,使用 $ gem-based-binary _version_ args 指定要执行的版本>符号。

  • 当您有指定版本的Gemfile时,使用 bundle exec
>

gem install rails -v 3.2.13
rails _3.2.13_ new Project2
cd Project2
bundle exec rails server






更新: 2015-06-04



三年前我写过这个问题。部分原因是它基于一个错误的假设,部分情况自那时起就发生了变化。感谢@indirect对他的原始答案,我想要引起人们对@ kelvin的新答案(不太高估)的回答,总结如上。



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



另请参阅如何调用旧版本的宝石来自命令行? re:下划线版本符号。






原始问题: strong>



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



问题: strong>在使用 rbenv 捆绑器时,创建多个使用不同版本的导轨的多个导轨项目的当前最佳做法是什么? ,而不是rbenv-gemset或rvm?



USE CASE:我有两个rails项目,名为ProjectA和ProjectB。 ProjectA是使用一个版本的Rails(RailsA)开发的,而ProjectB使用不同的版本(RailsB)。如何安装这两个版本?



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

  rvm gemset create RailsA 
rvm gemset use RailsA
#RailsA。注意:我的问题不是版本特定的。
gem install rails --version 3.0
rails新增ProjectA
cd ProjectA
rvm --rvmrc使用`rvm current`
vi Gemfile
bundle install
cd ..
##现在对ProjectB执行相同的操作
rvm gemset create RailsB
rvm gemset use RailsB
gem install rails --version 3.2
rails新的ProjectB
cd ProjectB
rvm --rvmrc使用`rvm current`
vi Gemfile
bundle install

注意:项目文件夹的创建应该由 rails new 命令使用期望的版本 rails,因为骨架文件的版本不同。 (也许我应该重新回顾这个前提?)



捆绑方法:我一直在玩 rbenv ,而不是RVM,但我不明白工作流程。在 README.md 中,Sam Stephenson写道:rbenv不会......管理gemset,Bundler是一种更好的方法来管理应用程序依赖关系。有一个插件( rbenv-gemset )获得与rvm的gemsets相同的结果,但是Sam显然有利于使用Bundler来代替。不幸的是,他没有详细说明工作流程的样子。即使是 Bundler 网站也没有明确指出如何将一个项目与另一个项目隔离开的所有点。几个博客 and gists 开始救援,提示以下〜/ .bundle / config 文件:

  --- 
BUNDLE_PATH:供应商/包

(顺便说一句,我不确定---是关于什么的,文档没有提及它,似乎也没有什么区别。)



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



但是房间里的大象是在第一个地方创建rails项目文件夹的鸡与蛋问题!! 为了使用RailsA创建ProjectA文件夹,我需要安装rails(及其众多依赖项) first 。但是当我想创建ProjectB时,我必须切换到使用RailsB。没有宝石,我必须做一些严重的升级/降级。不是很酷。



一个可能的解决方案就是不用担心我用来创建ProjectX文件夹的Rails版本。如果我然后使用rails 3.0创建一个3.2项目,我可以手动创建应用程序/资产树。但是,这只是让我感到厌烦。是不是有更好的方法?

解决方案

假设您安装了rails 3.1.0,但您想创建一个新项目使用未安装的rails 3.2.13。

假设您希望新项目位于〜/ projects / Project2 $ b $ pre $ gem install rails -v 3.2.13
cd〜/ projects
rails _3 .2.13_ new Project2

这将创建 Gemfile 为你,锁定到你在命令行中指定的rails版本。



我故意忽略为新项目保留一个单独的gem副本的想法,因为这违背了Bundler的哲学,即将所有的宝石安装在一个地方。当您运行导轨时,Bundler将从该中心位置自动选择正确的宝石版本。这意味着一个项目可以共享宝石,而不是为自己安装新的副本。 (注意,不管你安装的每个ruby版本都会有它自己的宝石,这是一件好事,因为本地扩展可能不会在各个ruby版本中工作。)



您必须更清楚一点,因为大多数命令(如 rake )将加载最新版本的 rake 你已经安装了。您需要运行 bundle exec rake ... 以确保加载了正确的版本。通常我会为 rails 以外的所有命令运行 bundle exec 。你可以创建一个别名来缩短它(我使用 bex )。要使用gem可执行文件自动执行此操作,您可以使用 rbenv-binstub ,但您仍然必须意识到运行诸如 ruby​​ irb 之类的非gem可执行文件不会自动使用Gemfile。



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



2 :假设您想要为Project2使用不同于默认值(例如2.3.0)的ruby版本(例如2.1.8)。在这种情况下,如上所述运行 gem install 会在2.3.0下安装gems,这是浪费时间,因为您需要再次将gem安装在2.1下0.8。为了解决这个问题,你可以强制命令通过环境变量使用首选版本:

  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

You could use rbenv shell 设置变量,但我只建议如果您不希望rbenv在该shell的持续时间内基于 .ruby-version 文件进行自动切换。很容易忘记你已经设置了变量,当你转到不同的项目时,它不会使用你期望的版本。


TL;DR

  • 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


UPDATE: 2015-06-04

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.

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.

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


Original question:

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.

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?

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?

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

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?)

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.)

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.

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.

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?

解决方案

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.

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

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

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.)

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.

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.

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

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:没有宝石的生存的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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