Подтвердить что ты не робот

Rbenv: выживание без гемсетов

TL; DR

  • Не беспокойтесь о gemset; несколько версий драгоценного камня могут быть установлены одновременно.
  • При необходимости укажите, какую версию выполнить с использованием нотации $ 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 более новый (менее одобренный) ответ, обобщенный выше.

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

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


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

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

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

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

ПОДХОД GEMSETS: Когда я впервые начал работу с Rails, я использовал RVM. В дополнение к поддержке нескольких параллельных установок рубинов, поддержка RVM имеет несколько Named Gem Sets. Каждый проект имеет свою собственную независимую коллекцию драгоценных камней (включая сами рельсы), называемую 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 не... управляет gemsets. Bundler - лучший способ управлять зависимостями приложений." Существует плагин (rbenv-gemset) для получения тех же результатов, что и rvm gemset, но Сэм явно предпочитает использовать Bundler. К сожалению, он не уточняет, как будет выглядеть рабочий процесс. Даже веб-сайт Bundler явно не связывает все точки выделения одного проекта из другого. Несколько блоги и gists приходят на помощь, предлагая следующий ~/.bundle/config файл:

---
BUNDLE_PATH: vendor/bundle

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

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

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

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

4b9b3361

Ответ 1

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

Предположим, вы хотите, чтобы новый проект находился в ~/projects/Project2.

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

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

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

Вам нужно быть немного более осведомленным, потому что большинство команд, таких как 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: предположим, что вы хотите использовать рубиновую версию 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 на время действия этой оболочки. Очень легко забыть, что у вас есть набор переменных, и когда вы подключаетесь к другому проекту, он не будет использовать ожидаемую версию.

Ответ 2

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

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

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