Was bedeutet Bundle Exec Rake?

350

Was heißt bundle exec rake db:migratedas Oder nur bundle exec rake <command>allgemein?

Ich verstehe, dass es bundledarum geht, die Dinge in der Gemfile zu pflegen. Ich weiß, was das Wort "exec" bedeutet. Ich verstehe, dass rakeall die verschiedenen Scripty-Dinge, die Sie tun können , beibehalten werden, und ich weiß, dass dies db:migrateeine davon ist. Ich weiß nur nicht, was all diese Wörter zusammen tun. Warum soll bundleverwendet werden , um auszuführen , rakeeine Datenbank migrieren ausführen?

JnBrymn
quelle

Antworten:

468

bundle execist ein Bundler- Befehl zum Ausführen eines Skripts im Kontext des aktuellen Bundles (das aus der Gemfile Ihres Verzeichnisses ). rake db:migrateist das Skript, in dem db der Namespace und migrate der definierte Aufgabenname ist.

So bundle exec rake db:migrateführt den Rake - Skript mit dem Befehl db:migrateim Kontext des aktuellen Bundles.

Was das "Warum?" Ich zitiere von der Bundler-Seite :

In einigen Fällen kann das Ausführen von ausführbaren Dateien ohne bundle execfunktionieren, wenn die ausführbare Datei zufällig auf Ihrem System installiert ist und keine Edelsteine ​​enthält, die mit Ihrem Bundle in Konflikt stehen.

Dies ist jedoch unzuverlässig und verursacht erhebliche Schmerzen. Selbst wenn es so aussieht, als würde es funktionieren, funktioniert es möglicherweise in Zukunft oder auf einem anderen Computer nicht mehr.

Ghoppe
quelle
7
Bedeutet das, dass wir immer Bundle Exec ausführen sollten? Ich habe Ruby Version Manager verwendet, um Ruby und Ruby auf Schienen zu installieren.
Pradeep Sharma
11
@Edmund Ein "Bündel" ist ein englisches Wort, das eine Gruppe ähnlicher Dinge bedeutet, die normalerweise ordentlich zusammengebunden sind. Speziell in dieser Frage bezieht es sich auf eine Gruppe von Gems (in sich geschlossene Ruby-Code-Bibliotheken). Bundler ist der Name der Software, die wir hier zum Verwalten von Gems verwenden. Und bundleist der Befehl, der von Bundler verwendet wird.
Ghoppe
2
Ich habe den Eindruck, dass die Shell bei jeder CD in einen Ordner mit Gemfile automatisch die in Gemfile angegebenen Versionen verwendet (z. B. Ruby-Version). Basierend auf dieser Annahme dachte ich, dass Rake DB: Migrate ohne Bundle Exec immer gut laufen würde. CMIIW
Pahlevi Fikri Auliya
1
@PahleviFikriAuliya das ist nur wahr, wenn Sie eine .ruby-gemsetDatei in Ihrem Projektstamm haben. Es gibt auch eine .ruby-versionDatei, die Ihre Ruby-Version festlegt, wenn Sie RVM verwenden.
Wels
1
Auf der verlinkten Seite wird das von Ihnen angegebene Zitat nicht mehr erwähnt. Bitte beheben, danke.
Gaurang Tandon
153

Sie laufen bundle execauf einem Programm. Die Entwickler des Programms haben es geschrieben, als bestimmte Versionen von Edelsteinen verfügbar waren. Das Programm Gemfile gibt die Versionen der Edelsteine ​​an, für die sich die Ersteller entschieden haben. Das heißt, das Skript wurde so erstellt, dass es mit diesen Edelsteinversionen korrekt ausgeführt wird.

Ihre systemweite Gemfile kann von dieser Gemfile abweichen. Möglicherweise haben Sie neuere oder ältere Edelsteine, mit denen dieses Skript nicht gut funktioniert. Dieser Unterschied in den Versionen kann zu seltsamen Fehlern führen.

bundle exechilft Ihnen, diese Fehler zu vermeiden. Das Skript wird mit den in der Gemfile des Skripts angegebenen Gems und nicht mit der systemweiten Gemfile ausgeführt. Es führt bestimmte Edelsteinversionen mit der Magie von Shell-Aliasen aus.

Weitere Informationen finden Sie auf der Manpage .

Hier ist ein Beispiel für Gemfile:

source 'http://rubygems.org'

gem 'rails', '2.8.3'

Hier bundle execwürde das Skript mit Rails Version 2.8.3 ausgeführt und nicht mit einer anderen Version, die Sie möglicherweise systemweit installiert haben.

