web-dev-qa-db-fra.com

Comment RVM et rbenv fonctionnent-ils réellement?

Je suis intéressé par le fonctionnement réel de RVM et rbenv.

Évidemment, ils échangent entre différentes versions de Ruby et les ensembles de gemmes, mais comment cela est-il réalisé? J'avais supposé qu'ils mettaient simplement à jour des liens symboliques, mais après avoir fouillé dans le code (et je dois admettre ma connaissance de Bash est superficiel), ils semblent faire plus que cela.

137
superluminary

Brève explication: rbenv fonctionne en se connectant au PATH de votre environnement. Le concept est simple, mais le diable est dans les détails; scoop complet ci-dessous.

Tout d'abord, rbenv crée des cales pour toutes les commandes (Ruby, irb, rake, gem et ainsi de suite) sur toutes vos versions installées de Ruby. Ce processus est appelé rehashing . Chaque fois que vous installez une nouvelle version de Ruby ou installez une gemme qui fournit une commande, exécutez rbenv rehash pour vous assurer que toutes les nouvelles commandes sont calées.

Ces cales vivent dans un seul répertoire (~/.rbenv/shims par défaut). Pour utiliser rbenv, il vous suffit d'ajouter le répertoire shims au début de votre PATH:

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

Ensuite, chaque fois que vous exécutez Ruby à partir de la ligne de commande ou exécutez un script dont Shebang lit #!/usr/bin/env Ruby, votre système d'exploitation trouvera ~/.rbenv/shims/Ruby d'abord et exécutez-le à la place de tout autre exécutable Ruby que vous pourriez avoir installé.

Chaque shim est un petit script Bash qui à son tour exécute rbenv exec. Donc, avec rbenv sur votre chemin, irb est équivalent à rbenv exec irb, et Ruby -e "puts 42" est équivalent à rbenv exec Ruby -e "puts 42".

Le rbenv exec commande détermine quelle version de Ruby vous souhaitez utiliser, puis exécute la commande correspondante pour cette version. Voici comment:

  1. Si la RBENV_VERSION la variable d'environnement est définie, sa valeur détermine la version de Ruby à utiliser.
  2. Si le répertoire de travail actuel a un .rbenv-version fichier, son contenu est utilisé pour définir le RBENV_VERSION variable d'environnement.
  3. Si il n'y a pas .rbenv-version dans le répertoire courant, rbenv recherche dans chaque répertoire parent un .rbenv-version fichier jusqu'à ce qu'il atteigne la racine de votre système de fichiers. S'il en trouve un, son contenu est utilisé pour définir le RBENV_VERSION variable d'environnement.
  4. Si RBENV_VERSION n'est toujours pas défini, rbenv essaie de le définir en utilisant le contenu du ~/.rbenv/version fichier.
  5. Si aucune version n'est spécifiée nulle part, rbenv suppose que vous souhaitez utiliser le "système" Ruby, c'est-à-dire. quelle que soit la version qui serait exécutée si rbenv n'était pas sur votre chemin.

(Vous pouvez définir une version spécifique au projet Ruby version avec le rbenv local, qui crée un .rbenv-version fichier dans le répertoire courant. De même, le rbenv global commande modifie le ~/.rbenv/version fichier.)

Armé d'un RBENV_VERSION variable d'environnement, rbenv ajoute ~/.rbenv/versions/$RBENV_VERSION/bin à l'avant de votre PATH, puis exécute la commande et les arguments passés à rbenv exec. Voila!

Pour un aperçu détaillé de ce qui se passe sous le capot, essayez de définir RBENV_DEBUG=1 et en exécutant une commande Ruby. Chaque commande Bash exécutée par rbenv sera écrite sur votre terminal.


Maintenant, rbenv ne s'occupe que de changer de version, mais un écosystème florissant de plugins vous aidera à tout faire de installer Ruby à configurer votre environnement , gérer " gemsets " et même automatisation bundle exec .

Je ne sais pas trop ce que le support IRC a à voir avec la commutation des versions Ruby, et rbenv est conçu pour être simple et suffisamment compréhensible pour ne pas nécessiter de support. Mais si vous avez besoin d'aide, le suivi des problèmes et Twitter ne sont qu'à quelques clics.

Divulgation: je suis l'auteur de rbenv, Ruby-build et rbenv-vars.

239
Sam Stephenson

J'ai écrit un article détaillé: http://niczsoft.com/2011/11/what-you-should-know-about-rbenv-and-rvm/

La différence fondamentale réside dans la modification de l'environnement Shell:

  • RVM: cela change quand vous changez Ruby.
  • rbenv: il est modifié lorsque vous exécutez un exécutable Ruby/gem.

En outre, le problème avec RVM est qu'il couvre beaucoup plus que la simple gestion de Rubies, il a beaucoup plus que tout autre outil (il y en a d'autres que RVM et rbenv: https://Twitter.com/# !/mpapis/status/171714447910502401 )

N'oubliez pas le support instantané que vous obtenez sur IRC dans le canal "#rvm" sur les serveurs Freenode.

18
mpapis

Donc, pour résumer les excellentes réponses ci-dessus, la principale différence pratique entre RVM et rbenv est lorsque la version de Ruby est sélectionnée.

rbenv:

rbenv ajoute une cale au début de votre chemin, une commande du même nom que Ruby. Lorsque vous tapez Ruby sur une ligne de commande, le shim est exécuté à la place (car il est également appelé "Ruby" et vient en premier dans le chemin). Le shim recherche une variable d'environnement ou .rbenv_version fichier pour lui dire à quelle version de Ruby à qui déléguer.

RVM:

RVM vous permet de définir une version de Ruby directement en appelant rvm use. En outre, il remplace également la commande système cd. Lorsque vous cd dans un dossier contenant un .rvmrc fichier, le code à l'intérieur du .rvmrc le fichier est exécuté. Cela peut être utilisé pour définir une version Ruby, ou tout autre élément de votre choix.

Autres différences:

Il y a bien sûr d'autres différences. RVM a des gemmes prêts à l'emploi, tandis que rbenv nécessite juste un peu plus de piratage (mais pas beaucoup). Les deux sont des solutions fonctionnelles au problème.

15
superluminary

La principale différence semble être quand et comment Ruby est changé . Ruby est changé:

  • pour RVM manuellement (utilisation RVM) ou automatiquement lors du changement de répertoires
  • pour rbenv automatiquement à chaque exécution d'une commande Ruby

RVM s'appuie sur la commande cd modifiée et la sélection manuelle de Ruby by rvm use. rbenv utilise des wrappers ou "shims" pour toutes les commandes de base Ruby comme mécanisme par défaut pour sélectionner Ruby. RVM crée des wrappers pour les outils de ligne de commande de base comme gem, rake, Ruby, aussi. Ils sont utilisés pour exemple dans CronJobs (voir http://rvm.io/integration/cron/ ), mais ils ne sont pas le mécanisme par défaut pour changer la version Ruby.

Ainsi, les deux méthodes sélectionnent "automatiquement" la bonne Ruby en écrasant les commandes et en utilisant des wrappers. Rvm remplace les commandes Shell comme cd. Rbenv remplace toutes les commandes de base Ruby commandes telles que comme rubis, irb, râteau et gemme.

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

Vous donne approximativement:

< 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

Et cela précède:

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

à $PATH

5
Reactormonk