Que signifie bundle exec rake?

351

Que veut bundle exec rake db:migratedire? Ou juste bundle exec rake <command>en général?

Je comprends que cela bundleprend soin de maintenir les choses dans le Gemfile. Je sais ce que le mot "exec" signifie. Je comprends que cela rakemaintient toutes les différentes choses que vous pouvez faire, et je sais que db:migratec'est l'une d'entre elles. Je ne sais tout simplement pas ce que tous ces mots font ensemble. Pourquoi devrait bundleêtre utilisé pour exécuter rakepour exécuter une migration de base de données?

JnBrymn
la source

Réponses:

468

bundle execest une commande Bundler pour exécuter un script dans le contexte du bundle actuel (celui du Gemfile de votre répertoire ). rake db:migrateest le script où db est l'espace de noms et migrate est le nom de tâche défini.

bundle exec rake db:migrateExécute donc le script rake avec la commande db:migratedans le contexte du bundle actuel.

Quant au "pourquoi?" Je vais citer la page du bundler :

Dans certains cas, l'exécution d'exécutables sans bundle execpeut fonctionner, si l'exécutable est installé sur votre système et ne récupère aucune gemme en conflit avec votre bundle.

Cependant, cela n'est pas fiable et est à l'origine d'une douleur considérable. Même s'il semble que cela fonctionne, il peut ne pas fonctionner à l'avenir ou sur une autre machine.

ghoppe
la source
7
Cela signifie-t-il que nous devrions toujours exécuter le bundle exec, j'ai utilisé le gestionnaire de version ruby ​​pour installer ruby ​​et ruby ​​sur les rails.
Pradeep Sharma
11
@Edmund Un "bundle" est un mot anglais, ce qui signifie un groupe de choses similaires, généralement bien liées. Plus précisément dans cette question, il fait référence à un groupe de gemmes (bibliothèques de code rubis autonomes.) Bundler est le nom du logiciel que nous utilisons ici pour gérer les gemmes. Et bundlec'est la commande qui est utilisée par Bundler.
ghoppe
2
J'ai l'impression que chaque fois que nous cd dans un dossier avec Gemfile, le shell utilisera automatiquement les versions spécifiées dans Gemfile (par exemple la version Ruby). Sur la base de cette hypothèse, je pensais que rake db: migrate fonctionnerait toujours correctement sans bundle exec. CMIIW
Fikri Auliya
1
@PahleviFikriAuliya qui n'est vrai que si vous avez un .ruby-gemsetfichier dans la racine de votre projet. Il existe également un .ruby-versionfichier qui définit votre version ruby ​​si vous utilisez RVM.
Catfish
1
La page liée ne mentionne plus le devis que vous avez spécifié. Veuillez corriger, merci.
Gaurang Tandon
153

Vous exécutez bundle execun programme. Les créateurs du programme l'ont écrit lorsque certaines versions de gemmes étaient disponibles. Le programme Gemfile spécifie les versions des gemmes que les créateurs ont décidé d'utiliser. Autrement dit, le script a été conçu pour fonctionner correctement avec ces versions de gemmes.

Votre Gemfile à l'échelle du système peut différer de ce Gemfile. Vous pouvez avoir des gemmes plus récentes ou plus anciennes avec lesquelles ce script ne joue pas bien. Cette différence de versions peut vous donner des erreurs étranges.

bundle execvous aide à éviter ces erreurs. Il exécute le script en utilisant les gemmes spécifiées dans le Gemfile du script plutôt que le Gemfile à l'échelle du système. Il exécute certaines versions de gemmes avec la magie des alias de shell.

Voir plus sur la page de manuel .

Voici un exemple de Gemfile:

source 'http://rubygems.org'

gem 'rails', '2.8.3'

Ici, bundle execexécuterait le script à l'aide de rails version 2.8.3 et non d'une autre version que vous pourriez avoir installée à l'échelle du système.