Rose Perrone
quelle
9
Diese Antwort gefällt mir besser als die vom OP gewählte: D! Viel klarer.
Mauricioschneider
1
Um dieses Beispiel zu ergänzen: Wenn die Person einfach rake db:migrateausgelassen bundle exechat, wird sie mit einer systemweiten Gem-Datei ausgeführt, in der möglicherweise ein Rack mit 1.5.2 (spätestens) vorhanden ist.
Smokin Joe
viel bessere Antwort mit konkreten Beispielen.
Ahnbizcad
2
So bundle execverwendet die „App-spezifischen“, lokale Edelsteine in Ihrer Gemfile Ihrer Anwendung und bundleverwendet die „maschinenspezifische“, globale Edelsteine , wenn Sie getan haben gem install a_certain_gem. lokal gegen global
ahnbizcad
Viel bessere Antwort als die Auserwählte.
Boon
9

Dies tritt häufig auf, wenn in Ihrem gemfile.lock verschiedene Versionen der Gems auf Ihrem Computer installiert sind. Möglicherweise erhalten Sie eine Warnung, nachdem Sie rake (oder rspec oder andere) ausgeführt haben, z.

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.

Das Voranstellen bundle execweist den Bundler an, diesen Befehl unabhängig vom Versionsunterschied auszuführen. Es gibt nicht immer ein Problem, es können jedoch Probleme auftreten.

Glücklicherweise gibt es ein Juwel, das dieses Problem löst: Rubygems-Bundler.

$ gem install rubygems-bundler

$ $ gem regenerate_binstubs

Dann versuchen Sie es erneut mit Ihrem Rechen, Rspec oder was auch immer.

Benjamin Dunphy
quelle
Immer noch eine großartige Lösung im Jahr 2020.
Brateq
6

Es sollte wahrscheinlich erwähnt werden, dass es Möglichkeiten gibt, diese wegzulassen bundle exec(sie sind alle in Kapitel 3.6.1 des Michael Hartls Ruby on Rails-Tutorial- Buches aufgeführt).

Am einfachsten ist es, nur eine ausreichend aktuelle Version von RVM (> = 1.11.x) zu verwenden.

Wenn Sie auf eine frühere Version von RVM beschränkt sind, können Sie immer diese Methode verwenden, die auch von calasyr erwähnt wird :

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

Das bundler_stubsVerzeichnis sollte dann auch zur .gitignoreDatei hinzugefügt werden.

Eine dritte Option ist die Verwendung des rubygems-bundlerEdelsteins, wenn Sie kein RVM verwenden:

$ gem install rubygems-bundler
$ gem regenerate_binstubs
tschale
quelle
1

Wenn Sie die Rake-Task direkt ausführen oder eine Binärdatei eines Gems ausführen, gibt es keine Garantie dafür, dass sich der Befehl wie erwartet verhält. Weil es passieren kann, dass Sie bereits dasselbe Juwel auf Ihrem System installiert haben, das eine Version von beispielsweise 1.0 hat, aber in Ihrem Projekt eine höhere Version von beispielsweise 2.0 haben. In diesem Fall können Sie nicht vorhersagen, welches verwendet wird.

Um die gewünschte Gem-Version zu erzwingen, verwenden Sie den bundle execBefehl, der die Binärdatei im Kontext des aktuellen Bundles ausführt. Das heißt, wenn Sie Bundle Exec verwenden, überprüft Bundler die für das aktuelle Projekt konfigurierte Gem-Version und verwendet diese, um die Aufgabe auszuführen.

Ich habe auch einen Beitrag darüber geschrieben, der auch zeigt, wie wir es vermeiden können, ihn mit bin stubs zu verwenden.

Ajit Singh
quelle
1

Ich habe nicht bundle execviel benutzt, aber ich richte es jetzt ein.

Ich hatte Fälle, in denen der falsche Rechen verwendet wurde und viel Zeit damit verschwendet wurde, das Problem aufzuspüren. Dies hilft Ihnen, dies zu vermeiden.

So richten Sie RVM so ein, dass Sie es bundle execstandardmäßig in einem bestimmten Projektverzeichnis verwenden können:

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

Calasyr
quelle
0

Dies bedeutet, dass Sie den Rake verwenden, den der Bundler kennt und der Teil Ihrer Gemfile ist, und zwar über jeden Rake, den der Bundler nicht kennt, und die Aufgabe db: migrate ausführen.

Omar Qureshi
quelle