¿Qué significa bundle exec rake?

351

Que bundle exec rake db:migratesignifica ¿O solo bundle exec rake <command>en general?

Entiendo que bundlese encarga de mantener las cosas en el Gemfile. Sé lo que significa la palabra "ejecutivo". Entiendo que rakemantiene todas las cosas diferentes que puedes hacer, y sé que db:migratees una de esas. Simplemente no sé qué hacen todas estas palabras juntas. ¿Por qué debería bundleusarse para ejecutar rakepara ejecutar una migración de base de datos?

JnBrymn
fuente

Respuestas:

468

bundle execes un comando Bundler para ejecutar un script en el contexto del paquete actual (el del Gemfile de su directorio ). rake db:migratees el script donde db es el espacio de nombres y migrate es el nombre de la tarea definida.

Entonces bundle exec rake db:migrateejecuta el script de rastrillo con el comando db:migrateen el contexto del paquete actual.

En cuanto al "¿por qué?" Citaré de la página del paquete :

En algunos casos, ejecutar ejecutables sin bundle execpuede funcionar, si el ejecutable está instalado en su sistema y no extrae gemas que entren en conflicto con su paquete.

Sin embargo, esto no es confiable y es la fuente de un dolor considerable. Incluso si parece que funciona, puede que no funcione en el futuro o en otra máquina.

ghoppe
fuente
77
¿Eso significa que siempre debemos ejecutar bundle exec? He utilizado el administrador de versiones de ruby ​​para instalar ruby ​​y ruby ​​en rieles.
Pradeep Sharma
11
@Edmund Un "paquete" es una palabra inglesa, que significa un grupo de cosas similares, por lo general bien ligadas. Específicamente en esta pregunta, se refiere a un grupo de gemas (bibliotecas de código rubí independientes). Bundler es el nombre del software que estamos usando aquí para administrar gemas. Y bundlees el comando que utiliza Bundler.
ghoppe
2
Tengo la impresión de que siempre que cd a una carpeta con Gemfile, el shell utilizará automáticamente las versiones especificadas en Gemfile (por ejemplo, la versión de Ruby). Basado en esa suposición, pensé que rake db: migrate siempre funcionaría bien sin el paquete exec. CMIIW
Pahlevi Fikri Auliya
1
@PahleviFikriAuliya eso solo es cierto si tiene un .ruby-gemsetarchivo en la raíz de su proyecto. También hay un .ruby-versionarchivo que establece su versión de ruby ​​si usa RVM.
Catfish
1
La página vinculada ya no menciona la cita que ha especificado. Por favor arregla, gracias.
Gaurang Tandon
153

Estás ejecutando bundle execun programa. Los creadores del programa lo escribieron cuando ciertas versiones de gemas estaban disponibles. El programa Gemfile especifica las versiones de las gemas que los creadores decidieron usar. Es decir, el script fue hecho para ejecutarse correctamente contra estas versiones de gemas.

Su Gemfile de todo el sistema puede diferir de este Gemfile. Es posible que tenga gemas más nuevas o más antiguas con las que este script no funciona bien. Esta diferencia en las versiones puede darte errores extraños.

bundle execLe ayuda a evitar estos errores. Ejecuta el script usando las gemas especificadas en el Gemfile del script en lugar del Gemfile de todo el sistema. Ejecuta ciertas versiones de gemas con la magia de los alias de concha.

Ver más en la página del manual .

Aquí hay un ejemplo de Gemfile:

source 'http://rubygems.org'

gem 'rails', '2.8.3'

Aquí, bundle execejecutaría el script usando rails versión 2.8.3 y no alguna otra versión que pueda haber instalado en todo el sistema.

Rose Perrone
fuente
99
Me gusta esta respuesta mejor que la elegida por el OP: D! Mucho más claro.
mauricioschneider
1
Entonces, para agregar a este ejemplo: si la persona simplemente salió rake db:migratecorriendo bundle exec, ¿se ejecutaría usando un Gemfile en todo el sistema donde uno puede tener un rack en 1.5.2 (más reciente)?
Smokin Joe
respuesta mucho mejor, con ejemplos concretos.
ahnbizcad
2
Por lo tanto, bundle executiliza las gemas locales "específicas de la aplicación" en su Gemfile de su aplicación, y bundleutiliza las gemas globales "específicas de la máquina" si lo hizo gem install a_certain_gem. local vs global
ahnbizcad
Respuesta mucho mejor que la elegida.
Boon
9

Esto surge mucho cuando su gemfile.lock tiene diferentes versiones de las gemas instaladas en su máquina. Puede recibir una advertencia después de ejecutar rake (o rspec u otros) como:

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.

El antecedente bundle execle dice al agrupador que ejecute este comando independientemente de la versión diferencial. No siempre hay un problema, sin embargo, puede tener problemas.

Afortunadamente, hay una gema que resuelve esto: rubygems-bundler.

$ gem install rubygems-bundler

$ $ gem regenerate_binstubs

Luego prueba tu rastrillo, rspec o lo que sea de nuevo

Benjamin Dunphy
fuente
Sigue siendo una gran solución en 2020.
Brateq
6

Probablemente debería mencionarse que hay formas de omitir bundle exec(todas se mencionan en el capítulo 3.6.1 del libro Tutorial Ruby on Rails de Michael Hartls ).

Lo más simple es usar una versión suficientemente actualizada de RVM (> = 1.11.x).

Si está restringido a una versión anterior de RVM, siempre puede usar este método también mencionado por calasyr :

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

El bundler_stubsdirectorio también debe agregarse al .gitignorearchivo.

Una tercera opción es usar la rubygems-bundlergema si no estás usando RVM:

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

Cuando ejecuta directamente la tarea de rastrillo o ejecuta cualquier archivo binario de una gema, no hay garantía de que el comando se comporte como se esperaba. Porque puede suceder que ya tenga la misma gema instalada en su sistema que tiene una versión que dice 1.0 pero en su proyecto tiene una versión más alta que dice 2.0. En este caso, no puede predecir cuál se utilizará.

Para imponer la versión de gema deseada, toma la ayuda del bundle execcomando que ejecutaría el binario en el contexto del paquete actual. Eso significa que cuando usa bundle exec, bundler comprueba la versión de gema configurada para el proyecto actual y la usa para realizar la tarea.

También escribí una publicación al respecto que también muestra cómo podemos evitar usarlo usando los apéndices bin.

Ajit Singh
fuente
1

No he usado bundle execmucho, pero lo estoy configurando ahora.

He tenido casos en los que se utilizó el rastrillo incorrecto y se perdió mucho tiempo rastreando el problema. Esto te ayuda a evitar eso.

A continuación, le mostramos cómo configurar RVM para que pueda usar bundle execde manera predeterminada dentro de un directorio de proyecto específico:

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

calasyr
fuente
0

Significa usar el rastrillo que el agrupador conoce y forma parte de su Gemfile sobre cualquier rastrillo que el agrupador no conozca y ejecute la tarea db: migrate.

Omar Qureshi
fuente