Как на самом деле работают RVM и rbenv? - PullRequest
136 голосов
/ 22 февраля 2012

Меня интересует, как на самом деле работают RVM и rbenv.

Очевидно, что они меняются между различными версиями Ruby и gemsets, но как это достигается? Я предполагал, что они просто обновляют символические ссылки, но, углубившись в код (и я должен признать, что мои знания Bash поверхностны), они, кажется, делают больше, чем это.

Ответы [ 5 ]

238 голосов
/ 24 февраля 2012

Краткое объяснение: rbenv работает, подключаясь к PATH вашей среды.Концепция проста, но дьявол кроется в деталях;полный текст приведен ниже.

Сначала rbenv создает прокладки для всех команд (ruby, irb, rake, gem и т. д.) во всех установленных версиях.рубина.Этот процесс называется Перефразировка .Каждый раз, когда вы устанавливаете новую версию Ruby или устанавливаете гем, который предоставляет команду, запускайте rbenv rehash, чтобы убедиться, что все новые команды подкладываются.

Эти прокладки живут в одном каталоге (~/.rbenv/shims по умолчанию).Чтобы использовать rbenv, вам нужно всего лишь добавить каталог shims в начало вашего PATH:

export PATH="$HOME/.rbenv/shims:$PATH"

Затем каждый раз, когда вы запускаете ruby из командной строки или запускаете скрипт, чей shebang читает #!/usr/bin/env ruby, ваша операционная система сначала найдет ~/.rbenv/shims/ruby и запустит ее вместо любого другого исполняемого файла ruby, который вы, возможно, установили.

Каждый шим представляет собой крошечный скрипт Bash, который, в свою очередь, запускает rbenv exec.Таким образом, с rbenv на вашем пути, irb эквивалентно rbenv exec irb, а ruby -e "puts 42" эквивалентно rbenv exec ruby -e "puts 42".

Команда rbenv exec определяет, какую версию Ruby вы хотите использовать,затем запускает соответствующую команду для этой версии.Вот как:

  1. Если установлена ​​переменная окружения RBENV_VERSION, ее значение определяет используемую версию Ruby.
  2. Если текущий рабочий каталог имеет файл .rbenv-version,его содержимое используется для установки переменной среды RBENV_VERSION.
  3. Если в текущем каталоге нет файла .rbenv-version, rbenv ищет в каждом родительском каталоге файл .rbenv-version, пока не достигнет корня вашего файла.файловая система.Если он найден, его содержимое используется для установки переменной среды RBENV_VERSION.
  4. Если RBENV_VERSION все еще не задано, rbenv пытается установить его, используя содержимое файла ~/.rbenv/version.
  5. Если нигде не указана версия, rbenv предполагает, что вы хотите использовать "системный" Ruby - то есть, какую бы версию вы не запускали, если бы rbenv не был на вашем пути.

(Вы можетеустановить версию Ruby для конкретного проекта с помощью команды rbenv local, которая создает файл .rbenv-version в текущем каталоге. Аналогично, команда rbenv global изменяет файл ~/.rbenv/version.)

ВооруженаRBENV_VERSION Переменная окружения, rbenv добавляет ~/.rbenv/versions/$RBENV_VERSION/bin в начало вашего PATH, затем выполняет команду и аргументы, переданные в rbenv exec.Вуаля!

Для более подробного ознакомления с тем, что происходит под капотом, попробуйте установить RBENV_DEBUG=1 и запустить команду Ruby.Каждая команда Bash, которую запускает rbenv, будет записана на ваш терминал.


Теперь rbenv просто занимается переключением версий, но процветающая экосистема плагинов поможет вам сделать все, начиная с установки Ruby *От 1073 * до настройка среды , управление "наборами гемов" и даже автоматизация bundle exec.

Я не совсем уверен, какой IRCподдержка связана с переключением версий Ruby, а rbenv разработан так, чтобы быть простым и достаточно понятным, чтобы не требовать поддержки.Но если вам когда-нибудь понадобится помощь, система отслеживания проблем и Twitter находятся всего в нескольких щелчках мыши.

