rbenv: выживание без гемсетов - PullRequest
43 голосов
/ 19 марта 2012

TL; DR

  • Не беспокойтесь о наборе драгоценных камней; несколько версий гемов могут быть установлены одновременно.
  • При необходимости укажите версию для выполнения, используя обозначение $ gem-based-binary _version_ args.
  • Используйте bundle exec, если у вас есть Gemfile, указывающий версию.
gem install rails -v 3.2.13
rails _3.2.13_ new Project2
cd Project2
bundle exec rails server

ОБНОВЛЕНИЕ: 2015-06-04

Я написал этот вопрос три года назад. Частично это было основано на ложном предположении, а частично ситуация изменилась с тех пор. С благодарностью @indirect за его оригинальный ответ, я хочу обратить внимание на более новый (менее одобренный) ответ @ kelvin, обобщенный выше.

Мое ложное предположение: за один раз может быть установлена ​​только одна версия гема, поэтому необходимость в гемсетах изолировать пространство имен. Не правда. Несколько версий драгоценного камня могут быть установлены одновременно. Самый последний из них будет использоваться при вызове из командной строки, если только у вас нет Gemfile, задающего ограничения версии, и вы вызываете команду через bundle exec или не указали версию в качестве первого аргумента.

См. Также Как я могу вызвать более старую версию гема из командной строки? re: запись с подчеркиванием версии.


Оригинальный вопрос:

У меня есть несколько проектов, использующих разные версии Rails. У меня есть рабочий процесс (описанный ниже) для создания проектов с использованием определенных версий рельсов и сохранения проектов изолированными друг от друга. Я хотел бы поэкспериментировать с другими рабочими процессами, в частности, используя rbenv вместо RVM, но не совсем понятно, как это сделать.

ВОПРОС: Какова наилучшая текущая практика для создания нескольких проектов рельсов, каждый из которых использует свою версию рельсов, при использовании rbenv и bundler , в отличие от rbenv-gemset или rvm?

ИСПОЛЬЗОВАНИЕ: У меня есть два проекта рельсов, которые называются ProjectA и ProjectB. ProjectA разработан с использованием одной версии rails ("RailsA"), тогда как ProjectB использует другую версию ("RailsB"). Как мне установить обе версии?

Подход к GEMSETS: Когда я только начинал с разработки на Rails, я использовал RVM . Помимо поддержки нескольких одновременных установок ruby, RVM поддерживает несколько именованных наборов драгоценных камней . Каждый проект имеет свою собственную независимую коллекцию драгоценных камней (включая сами рельсы), которая называется 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

Примечание: Само создание папок проекта должно выполняться (IMHO) командой rails new с использованием желаемой версии рельсов, так как файлы скелетов меняются от версии к версии. (Может быть, я должен вернуться к этой предпосылке?)

ПОДХОД К BUNDLER: Я играл с использованием rbenv вместо RVM, но я не так ясно понимаю рабочий процесс. В README.md Сэм Стивенсон пишет, что «rbenv не ... управляет наборами гемов. Bundler - лучший способ управления зависимостями приложений». Существует плагин ( rbenv-gemset ) для получения тех же результатов, что и для наборов гемов rvm, но Сэм явно предпочитает использовать Bundler. К сожалению, он не уточняет, как будет выглядеть рабочий процесс. Даже веб-сайт Bundler явно не связывает все точки, как изолировать один проект от другого. Несколько блогов и gists приходят на помощь, предлагая следующий файл ~/.bundle/config:

---
BUNDLE_PATH: vendor/bundle

(Кстати, я не уверен, что означает "---". В документах об этом ничего не говорится, и, похоже, это не имеет значения.)

Это фактически дает каждому рельсовому проекту свой собственный набор гемов, хранящий драгоценные камни в ProjectX / vendor / bundle /. Фактически, сами рельсы будут (пере) установлены там, что сделает проект полностью независимым от остальной части моего окружения, как только я запусту bundle install.

Но слон в комнате - это проблема курицы и яйца при создании папки проекта rails в месте !!создать папку ProjectA с помощью RailsA, мне нужно установить rails (и его многочисленные зависимости) first .Но когда я хочу создать ProjectB, я должен переключиться на использование RailsB.Без gemsets я должен сделать серьезное обновление / понижение.Не круто.

