webentwicklung-frage-antwort-db.com.de

Wie funktionieren RVM und rbenv tatsächlich?

Ich bin daran interessiert, wie RVM und rbenv tatsächlich funktionieren.

Offensichtlich tauschen sie zwischen verschiedenen Versionen von Ruby und Edelsteinen aus, aber wie wird das erreicht? Ich hatte angenommen, dass sie einfach Symlinks aktualisieren, aber in den Code vertieft sind (und ich muss mein Wissen über Bash zugeben) ist oberflächlich) sie scheinen mehr als das zu tun.

137
superluminary

Kurze Erklärung: rbenv funktioniert, indem es in die PATH Ihrer Umgebung eingebunden wird. Das Konzept ist einfach, aber der Teufel steckt im Detail. volle Schaufel unten.

Zunächst erstellt rbenv Shims für alle Befehle (Ruby, irb, rake, gem usw.) in allen installierten Ruby-Versionen. Dieser Vorgang wird als Nachwärmen bezeichnet. Jedes Mal, wenn Sie eine neue Version von Ruby oder ein Juwel installieren, das einen Befehl bereitstellt, führen Sie rbenv rehash aus, um sicherzustellen, dass alle neuen Befehle angepasst werden.

Diese Shims befinden sich in einem einzigen Verzeichnis (standardmäßig ~/.rbenv/shims). Um rbenv zu verwenden, müssen Sie nur das Shims-Verzeichnis vor Ihrem PATH hinzufügen:

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

Wenn Sie dann Ruby über die Befehlszeile ausführen oder ein Skript ausführen, dessen Shebang #!/usr/bin/env Ruby liest, findet Ihr Betriebssystem zuerst ~/.rbenv/shims/Ruby und führt es anstelle eines anderen Ruby ausführbare Datei, die Sie möglicherweise installiert haben.

Jedes Shim ist ein winziges Bash-Skript, das wiederum rbenv exec ausführt. Wenn Sie also rbenv in Ihrem Pfad haben, entspricht irbrbenv exec irb und Ruby -e "puts 42"rbenv exec Ruby -e "puts 42".

Der Befehl rbenv exec ermittelt, welche Version von Ruby) Sie verwenden möchten, und führt dann den entsprechenden Befehl für diese Version aus.

  1. Wenn die Umgebungsvariable RBENV_VERSION festgelegt ist, bestimmt ihr Wert die zu verwendende Version von Ruby).
  2. Wenn das aktuelle Arbeitsverzeichnis eine .rbenv-version -Datei enthält, wird deren Inhalt zum Festlegen der Umgebungsvariablen RBENV_VERSION verwendet.
  3. Wenn sich im aktuellen Verzeichnis keine .rbenv-version -Datei befindet, durchsucht rbenv jedes übergeordnete Verzeichnis nach einer .rbenv-version -Datei, bis sie das Stammverzeichnis Ihres Dateisystems erreicht. Wenn eine gefunden wird, wird ihr Inhalt verwendet, um die Umgebungsvariable RBENV_VERSION festzulegen.
  4. Wenn RBENV_VERSION immer noch nicht festgelegt ist, versucht rbenv, es mithilfe des Inhalts der ~/.rbenv/version -Datei festzulegen.
  5. Wenn nirgendwo eine Version angegeben ist, geht rbenv davon aus, dass Sie den Ruby "system" verwenden möchten, d. H. Welche Version auch immer ausgeführt werden würde, wenn rbenv nicht in Ihrem Pfad wäre.

(Mit dem Befehl rbenv local können Sie eine projektspezifische Ruby) - Version festlegen, die eine .rbenv-version -Datei im aktuellen Verzeichnis erstellt. Ebenso die rbenv global Befehl ändert die Datei ~/.rbenv/version.)

Mit einer Umgebungsvariablen RBENV_VERSION versehen, fügt rbenv ~/.rbenv/versions/$RBENV_VERSION/bin vor Ihrem PATH ein und führt dann den Befehl und die Argumente aus, die an rbenv exec übergeben wurden. Voila!

Um genau zu sehen, was unter der Haube passiert, setzen Sie RBENV_DEBUG=1 und führen Sie den Befehl Ruby) aus. Jeder Bash-Befehl, den rbenv ausführt, wird auf Ihr Terminal geschrieben.


