¿Cuál es la diferencia entre Gemfile y Gemfile.lock en Ruby on Rails?

Respuestas:

159

Aquí Gemfilees donde especifica qué gemas desea usar, y le permite especificar qué versiones.

El Gemfile.lockarchivo es donde Bundler registra las versiones exactas que se instalaron. De esta manera, cuando se carga la misma biblioteca / proyecto en otra máquina, la ejecución bundle installexaminará Gemfile.locke instalará las mismas versiones exactas, en lugar de solo usar Gemfilee instalar las versiones más recientes. (Ejecutar diferentes versiones en diferentes máquinas podría llevar a pruebas rotas, etc.) Nunca debería tener que editar directamente el archivo de bloqueo.

Consulte el Propósito y la justificación de Bundler , específicamente la sección Verificar su código en el Control de versiones.

Dylan Markow
fuente
2
Así es como debería funcionar, pero aparentemente Gemfile.lockincluye versiones "abiertas" en algunos casos (por ejemplo, rails (4.0.0)requiere bundler (>= 1.3.0, < 2.0)), lo que causa problemas. ¿Alguna idea de cómo evitar esas dependencias 'abiertas'?
Guillermo Grau
158

Por lo general, escribimos dependencias en Gemfile como:

gem "nokogiri", "~> 1.4.4"
gem 'bcrypt-ruby', '~> 3.0.0'
gem 'uglifier', '>= 1.2.3'
..

Aquí básicamente dices: " Quiero nokogiri siempre que sea mayor que la versión 1.4.4 ", etc. Ahora supongamos que configuré mi hace Gemfile 8 meses y configuré mi aplicación con este requisito. Hace 8 meses la versión nokogiri era 1.4.4 . Mis aplicaciones de rieles funcionaban perfectamente sin ningún problema con esta versión.

Ahora piensa que estoy tratando de construir con lo mismo Gemfile. Pero si miramos las versiones de nokogiri , vemos que la versión estable actual ha cambiado a 1.4.9 . Eso significa que si intentamos construir, el paquete instalará la versión 1.4.9 de nokogiri (supongamos que no tenemos Gemfile.lock).

Qué significa eso ?

Como ves si no tienes ninguno Gemfile.locky ejecuta:

bundle install

entonces las gemas utilizadas actualmente pueden ser diferentes en cualquier momento . Su aplicación utilizaba la versión 1.4.4 y funciona hace 8 meses sin ningún problema, pero si intenta compilarla ahora obtendrá la versión 1.4.9 . Tal vez está roto con la última versión de nokogiri, la increíble característica que usó con 1.4.4 no está más disponible, etc.

Para evitar este tipo de problema Gemfile.lockse utiliza. En Gemfile.locksolamente las versiones exactas son escritas y por lo tanto sólo éstos serán instalados. Eso significa que si distribuye su aplicación con un Gemfile.lock, cada máquina tendrá las mismas gemas instaladas y lo más importante es que todas obtienen la misma versión . Esto le dará una pila de implementación estable y común.

¿Cómo se crea Gemfile.lock?

Se crea automáticamente con el primero:

bundle install

mando. Después de eso, cada vez que ejecute bundle install, el paquete primero buscará Gemfile.locke instalará las gemas especificadas allí. Es un hábito distribuir este archivo entre sus proyectos para proporcionar coherencia y estabilidad.

¿Cómo actualizar Gemfile.lock?

Si está satisfecho con la última versión de sus aplicaciones, puede actualizarla Gemfile.lock. Solo refleja tus cambios a Gemfile. Eso significa cambiar las dependencias a las nuevas versiones exactas en Gemfile. Después de esa carrera:

bundle install

Esto lo actualizará Gemfile.lockcon su versión más reciente de aplicaciones.

Fatih Arslan
fuente
19
Una descripción muy bonita y clara (he votado); pero un punto crítico, sin embargo: nokogiri ~> 1.4.4no permitiría 1.5.3ser instalado; max permitido sería 1.4.xdonde x>=4(para nokogiri sería 1.4.7). El ~>operador significa que solo el último dígito en la gema utilizada puede ser "mayor que" la versión dada. Por ejemplo, foo ~> a.b.c.dsignifica que cualquier versión de fooestá bien siempre y cuando siga siendo abc {something} donde {something} >=d. Ver también la pregunta relacionada
michael
1
Lo que me confunde es que ya está especificando versiones específicas gem "nokogiri", "~> 1.4.4"al usarlas en el archivo de gemas. ¿Por qué el paquete no podía usar esa versión? ¿Es porque está diseñado para instalar intencionalmente las últimas versiones de la gema por defecto?
Jonny
@ Jonny, mira el comentario de michael_n. ~> 1.4.4 no especifica una versión exacta.
Matthew Flaschen
2
@ Jonny, ~> 1.4.4es equivalente a >= 1.4.4 and < 1.5. Ver bundler.io/v1.5/gemfile.html . Para una versión exacta, solo use gem 'foo', '1.4.4'.
Matthew Flaschen
1
Gran respuesta, pero por favor aclare "¿ actualizar Gemfile.lock? ": ¿Esta sección dice que bundle installverificará Gemfileincluso si hay una Gemfile.locky aplicará nuevas restricciones Gemfile.lock?
JMess
4

El Gemfile.lock

Cuando ejecuta la instalación del paquete, Bundler conservará los nombres completos y las versiones de todas las gemas que utilizó (incluidas las dependencias de las gemas especificadas en el Gemfile (5)) en un archivo llamado Gemfile.lock.

Bundler usa este archivo en todas las llamadas posteriores a la instalación de paquetes, lo que garantiza que siempre use el mismo código exacto, incluso cuando su aplicación se mueva a través de las máquinas.

Debido a la forma en que funciona la resolución de dependencias, incluso un cambio aparentemente pequeño (por ejemplo, una actualización a una liberación puntual de una dependencia de una gema en su Gemfile (5)) puede resultar en que se necesiten gemas radicalmente diferentes para satisfacer todas las dependencias.

Como resultado, DEBE verificar su Gemfile.lock en el control de versiones. Si no lo hace, cada máquina que revisa su repositorio (incluido su servidor de producción) resolverá todas las dependencias nuevamente, lo que resultará en el uso de diferentes versiones de código de terceros si alguna de las gemas en el Gemfile (5) o cualquiera de sus dependencias han sido actualizadas.

Ajey
fuente