Cosa significa bundle exec rake?


351

Cosa bundle exec rake db:migratesignifica? O semplicemente bundle exec rake <command>in generale?

Capisco che bundlesi occupa di mantenere le cose nel Gemfile. So cosa significa la parola "exec". Capisco che rakemantiene tutte le diverse cose scripty che puoi fare, e so che db:migrateè una di quelle. Semplicemente non so cosa facciano tutte queste parole insieme. Perché dovrebbe bundleessere usato per eseguire rakeper eseguire una migrazione del database?

Risposte:


468

bundle execè un comando Bundler per eseguire uno script nel contesto del bundle corrente (quello dal Gemfile della tua directory ). rake db:migrateè lo script in cui db è lo spazio dei nomi e migrate è il nome dell'attività definito.

Quindi bundle exec rake db:migrateesegue lo script rake con il comando db:migratenel contesto del bundle corrente.

Quanto al "perché?" Citerò dalla pagina del bundler :

In alcuni casi, l'esecuzione di eseguibili senza bundle execpuò funzionare, se l'eseguibile sembra essere installato nel tuo sistema e non estrae gemme in conflitto con il tuo bundle.

Tuttavia, questo è inaffidabile ed è la fonte di notevole dolore. Anche se sembra che funzioni, potrebbe non funzionare in futuro o su un'altra macchina.


7
Ciò significa che dovremmo sempre eseguire bundle exec, ho usato il gestore versione ruby ​​per installare ruby ​​e ruby ​​su binari.
Pradeep Sharma,

11
@Edmund Un "fascio" è una parola inglese, che significa un gruppo di cose simili, di solito legate ordinatamente. Nello specifico in questa domanda, fa riferimento a un gruppo di gemme (librerie di codici ruby ​​indipendenti). Bundler è il nome del software che stiamo usando qui per gestire le gemme. Ed bundleè il comando utilizzato da Bundler.
ghoppe,

2
Ho l'impressione che ogni volta che eseguiamo il cd in una cartella con Gemfile, la shell utilizzerà automaticamente le versioni specificate in Gemfile (ad esempio la versione di Ruby). Sulla base di questo presupposto, ho pensato che rake db: migrate sarebbe sempre andato bene senza bund bund exec. CMIIW
Pahlevi Fikri Auliya,

1
@PahleviFikriAuliya è vero solo se hai un .ruby-gemsetfile nella radice del tuo progetto. C'è anche un .ruby-versionfile che imposta la versione di Ruby se si utilizza RVM.
Pesce gatto

1
La pagina collegata non menziona più la citazione che hai specificato. Per favore, grazie.
Gaurang Tandon,

153

Stai eseguendo bundle execun programma. I creatori del programma lo hanno scritto quando erano disponibili alcune versioni di gemme. Il programma Gemfile specifica le versioni delle gemme che i creatori hanno deciso di utilizzare. Cioè, lo script è stato creato per funzionare correttamente con queste versioni gem.

Il tuo Gemfile a livello di sistema potrebbe essere diverso da questo Gemfile. Potresti avere gemme nuove o più vecchie con le quali questo script non funziona bene. Questa differenza nelle versioni può dare strani errori.

bundle execti aiuta a evitare questi errori. Esegue lo script usando le gemme specificate nel Gemfile dello script anziché nel Gemfile a livello di sistema. Esegue alcune versioni di gemme con la magia degli alias di shell.

Vedi di più sulla pagina man .

Ecco un esempio Gemfile:

source 'http://rubygems.org'

gem 'rails', '2.8.3'

Qui, bundle execeseguiresti lo script usando rails versione 2.8.3 e non qualche altra versione che potresti aver installato a livello di sistema.


9
Mi piace questa risposta meglio di quella scelta dall'OP: D! Molto più chiaro.
mauricioschneider,

1
Quindi, per aggiungere a questo esempio: se la persona semplicemente correva rake db:migratetralasciando bundle exec, verrebbe eseguita usando un Gemfile a livello di sistema in cui si potrebbe avere un rack a 1.5.2 (ultimo)?
Smokin Joe,

risposta molto migliore, con esempi concreti.
ahnbizcad,

2
Quindi bundle executilizza le gemme locali "specifiche dell'app" nel Gemfile della tua app e, se lo facevi, bundleusa le gemme globali "specifiche della macchina" gem install a_certain_gem. local vs global
ahnbizcad,

Risposta molto migliore di quella scelta.
Boon,

9

Questo si presenta molto quando gemfile.lock ha versioni diverse delle gemme installate sul tuo computer. Potresti ricevere un avviso dopo aver eseguito rake (o rspec o altri) come:

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 execdice al bundler di eseguire questo comando indipendentemente dal differenziale di versione. Non sempre c'è un problema, tuttavia, potresti incorrere in problemi.

Fortunatamente, c'è una gemma che risolve questo problema: rubygems-bundler.

$ gem install rubygems-bundler

$ $ gem regenerate_binstubs

Quindi prova di nuovo il tuo rake, rspec o qualsiasi altra cosa.


Ancora un'ottima soluzione nel 2020.
Brateq

6

Dovrebbe probabilmente essere menzionato che ci sono modi per omettere bundle exec(sono tutti indicati nel capitolo 3.6.1 del libro di tutorial di Michael Hartls Ruby on Rails ).

Il più semplice è usare solo una versione sufficientemente aggiornata di RVM (> = 1.11.x).

Se sei limitato a una versione precedente di RVM, puoi sempre utilizzare questo metodo menzionato anche da calasyr :

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

La bundler_stubsdirectory dovrebbe quindi essere aggiunta anche al .gitignorefile.

Una terza opzione è quella di utilizzare la rubygems-bundlergemma se non si utilizza RVM:

$ gem install rubygems-bundler
$ gem regenerate_binstubs

1

Quando si esegue direttamente l'attività di rake o si esegue un file binario di una gemma, non esiste alcuna garanzia che il comando si comporti come previsto. Perché potrebbe accadere che tu abbia già installato la stessa gemma sul tuo sistema che ha una versione diciamo 1.0 ma nel tuo progetto hai una versione più alta diciamo 2.0. In questo caso non è possibile prevedere quale verrà utilizzato.

Per imporre la versione gemma desiderata, prendi l'aiuto del bundle execcomando che eseguirà il binario nel contesto del bundle corrente. Ciò significa che quando si utilizza bundle exec, il bundler controlla la versione gem configurata per il progetto corrente e la utilizza per eseguire l'attività.

Ho anche scritto un post su di esso che mostra anche come possiamo evitare di usarlo usando gli stub bin.


1

Non ho usato bundle execmolto, ma lo sto configurando ora.

Ho avuto casi in cui è stato utilizzato il rastrello sbagliato e molto tempo perso a rintracciare il problema. Questo ti aiuta a evitarlo.

Ecco come impostare RVM in modo da poterlo utilizzare bundle execper impostazione predefinita all'interno di una directory di progetto specifica:

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


0

Significa utilizzare il rake di cui il bundler è a conoscenza e fa parte del proprio Gemfile su qualsiasi rake di cui il bundler non è a conoscenza ed eseguire l'attività db: migrate.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.