Раскрытие информации: я являюсь автором rbenv, ruby-build и rbenv-vars. * * 1087

18 голосов
/ 22 февраля 2012

Я написал подробную статью: http://niczsoft.com/2011/11/what-you-should-know-about-rbenv-and-rvm/

Основное различие заключается в том, где изменяется среда оболочки:

  • RVM: она изменяется при изменении Ruby.
  • rbenv: он меняется, когда вы запускаете исполняемый файл Ruby / gem.

Кроме того, в RVM заложено гораздо больше, чем просто управление Ruby, у него гораздо большечем любой другой инструмент (кроме RVM и rbenv есть другие: https://twitter.com/#!/mpapis/status/171714447910502401)

Не забывайте о мгновенной поддержке, которую вы получаете по IRC в канале "#rvm" на серверах Freenode.

15 голосов
/ 15 марта 2012

Итак, чтобы суммировать превосходные ответы выше, основное практическое различие между RVM и rbenv заключается в том, что выбрана версия Ruby.

rbenv:

rbenv добавляет шим в начало вашего пути, команду с тем же именем, что и Ruby. Когда вы набираете ruby в командной строке, вместо этого запускается прокладка (потому что она также называется "ruby" и стоит первой в пути). Shim ищет переменную среды или файл .rbenv_version, чтобы сообщить, какой версии Ruby делегировать.

RVM:

RVM позволяет вам установить версию Ruby напрямую, вызвав rvm use. Кроме того, он также отменяет системную команду cd. Когда вы cd попадаете в папку, содержащую файл .rvmrc, выполняется код внутри файла .rvmrc. Это может быть использовано для установки версии для Ruby или чего-либо еще, что вам нравится.

Другие отличия:

Конечно, есть и другие различия. RVM имеет гемсеты из коробки, в то время как rbenv требует немного больше взлома (но не много). Оба являются функциональными решениями проблемы.

6 голосов
/ 20 декабря 2012

Основным отличием является , когда и как рубин переключается . Рубин включен:

  • для RVM вручную (использование rvm) или автоматически при смене каталогов
  • для rbenv автоматически при каждом выполнении команды ruby ​​

RVM использует модифицированную команду cd и ручной выбор Ruby с помощью rvm use. rbenv использует оболочки или «прокладки» для всех основных команд ruby ​​в качестве механизма по умолчанию для выбора ruby. RVM создает оболочки для основных инструментов командной строки, таких как gem, rake, ruby. Они используются, например, в CronJobs (см. http://rvm.io/integration/cron/), но они не являются механизмом по умолчанию для переключения версии Ruby.

Таким образом, оба метода «автоматически» выбирают нужную версию Ruby, перезаписывая команды и используя обертки. rvm переопределяет команды оболочки, такие как cd. rbenv отменяет все основные команды ruby, такие как ruby, irb, rake и gem.

5 голосов
/ 22 февраля 2012
rvm system
env > before
rvm jruby # or whatever
env > after
diff after before

Дает вам примерно:

< GEM_HOME=$HOME/.gem/ruby/1.9.1
---
> GEM_HOME=$HOME/.rvm/gems/jruby-1.6.6
< GEM_PATH=$HOME/.gem/ruby/1.9.1
---
> GEM_PATH=$HOME/.rvm/gems/jruby-1.6.6:$HOME/.rvm/gems/jruby-1.6.6@global
*bunch of rvm_*
> MY_RUBY_HOME=$HOME/.rvm/rubies/jruby-1.6.6
> RUBY_VERSION=jruby-1.6.6
> IRBRC=$HOME/.rvm/rubies/jruby-1.6.6/.irbrc

И это предполагает:

$HOME/.rvm/gems/jruby-1.6.6/bin:$HOME/.rvm/gems/jruby-1.6.6@global/bin

до $PATH

...