Rose Perrone
la source
9
J'aime mieux cette réponse que celle choisie par l'OP: D! Beaucoup plus clair.
mauricioschneider
1
Donc, pour ajouter à cet exemple: si la personne a simplement rake db:migrateabandonné, bundle execelle s'exécuterait en utilisant un Gemfile à l'échelle du système où l'on peut avoir un rack à 1.5.2 (dernier)?
Smokin Joe
bien meilleure réponse, avec des exemples concrets.
ahnbizcad
2
bundle execUtilise donc les gemmes locales "spécifiques à l'application" dans votre Gemfile de votre application, et bundleutilise les gemmes globales "spécifiques à la machine" si vous l'avez fait gem install a_certain_gem. local vs global
ahnbizcad
Réponse bien meilleure que celle choisie.
Boon
9

Cela revient souvent lorsque votre gemfile.lock a différentes versions des gemmes installées sur votre machine. Vous pouvez recevoir un avertissement après avoir exécuté le râteau (ou rspec ou autres) tels que:

You have already activated rake 10.3.1, but your Gemfile requires rake 10.1.0. Prepending "bundle exec" to your command may solve this.

Prepending bundle execindique au bundler d'exécuter cette commande indépendamment de la différence de version. Il n'y a pas toujours de problème, cependant, vous pourriez rencontrer des problèmes.

Heureusement, il existe un joyau qui résout ce problème: rubygems-bundler.

$ gem install rubygems-bundler

$ $ gem regenerate_binstubs

Essayez ensuite votre râteau, rspec ou autre chose.

Benjamin Dunphy
la source
Encore une excellente solution en 2020.
Brateq
6

Il convient probablement de mentionner qu'il existe des moyens d'omettre bundle exec(ils sont tous indiqués dans le chapitre 3.6.1 du livre Tutoriel Michael Hartls Ruby on Rails ).

Le plus simple est d'utiliser simplement une version suffisamment à jour de RVM (> = 1.11.x).

Si vous êtes limité à une version antérieure de RVM, vous pouvez toujours utiliser cette méthode également mentionnée par calasyr :

$ rvm get head && rvm reload
$ chmod +x $rvm_path/hooks/after_cd_bundler
$ bundle install --binstubs=./bundler_stubs

Le bundler_stubsrépertoire doit ensuite également être ajouté au .gitignorefichier.

Une troisième option consiste à utiliser la rubygems-bundlergemme si vous n'utilisez pas RVM:

$ gem install rubygems-bundler
$ gem regenerate_binstubs
tschale
la source
1

Lorsque vous exécutez directement la tâche de râteau ou exécutez n'importe quel fichier binaire d'une gemme, rien ne garantit que la commande se comportera comme prévu. Parce qu'il peut arriver que vous ayez déjà la même gemme installée sur votre système qui a une version disons 1.0 mais dans votre projet vous avez une version supérieure disons 2.0. Dans ce cas, vous ne pouvez pas prédire lequel sera utilisé.

Pour appliquer la version de gemme souhaitée, vous utilisez l'aide de la bundle execcommande qui exécuterait le binaire dans le contexte du bundle actuel. Cela signifie que lorsque vous utilisez le bundle exec, bundler vérifie la version gem configurée pour le projet en cours et l'utilise pour effectuer la tâche.

J'ai également écrit un article à ce sujet qui montre également comment nous pouvons éviter de l'utiliser en utilisant des talons de bac.

Ajit Singh
la source
1

Je n'ai pas bundle execbeaucoup utilisé , mais je le mets en place maintenant.

J'ai eu des cas où le mauvais râteau a été utilisé et beaucoup de temps perdu à rechercher le problème. Cela vous aide à éviter cela.

Voici comment configurer RVM pour pouvoir l'utiliser bundle execpar défaut dans un répertoire de projet spécifique:

https://thoughtbot.com/blog/use-bundlers-binstubs

calasyr
la source
0

Cela signifie utiliser le râteau que le bundler connaît et fait partie de votre Gemfile sur tout rake que le bundler n'a pas connu et exécuter la tâche db: migrate.

Omar Qureshi
la source