Возможное решение - просто не беспокоиться о том, какую версию рельсов я использую для создания папки ProjectX.Если бы я затем использовал rails 3.0 для создания проекта 3.2, я мог бы просто вручную создать дерево приложений / ресурсов.Но это только раздражает меня.Разве нет лучшего способа?

Ответы [ 3 ]

42 голосов
/ 20 марта 2012

Большинство людей решают эту проблему, сначала устанавливая камень rails через gem install rails. Если вы по какой-то причине отказываетесь от этого, вы можете отказаться от автоматического связывания, которое Rails пытается сделать для вас. Это будет работать полностью независимо от вашей системы управления ruby.

mkdir myapp
cd myapp
echo "source :rubygems" > Gemfile
echo "gem 'rails', '3.2.2'" >> Gemfile
bundle install --path vendor/bundle
bundle exec rails new . --skip-bundle

При появлении запроса введите «y», чтобы заменить ваш Gemfile на Rails по умолчанию (или нет, как вы предпочитаете). Затем, как только это будет сделано:

bundle install

Все готово, и вы обновили новое приложение rails с выбранной версией, не устанавливая драгоценный камень rails в rubygems.

12 голосов
/ 24 сентября 2013

Предположим, у вас установлен rails 3.1.0, но вы хотите создать новый проект с использованием rails 3.2.13, который не установлен.

Допустим, вы хотите, чтобы новый проект был в ~/projects/Project2.

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

Это создаст для вас Gemfile, привязанный к версии рельсов, которую вы указали в командной строке.

Я намеренно пропустил идею сохранения отдельной копии драгоценных камней для нового проекта, потому что это противоречит философии Bundler, которая заключается в установке всех драгоценных камней в одном месте. Когда вы запускаете рельсы, Bundler автоматически выбирает правильные версии драгоценных камней из этого центрального места. Это означает, что проект может делиться драгоценными камнями вместо установки новой копии для себя. (Обратите внимание, однако, что каждая версия ruby, которую вы устанавливаете, будет иметь свои гемы. Это хорошо, потому что собственные расширения, скорее всего, не будут работать в версиях ruby.)

Вы должны быть немного более осведомлены, потому что большинство команд, таких как rake, загрузят самую последнюю версию rake, которую вы установили. Вам нужно будет запустить bundle exec rake ..., чтобы убедиться, что загружена правильная версия. Обычно я запускаю bundle exec для всех команд, кроме rails. Вы можете создать псевдоним, чтобы сделать его короче (я использую bex). Чтобы автоматизировать это с исполняемыми файлами gem, вы можете использовать rbenv-binstubs , но вы все равно должны знать, что при запуске исполняемых файлов, не являющихся gem, таких как ruby и irb, автоматически не будет использоваться Gemfile.

Sidenote : rails new запустит bundle install, который проверит наличие самой новой версии зависимостей. Если вы хотите, чтобы компоновщик пытался использовать текущие установленные гемы, которые удовлетворяют требованиям зависимости, вы можете пропустить bundle install с rails new --skip-bundle, а затем запустить bundle check в директории приложения.

Sidenote 2 : предположим, что вы хотите использовать версию Ruby для Project2 (например, 2.1.8), которая отличается от версии по умолчанию (например, 2.3.0). В этом случае выполнение gem install, как указано выше, установит гемы под 2.3.0, что является пустой тратой времени, потому что вам нужно будет снова установить гемы под 2.1.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

Вы могли бы использовать rbenv shell для установки переменной, но я рекомендую только, если вы не хотите, чтобы rbenv автоматически переключался на основе файлов .ruby-version для продолжительность этой оболочки. Очень легко забыть, что у вас установлена ​​переменная, и когда вы переходите на другой проект, он не будет использовать ожидаемую вами версию.

8 голосов
/ 28 марта 2012

Хороший недавний пост, посвященный теме gemsets / bundler, здесь http://rakeroutes.com/blog/how-to-use-bundler-instead-of-rvm-gemsets/ Хороший фон, который вы можете применить к вашей настройке rbenv.

...