ruby - Comprender el archivo Gemfile.lock
bundler (7)
¿Qué significa el signo de exclamación después del nombre de la gema en el grupo ''DEPENDENCIAS''?
El signo de admiración aparece cuando la gema se instaló utilizando una fuente que no sea " https://rubygems.org ".
Después de ejecutar el comando de bundle install
del bundle install
, 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 las subdirectivas '' remota '' y '' especificaciones ''?
¿Qué significa el signo de exclamación después del nombre de la gema en el grupo '' DEPENDENCIAS ''?
Bundler es un administrador de gemas que proporciona un entorno coherente para los proyectos de Ruby al rastrear e instalar las gemas y versiones exactas que se necesitan.
Gemfile y Gemfile.lock son productos primarios de la gema Bundler (Bundler en sí es una gema).
Gemfile contiene la dependencia de tu proyecto en gem (s), que mencionas manualmente con la (s) versión (es) especificada (s), pero esas gemas (inturn) dependen de otras gemas que resuelve automáticamente bundler.
Gemfile.lock contiene una instantánea completa de todas las gemas en Gemfile junto con la dependencia asociada.
Cuando llame por primera vez a la instalación del paquete , creará este archivo Gemfile.lock y usará este archivo en todas las llamadas posteriores a la instalación del paquete, lo que garantiza que tendrá todas las dependencias instaladas y omitirá la instalación de la dependencia.
Lo mismo sucede cuando comparte su código con diferentes máquinas
Compartes tu Gemfile.lock junto con Gemfile, cuando ejecutas bundle install en otra máquina, se referirá a tu Gemfile.lock y saltará el paso de resolución de dependencia, en su lugar instalará todas las mismas gemas dependientes que usaste en el máquina original, que mantiene la consistencia entre múltiples máquinas
¿Por qué tenemos que mantener la consistencia a lo largo de varias máquinas?
Ejecutar diferentes versiones en diferentes máquinas podría llevar a código roto
Supongamos que su aplicación usó 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 obtienes 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 (preferido
práctica).
También es posible actualizar gem (s) en Gemfile.lock usando bundle update .
Esto se basa en el concepto de actualización conservadora
He pasado los últimos meses jugando con Gemfiles y Gemfile.locks mucho mientras creo una herramienta de actualización de dependencia automatizada 1 . Lo que sigue está lejos de ser definitivo, pero es un buen punto de partida para entender el formato Gemfile.lock. También es posible que desee verificar el código fuente del analizador de archivos de bloqueo de Bundler .
Encontrará los siguientes títulos en un archivo de bloqueo generado por Bundler 1.x:
GEM (opcional pero muy común)
Estas son dependencias de un servidor de 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ás:
-
remote:
una o más líneas que especifican la ubicación del índice (es) de Rubygems -
specs:
una lista de dependencias, con su número de versión y las restricciones en cualquier subdependencias
GIT (opcional)
Estas son dependencias de un control remoto git dado. Verá una de estas secciones diferente para cada control remoto de git, y dentro de cada sección verá:
-
remote:
el control remoto git. Por ejemplo,[email protected]:rails/rails
-
revision:
la referencia de confirmación Gemfile.lock está bloqueado para -
tag:
(opcional) la etiqueta especificada en el Gemfile -
specs:
la dependencia git encontrada en este control remoto, con su número de versión y las restricciones en cualquier subdependencias
RUTA (opcional)
Estas son dependencias que provienen de una path
dada, proporcionada en el Gemfile. Verá una de estas secciones diferente para cada dependencia de ruta, y dentro de cada sección verá:
-
remote:
el camino. Por ejemplo,plugins/vendored-dependency
-
specs:
la dependencia git encontrada en este control remoto, con su número de versión y las restricciones en cualquier subdependencias
PLATAFORMAS
La plataforma Ruby sobre la que se generó Gemfile.lock. Si alguna dependencia en el Gemfile especifica una plataforma, entonces solo se incluirán en Gemfile.lock cuando el archivo de bloqueo se genere en esa plataforma (por ejemplo, mediante 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 al índice Rubygems principal (por ejemplo, dependencias git, basadas en rutas, dependencias) tienen un !
lo que significa que están "anclados" a esa fuente 2 (aunque a veces se debe buscar en el Gemfile para determinarlo).
VERSIÓN RUBY (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 archivo .ruby_version
, esta sección no estará presente (ya que Bundler considerará que Gemfile / Gemfile.lock es independiente de la versión de Ruby del instalador).
CONJUNTO CON (Bundler> = 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.
PLUGIN SOURCE (opcional y muy raro)
En teoría, un Gemfile puede especificar complementos Bundler, así como gemas 3 , que luego se enumerarán aquí. En la práctica, no conozco ningún complemento disponible a partir de julio de 2017. ¡Esta parte de Bundler aún está en desarrollo activo!
Me parece que PATH enumera las dependencias de primera generación directamente de tu gemspec, mientras que GEM enumera las dependencias de segunda generación (es decir, de qué dependen tus dependencias) y las de tu Gemfile. PATH :: remote es .
porque se basó en un gemspec local en el directorio actual para averiguar qué pertenece en PATH :: spec, mientras que GEM :: remote es rubygems.org
, ya que ahí es donde tenía que ir para averiguar qué pertenece a GEM :: spec.
En un complemento Rails, verá una sección PATH, pero no en la aplicación Rails. Como la aplicación no tiene un archivo gemspec, no habría nada que poner en PATH.
En cuanto a DEPENDENCIAS, gembundler.com declara:
Runtime dependencies in your gemspec are treated like base dependencies,
and development dependencies are added by default to the group, :development
El archivo Gemfile generado por el rails plugin new my_plugin
dice 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. Por lo tanto, cuando ejecute bundle install
, verá "julio" no solo en PATH sino también en DEPENDENCIAS, pero solo en desarrollo. En producción, no estará allí en absoluto. Sin embargo, cuando usa (2), verá "julio" solo en RUTA, no en DEPENDENCIAS, pero se mostrará cuando bundle install
desde 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 por qué nada de esto es así, pero agradezco más comentarios.
Parece que no hay documentos claros hablando en el formato Gemfile.lock
. Tal vez sea porque Gemfile.lock
solo se usa por paquete internamente.
Sin embargo, desde Gemfile.lock
es una instantánea de Gemfile
, lo que significa que toda su información debe provenir de 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
. remote
bajo GEM
dice dónde obtener las gemas, que se especifica por source en Gemfile
.
Si no se obtiene una gema del remote
, PATH
le dice a la ubicación que la busque. La información de PATH
proviene de path en Gemfile
cuando declaras una dependencia.
Y PLATFORM
es de here .
Para DEPENDENCIES
, es la instantánea de las dependencias resueltas por paquete.
Puede encontrar más información al respecto en el sitio web de bundler (énfasis agregado a continuación para su conveniencia):
Después de desarrollar su aplicación por un tiempo, verifique la aplicación junto con la instantánea Gemfile y Gemfile.lock . Ahora, tu repositorio tiene un registro de las versiones exactas de todas las gemas que usaste la última vez que sabes con certeza que la aplicación funcionó ...
Esto es importante: el archivo Gemfile.lock hace que su aplicación sea un paquete único de su propio código y el código de terceros que ejecutó la última vez que supo con certeza que todo funcionó. Especificar las versiones exactas del código de terceros del que dependes en tu Gemfile no proporcionaría la misma garantía, ya que las gemas generalmente declaran un rango de versiones para sus dependencias.
en lo que respecta al signo de exclamación, descubrí que se trata de gemas obtenidas a través de :git
, por ejemplo
gem "foo", :git => "[email protected]:company/foo.git"