Nun, rbenv befasst sich nur mit dem Versionswechsel, aber ein florierendes Ökosystem von Plugins wird Ihnen dabei helfen, alles von Installieren von Ruby bis Einrichten Ihrer Umgebung , Verwalten von " Edelsteine ​​" und sogar Automatisierung von bundle exec .

Ich bin nicht ganz sicher, was IRC Unterstützung mit dem Umschalten von Ruby Versionen zu tun hat, und rbenv ist so einfach und verständlich, dass keine Unterstützung erforderlich ist Sollten Sie jemals Hilfe benötigen, sind der Issue Tracker und Twitter nur ein paar Klicks entfernt.

Offenlegung: Ich bin der Autor von rbenv, Ruby-build und rbenv-vars.

239
Sam Stephenson

Ich schrieb einen ausführlichen Artikel: http://niczsoft.com/2011/11/what-you-should-know-about-rbenv-and-rvm/

Der grundlegende Unterschied besteht darin, wo die Shell-Umgebung geändert wird:

  • RVM: Es wird geändert, wenn Sie Ruby ändern.
  • rbenv: Es wird geändert, wenn Sie eine ausführbare Ruby/Gem-Datei ausführen.

Die Sache mit RVM ist auch, dass es viel mehr abdeckt als nur Rubies zu verwalten, es hat viel mehr als jedes andere Tool (es gibt andere außer RVM und rbenv: https://Twitter.com/# !/mpapis/status/171714447910502401 )

Vergessen Sie nicht den sofortigen Support, den Sie auf IRC im "#rvm" -Kanal auf den Freenode-Servern erhalten.

18
mpapis

Um die hervorragenden Antworten oben zusammenzufassen, besteht der wesentliche praktische Unterschied zwischen RVM und rbenv darin, dass die Version von Ruby ausgewählt wird.

rbenv:

rbenv fügt einen Shim an den Anfang Ihres Pfads ein, einen Befehl mit demselben Namen wie Ruby. Wenn Sie Ruby in eine Befehlszeile eingeben, wird stattdessen das Shim ausgeführt (da es auch als "Ruby" bezeichnet wird und im Pfad an erster Stelle steht). Das Shim sucht nach einer Umgebungsvariablen oder einer .rbenv_version - Datei, um anzugeben, an welche Version von Ruby) delegiert werden soll.

RVM:

Mit RVM können Sie eine Version von Ruby direkt durch Aufrufen von rvm use Festlegen. Außerdem wird der Systembefehl cd überschrieben. Wenn Sie cd In einem Ordner, der eine .rvmrc - Datei enthält, wird der Code in der .rvmrc - Datei ausgeführt, mit dem eine Ruby Version festgelegt werden kann, oder alles andere was du magst.

Andere Unterschiede:

Es gibt natürlich noch andere Unterschiede. RVM hat Edelsteine ​​aus der Schachtel, während RBENV nur ein wenig mehr Hacking erfordert (aber nicht viel). Beides sind funktionale Lösungen für das Problem.

15
superluminary

Der Hauptunterschied scheint zu sein wann und wie Ruby wird umgeschaltet . Ruby wird umgeschaltet:

  • für RVM manuell (rvm use) oder automatisch beim Verzeichniswechsel
  • für rbenv automatisch jedes Mal, wenn ein Ruby Befehl ausgeführt wird

RVM stützt sich auf den geänderten Befehl cd und die manuelle Auswahl von Ruby von rvm use. rbenv verwendet Wrapper oder "Shims" für alle grundlegenden Ruby) - Befehle als Standardmechanismus für die Auswahl von Ruby. RVM erstellt Wrapper für grundlegende Befehlszeilen-Tools wie gem, rake, Ruby Beispiel in CronJobs (siehe http://rvm.io/integration/cron/ ), aber sie sind nicht der Standardmechanismus zum Wechseln der Ruby Version.

So wählen beide Methoden "automatisch" die richtige Ruby= Version durch Überschreiben von Befehlen und Verwenden von Wrappern. Rvm überschreibt Shell-Befehle wie cd. Rbenv überschreibt alle grundlegenden Ruby Befehle wie z als Ruby, Irb, Rake und Gem.

6
0x4a6f4672
rvm system
env > before
rvm jruby # or whatever
env > after
diff after before

Gibt Ihnen ungefähr:

< 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/[email protected]
*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

Und es geht vor:

$HOME/.rvm/gems/jruby-1.6.6/bin:$HOME/.rvm/gems/[email protected]/bin

zu $PATH

5
Reactormonk