Comprender el archivo Gemfile.lock

181

Después de ejecutar el bundle installcomando, se crea ' Gemfile.lock ' en el directorio de trabajo. ¿Qué significan las directivas dentro de ese archivo?

Por ejemplo, tomemos el siguiente archivo:

PATH
  remote: .
  specs:
    gem_one (0.0.1)

GEM
  remote: http://example.org/
  specs:
    gem_two (0.0.2)
    gem_three (0.0.3)
      gem_four (0.0.4)

PLATFORMS
  platform

DEPENDENCIES
  gem_two
  gem_one!

¿Qué describen ' PATH ', ' GEM ', ' PLATFORMS ' y ' DEPENDENCIES '? ¿Se requieren todos?

¿Qué debería contener los subdirectivos ' remoto ' y ' especificaciones '?

¿Qué significa el signo de exclamación después del nombre de la gema en el grupo ' DEPENDENCIAS '?

Shamaoke
fuente

Respuestas:

71

Puede encontrar más información al respecto en el sitio web del paquete (énfasis agregado a continuación para su conveniencia):

Después de desarrollar su aplicación por un tiempo, registre la aplicación junto con la instantánea Gemfile y Gemfile.lock . Ahora, su repositorio tiene un registro de las versiones exactas de todas las gemas que utilizó la última vez que sabe con certeza que la aplicación funcionó ...

Esto es importante: Gemfile.lock hace que su aplicación sea un paquete único tanto de su propio código como del código de terceros que ejecutó la última vez que sabe con seguridad que todo funcionó. Especificar versiones exactas del código de terceros del que depende en su Gemfile no proporcionaría la misma garantía, porque las gemas generalmente declaran un rango de versiones para sus dependencias.

Filipe Miguel Fonseca
fuente
65
Esto no respondió a ninguna de sus preguntas, está preguntando sobre el formato del Gemfile.lock, pero esto solo describe lo que hace.
Joshua Cheek
38

con respecto al signo de exclamación que acabo de descubrir está en gemas obtenidas a través de :git, por ejemplo

gem "foo", :git => "[email protected]:company/foo.git"
agenteo
fuente
Wow, buen trabajo resolviendo eso, también me lo he preguntado. Gracias.
JP Silvashy
55
También ocurre al cargar gemas locales a través de la pathopción. ¿Supongo que tiene algo que ver con cargar una gema no compilada?
zykadelic
Sí, esta es una razón. Pero esta NO es la única razón para que una gema se marque con un signo de exclamación. Actualmente veo que cualquier gema declarada dentro de un bloque de origen está marcada con un signo de exclamación.
Sean Moubry
35

Pasé los últimos meses jugando con Gemfiles y Gemfile.locks mucho mientras construía una herramienta de actualización de dependencia automatizada 1 . Lo siguiente está lejos de ser definitivo, pero es un buen punto de partida para comprender el formato Gemfile.lock. También es posible que desee consultar el código fuente del analizador de archivos de bloqueo de Bundler .

Encontrará los siguientes encabezados en un archivo de bloqueo generado por Bundler 1.x:

GEM (opcional pero muy común)

Estas son dependencias provenientes de un servidor Rubygems. Ese puede ser el índice principal de Rubygems, en Rubygems.org, o puede ser un índice personalizado, como los disponibles en Gemfury y otros. Dentro de esta sección verá:

  • remote: una o más líneas que especifican la ubicación de los índices de Rubygems
  • specs: una lista de dependencias, con su número de versión, y las restricciones en cualquier subdependencia

GIT (opcional)

Estas son dependencias que provienen de un remoto git dado. Verá una sección diferente para cada control remoto de git, y dentro de cada sección verá:

  • remote:El mando a distancia. P.ej,[email protected]:rails/rails
  • revision: la referencia de confirmación a la que está bloqueado el Gemfile.lock
  • tag: (opcional) la etiqueta especificada en el Gemfile
  • specs: la dependencia de git encontrada en este control remoto, con su número de versión, y las restricciones en cualquier subdependencia

RUTA (opcional)

Estas son dependencias derivadas de un determinado path, proporcionado en el Gemfile. Verá una de estas secciones diferente para cada dependencia de ruta, y dentro de cada sección verá:

  • remote:el camino. P.ej,plugins/vendored-dependency
  • specs: la dependencia de git encontrada en este control remoto, con su número de versión, y las restricciones en cualquier subdependencia

PLATAFORMAS

La plataforma Ruby contra la que se generó el Gemfile.lock. Si alguna dependencia del Gemfile especifica una plataforma, solo se incluirá en el Gemfile.lock cuando el lockfile se genera en esa plataforma (por ejemplo, a través de una instalación).

Dependencias

Una lista de las dependencias que se especifican en Gemfile, junto con la restricción de versión especificada allí.

Las dependencias especificadas con una fuente distinta del índice principal de Rubygems (por ejemplo, dependencias git, basadas en rutas, dependencias) tienen un !significado que está "anclado" a esa fuente 2 (aunque a veces hay que buscar en el Gemfile para determinar en).

VERSIÓN DE RUBIO (opcional)

La versión de Ruby especificada en el Gemfile, cuando se creó este Gemfile.lock. Si se especifica una versión de Ruby en un .ruby_versionarchivo, esta sección no estará presente (ya que Bundler considerará que el Gemfile / Gemfile.lock es independiente de la versión de Ruby del instalador).

INCLUIDO CON (Paquete> = v1.10.x)

