Que signifie bundle exec rake db:migrate
? Ou simplement bundle exec rake <command>
en général?
Je comprends que bundle
s’occupe de maintenir les choses dans le Gemfile. Je sais ce que le mot "exec" signifie. Je comprends que rake
conserve toutes les tâches scriptées que vous pouvez faire et je sais que db:migrate
en fait partie. Je ne sais tout simplement pas ce que tous ces mots font ensemble. Pourquoi utiliser bundle
pour exécuter rake
afin d'exécuter une migration de base de données?
bundle exec
est une commande Bundler permettant d'exécuter un script dans le contexte de l'ensemble actuel (celui de votre répertoire Gemfile ). _rake db:migrate
_ est le script où db est l’espace de nom et migrate est le nom de la tâche défini.
Donc _bundle exec rake db:migrate
_ exécute le script rake avec la commande _db:migrate
_ dans le contexte du bundle actuel.
Quant au "pourquoi?" Je citerai le page de bundler :
Dans certains cas, l'exécution d'exécutables sans _
bundle exec
_ peut fonctionner si l'exécutable est installé sur votre système et n'entraîne aucune gemme en conflit avec votre bundle.Cependant, cela n’est pas fiable et est la source d’une douleur considérable. Même si cela semble fonctionner, il est possible que cela ne fonctionne pas à l'avenir ou sur une autre machine.
Vous exécutez bundle exec
sur un programme. Les créateurs du programme l'ont écrit lorsque certaines versions de gems étaient disponibles. Le programme Gemfile spécifie les versions des gemmes que les créateurs ont décidé d'utiliser. C'est-à-dire que le script a été conçu pour s'exécuter correctement sur ces versions de gem.
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 à Nice. Cette différence dans les versions peut vous donner des erreurs étranges.
bundle exec
vous aide à éviter ces erreurs. Il exécute le script en utilisant les gems spécifiés dans le fichier Gemfile du script plutôt que dans le fichier Gemfile système. Il exécute certaines versions de gemmes avec la magie des alias Shell.
Voir plus sur la page de manuel .
Voici un exemple de Gemfile:
source 'http://rubygems.org'
gem 'Rails', '2.8.3'
Ici, bundle exec
exécuterait le script en utilisant Rails version 2.8.3 et non une autre version que vous auriez peut-être installée à l'échelle du système.
Cela arrive souvent lorsque votre gemfile.lock a différentes versions des gemmes installées sur votre ordinateur. Vous pouvez recevoir un avertissement après avoir exécuté rake (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.
Le préfixe bundle exec
indique au groupeur qu'il doit exécuter cette commande, quelle que soit la version. Il n'y a pas toujours de problème, cependant, vous pourriez avoir des problèmes.
Heureusement, il existe un bijou qui résout ce problème: rubygems-bundler.
$ gem install rubygems-bundler
$ $ gem regenerate_binstubs
Ensuite, essayez votre rake, rspec ou autre chose.
Il convient probablement de mentionner qu'il existe des moyens d'omettre bundle exec
(ils sont tous décrits dans le chapitre 3.6.1 de Michael Hartls Ruby sur Rails Tutorial livre).
Le plus simple consiste simplement à utiliser une version suffisamment récente 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 répertoire bundler_stubs
doit alors également être ajouté au fichier .gitignore
.
Une troisième option consiste à utiliser la gemme rubygems-bundler
si vous n'utilisez pas RVM:
$ gem install rubygems-bundler
$ gem regenerate_binstubs
Je n'ai pas beaucoup utilisé bund, mais je le configure maintenant.
J'ai eu des cas où le mauvais râteau a été utilisé et beaucoup de temps perdu à chercher le problème. Cela vous aide à éviter cela.
Voici comment configurer rvm afin que vous puissiez utiliser bundle exec par défaut dans un répertoire de projet spécifique:
http://robots.thoughtbot.com/post/15346721484/use-bundlers-binstubs
Lorsque vous exécutez directement la tâche rake ou que vous exécutez un 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à installé la même gemme sur votre système, avec la version 1.0, mais que dans votre projet, vous disposiez d'une version supérieure, dites 2.0. Dans ce cas, vous ne pouvez pas prédire lequel sera utilisé.
Pour appliquer la version de gem souhaitée, utilisez l'aide de la commande bundle exec
qui exécutera le fichier binaire dans le contexte de l'ensemble actuel. Cela signifie que lorsque vous utilisez bundle exec, bundler vérifie la version de gem configurée pour le projet en cours et l'utilise pour effectuer la tâche.
J'ai également écrit un post qui indique également comment nous pouvons éviter de l'utiliser avec des stubs de bacs.
Cela signifie que vous devez utiliser rake et que le bundleur en a connaissance. Il fait partie de votre fichier Gemfile par-dessus tout rake qu'il ignore et qu'il exécute la tâche db: migrate.