Rbenv and Bundle

05 November 2012 #ruby#rvm#rbenv

Довольно долго я использовал в своей практике RVM, но в конце концов мне надоело то, что возникают проблемы с обновлением пакетов, да и много чего еще. Решил в итоге взглянуть на альтернативу в лице Rbenv.

Предварительно удалил из системы rvm. Для этого достаточно удалить из конфигурационных файлов bash/zsh строку инициализации rvm, после чего перезагрузить командный интерпретатор и затем удалить директорию ~/.rvm. Теперь можно приступать к установке rbenv.

Установка rbenv

По идее rbenv можно довольно просто установить, используя пакетный менеджер homebrew, который очень часто используется в osx. Но используя его я столкнулся с тем, что в последствии совершенно запутался, где и какие пути прописывать в конфигурации rbenv. Поэтому рекомендую устанавливать с использованием git.

$ cd
$ git clone git://github.com/sstephenson/rbenv.git ~/.rbenv
$ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile
$ echo 'eval "$(rbenv init -)"' >> ~/.bash_profile

При использовании zsh, в последних двух строках необходимо использовать файл ~/.zshenv вместо ~/.bash_profile.

Теперь перезапускаем командную оболочку и устанавливаем необходимые версии ruby.

Установка ruby

Для упрощения данной операции рекомендуется установить расширение ruby-build, которое позволяет устанавливать ruby с использованием всего одной команды. Для установки достаточно дать всего одну команду:

$ git clone git://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build

Теперь можно установить необходимую версию ruby:

$ rbenv install 1.9.3-p194
$ rbenv rehash

Команда rbenv rehash используется для того, чтобы rbenv обновила пути, и используется каждый раз при установке ruby.

Для того, чтобы данная версия использовалась в системе по умолчанию, достаточно использовать команду:

$ rbenv global 1.9.3-p194

Для того, чтобы в проекте использовалась ruby с версией, отличной от глобальной, достаточно в директории проекта создать файл .rbenv-version, в которую помещаем номер версии:

$ echo 'ree-1.8.7-2012.02' > .rbenv-version

Да, после того, как я стал использовать rbenv, я совершенно перестал использовать системный ruby. А для использования ruby версии 1.8.7 я установил Ruby Enterprise Edition, которая отличается более высокими требованиями к безопасности. Данную версию я использую при работе с jekyll.

Обращаю внимание так же на то, что в последних версиях OSX просто невозможно собрать ruby с версиями ниже 1.9.3 из-за особенностей используемой версии gcc. И для того, чтобы использовать ruby 1.8.7 приходиться или использовать системную версию или же устанавливать Ruby Enterprise Edition.

Так же стоит обратить внимание на то, что каждая версия ruby будет иметь свой набор пакетов. Поэтому если какой-то пакет должен использоваться в глобальном наборе, то его стоит устанавливать каждый раз после установки новой версии ruby.

Использование bundle

В случае использования rvm все пакеты устанавливались глобально, но в каждом проекте использовались только их определенные версии. И ве управлялось с использованием gemset. Из-за чего возникало масса путаницы, проблемы с обновлением…

Когда я спрашивал, что лучше всего использовать для управления пакетами, мне постоянно говорили – “используй bundle!”, но я никак не мог понять, почему.

В моем понимании в то время bundle служил для того, чтобы установить пакеты, которые описаны в файле Gemfile. То есть фактически только упрощает установку определенных пакетов в проекте. Но когда я погрузился в документацию bundle, понял что ошибался и очень сильно!

Устанавливать bundle лучше всего глобально, чтобы команда была доступна везде и всегда:

$ gem install bundler

Обращаю внимание на то, что при установке пакетов с использованием версий ruby, которые мы ставили через rbenv, не нужно использовать sudo.

Для упрощения работы с командой bundle, рекомендуется создать алиасы в командной оболочке:

# bundle alias
alias b="bundle"
alias bi="bundle install --path .bundle/gems --binstubs .bundle/bin"
alias bu="b update"
alias be="b exec"

Теперь для использования пакетов в проекте достаточно создать файл Gemfile, в котором описываем, какие именно пакеты необходимо использовать и откуда их требуется брать, например:

source :rubygems

group :development do
  gem 'rake'
  gem 'jekyll'
  gem 'kramdown'
  gem 'jammit'
  gem 'liquid'
end

Теперь просто используем команду bi, которая установит все пакеты в локальную директорию .bundle/gems и при этом еще создаст ссылки на программы в директорию .bundle/bin.

Если изменить переменную PATH следующим образом:

$ export PATH="./.bundle/bin:$PATH"

То при нахождении в директории проекта можно запускать установленные пакеты, как обычные системные, что очень удобно.

Для обновления пакетов в проекте достаточно дать повторно команду bi, или же просто удалить директорию .bundle и установить пакеты снова. Сколько будет проектов, какие версии пакетов в них будут использоваться, не имеет ровно никакого значения. Система остается чистой и все проекты совершенно не пересекаются между собой.

Для удаления определенного пакета достаточно удалить строку с его описанием из файла Gemfile и выполнить команду bi. Проще некуда!

Больше информации по используемому формату файла Gemfile можно получить на страницах официального сайта gembundler.com.

Тонкости bundle

Для избавления от некоторых сложностей при использовании bundle, рекомендуется создать файл конфигурации ~/.bundle/config, в который поместить следующее:

---
BUNDLE_PATH: .bundle
BUNDLE_SHEBANG: ruby-local-exec
BUNDLE_BIN: ./.bundle/bin

Теперь и просто используя команду bundle или ее синоним b, который мы создали чуть ранее, мы получим тот же самый результат, что и при использовании нашего синонима bi. То есть все пакеты будут устанавливаться в локальную директорию проекта и при этом у нас будет возможность запускать установленные пакеты, как обычные системные.

Если мне еще кто скажет, что для работы с ruby лучше всего использовать rvm, я посмотрю на этого человека с “большим удивлением”.