La versión de Bundler utilizada para crear Gemfile.lock. Se usa para recordar a los instaladores que actualicen su versión de Bundler, si es anterior a la versión que creó el archivo.

FUENTE DE PLUGIN (opcional y muy rara)

En teoría, un Gemfile puede especificar complementos de Bundler, así como gemas 3 , que luego se enumerarían aquí. En la práctica, no conozco ningún complemento disponible, a partir de julio de 2017. ¡Esta parte de Bundler todavía está en desarrollo activo!


  1. https://dependabot.com
  2. https://github.com/bundler/bundler/issues/4631
  3. http://andre.arko.net/2012/07/23/towards-a-bundler-plugin-system/
greysteil
fuente
2
parece ser la mejor respuesta
daslicious
9

Bundler es un administrador de gemas que proporciona un entorno consistente para proyectos de Ruby al rastrear e instalar las gemas y versiones exactas que se necesitan.

Gemfile y Gemfile.lock son productos primarios dados por Bundler gem (Bundler en sí mismo es una gema).

Gemfile contiene la dependencia de su proyecto en las gemas, que usted menciona manualmente con las versiones especificadas, pero esas gemas dependen de otras gemas que el paquete resuelve automáticamente.

Gemfile.lock contiene una instantánea completa de todas las gemas en Gemfile junto con su dependencia asociada.

Cuando llame por primera vez a la instalación de paquete , creará este Gemfile.lock y usará este archivo en todas las llamadas posteriores a la instalación de paquete, lo que garantiza que tenga todas las dependencias instaladas y omitirá la instalación de dependencia.

Lo mismo sucede cuando comparte su código con diferentes máquinas

Compartes tu Gemfile.lock junto con Gemfile, cuando ejecutas la instalación del paquete en otra máquina, se referirá a tu Gemfile.lock y omite el paso de resolución de dependencia, en su lugar, instalará las mismas gemas dependientes que usaste en el máquina original, que mantiene la consistencia en múltiples máquinas

¿Por qué necesitamos mantener la coherencia en varias máquinas?

  • Ejecutar diferentes versiones en diferentes máquinas podría conducir a un código roto

  • Supongamos que su aplicación usaba la versión 1.5.3 y funciona hace 14 meses
    sin ningún problema, e intenta instalar en una máquina diferente
    sin Gemfile.lock ahora obtiene la versión 1.5.8. Tal vez está roto con la última versión de algunas gemas y su aplicación
    fallará. Mantener la consistencia es de suma importancia (
    práctica preferida ).

También es posible actualizar gema (s) en Gemfile.lock mediante la actualización de paquete .

Esto se basa en el concepto de actualización conservadora.

Keshav
fuente
8

Me parece que PATH enumera las dependencias de primera generación directamente de su gemspec, mientras que GEM enumera las dependencias de segunda generación (es decir, de qué dependen sus dependencias) y las de su Gemfile. PATH :: remote se .debe a que se basa en una gemspec local en el directorio actual para averiguar qué pertenece a PATH :: spec, mientras que GEM :: remote es rubygems.org, ya que ahí es donde tenía que ir para averiguar qué pertenece a GEM :: Especificaciones.

En un complemento de Rails, verá una sección de RUTA, pero no en una aplicación de Rails. Como la aplicación no tiene un archivo gemspec, no habría nada que poner en RUTA.

En cuanto a DEPENDENCIAS, gembundler.com afirma:

Runtime dependencies in your gemspec are treated like base dependencies, 
and development dependencies are added by default to the group, :development

El Gemfile generado por rails plugin new my_plugindice algo similar:

# Bundler will treat runtime dependencies like base dependencies, and
# development dependencies will be added by default to the :development group.

Lo que esto significa es que la diferencia entre

s.add_development_dependency "july" # (1)

y

s.add_dependency "july" # (2)

es que (1) solo incluirá "julio" en Gemfile.lock (y, por lo tanto, en la aplicación) en un entorno de desarrollo. Entonces, cuando corras bundle install, verás "julio" no solo en RUTA sino también en DEPENDENCIAS, sino solo en desarrollo. En producción, no estará allí en absoluto. Sin embargo, cuando use (2), verá "julio" solo en RUTA, no en DEPENDENCIAS, pero aparecerá cuando provenga bundle installde un entorno de producción (es decir, en alguna otra gema que incluya la suya como una dependencia), no Solo desarrollo.

Estas son solo mis observaciones y no puedo explicar completamente por qué nada de esto es así, pero agradezco más comentarios.

Isaac Betesh
fuente
3

Parece que no hay un documento claro hablando sobre el Gemfile.lockformato. Tal vez sea porque Gemfile.locksolo lo usa el paquete internamente.

Sin embargo, dado que Gemfile.lockes una instantánea de Gemfile, lo que significa que toda su información debe provenir Gemfile(o del valor predeterminado si no se especifica en Gemfile).

Para GEM, enumera todas las dependencias que introduce directa o indirectamente en el Gemfile. remotedebajo GEMindica dónde obtener las gemas, que se especifica por fuente en Gemfile.

Si no se obtiene una gema remote, PATHindica la ubicación para encontrarla. PATH's información proviene de ruta en Gemfilecuando se declara una dependencia.

Y PLATFORMes de aquí .

Para DEPENDENCIES, es la instantánea de las dependencias resueltas por paquete.

Hong
fuente
0

¿Qué significa el signo de exclamación después del nombre de la gema en el grupo 'DEPENDECIES'?

El signo de exclamación aparece cuando la gema se instaló utilizando una fuente distinta de " https://rubygems.org ".

Swiggels
fuente