¿Composer.lock debería comprometerse con el control de versiones?

529

Estoy un poco confundido con el composer.lockutilizado en una aplicación con un repositorio.

Vi a muchas personas decir que no deberíamos .gitignore composer.lockdesde el repositorio.

Si actualizo mis bibliotecas en mi entorno de desarrollo, tendré una nueva composer.lockpero no podré actualizarlas a producción, ¿verdad?

¿No generará conflictos en este archivo?

Pierre de LESPINAY
fuente
1
Ese enlace ahora está muerto @markus
Kyrre

Respuestas:

674

Si actualiza sus bibliotecas, también desea confirmar el archivo de bloqueo. Básicamente establece que su proyecto está bloqueado para esas versiones específicas de las bibliotecas que está utilizando.

Si confirma sus cambios y alguien extrae su código y actualiza las dependencias, el archivo de bloqueo no debe modificarse. Si se modifica, significa que tiene una nueva versión de algo.

Tenerlo en el repositorio le asegura que cada desarrollador está utilizando las mismas versiones.

meza
fuente
55
Ok, pero imagínense que si actualizo las bibliotecas desde el entorno de producción, se sobrescribirá composer.lock, por lo que un próximo tirón de la producción me pedirá que
combine
77
Si se modifica el composer.lock, debe enviar las modificaciones de nuevo al repositorio. Si desea vincular el software a versiones dadas de las bibliotecas, hágalo explícitamente en la configuración. De esa manera la cerradura nunca cambiará. Piense en el archivo de bloqueo como un indicador de un problema de administración de dependencias que debe resolverse de una forma u otra.
meza
361
En producción no debe actualizar sus dependencias, debe ejecutar composer installlo que leerá del archivo de bloqueo y no cambiará nada.
Seldaek
112
"En producción no debes actualizar tus dependencias" debe escribirse en mayúsculas
Joaquín L. Robles
75
@ JoaquínL.Robles EN PRODUCCIÓN ¡NO DEBE ACTUALIZAR SUS DEPENDENCIAS! :)
Елин Й.
201

Para aplicaciones / proyectos : definitivamente sí.

La documentación del compositor establece esto (con énfasis):

Confirme el composer.lock de su aplicación (junto con composer.json) en el control de versiones.

Como dijo @meza: debe confirmar el archivo de bloqueo para que usted y sus colaboradores estén trabajando en el mismo conjunto de versiones y evitar que diga "Pero funcionó en mi computadora". ;-)

Para bibliotecas : probablemente no.

Las notas de la documentación del compositor sobre este asunto:

Nota: Para las bibliotecas no se recomienda necesariamente confirmar el archivo de bloqueo (...)

Y dice aquí :

Para su biblioteca, puede confirmar el archivo composer.lock si lo desea. Esto puede ayudar a su equipo a probar siempre las mismas versiones de dependencia. Sin embargo, este archivo de bloqueo no tendrá ningún efecto en otros proyectos que dependan de él. Solo tiene un efecto en el proyecto principal.

Para las bibliotecas, estoy de acuerdo con la respuesta de @Josh Johnson.

Jeroen Fiege
fuente
¿Por qué tratar los proyectos en el trabajo de manera diferente a las "bibliotecas"?
Josh Johnson
44
Quizás el uso de la palabra "compañeros de trabajo" era confuso aquí, lo cambié a colaboradores. La principal diferencia es "proyecto principal" frente a biblioteca, en la que un proyecto principal consiste en una o más bibliotecas y código para integrarlas. Cuando ejecuta composer desde el proyecto principal, no utiliza el archivo composer.lock de una biblioteca, por lo que instala sus dependencias en la última versión. Creo que esto debería ser similar al probar su biblioteca.
Jeroen Fiege
2
Confirmar el archivo de bloqueo con una biblioteca es probablemente algo bueno: el archivo de bloqueo documenta qué versiones de dependencias se instalaron cuando se ejecutó el conjunto de pruebas. Eso es particularmente importante en un equipo, y especialmente en entornos de integración continua.
mindplay.dk
Pueden surgir conflictos no triviales al reintegrarse en las ramas del tronco 2 que tienen paquetes nuevos instalados a través del compositor. Sucedió en este momento :)
g4b0
2
@tonix, ¡puedo responder esto con algo de autoridad! La razón por la que no comprometo composer.lock para mis bibliotecas es que mi CI crea el maestro todas las noches, pase lo que pase. Garantiza que si alguna de las dependencias de la biblioteca tiene problemas de actualización que tendría un usuario de la biblioteca, el CI falla. Funciona bien!
Theodore R. Smith
86

Después de hacerlo en ambos sentidos para algunos proyectos, mi postura es que composer.lockno debería comprometerse como parte del proyecto.

composer.lockes construir metadatos que no forman parte del proyecto. El estado de las dependencias debe controlarse a través de cómo las está versionando (ya sea manualmente o como parte de su proceso de compilación automatizado) y no de forma arbitraria por el último desarrollador para actualizarlas y confirmar el archivo de bloqueo.

Si le preocupa que sus dependencias cambien entre las actualizaciones del compositor, entonces tiene una falta de confianza en su esquema de versiones. Las versiones (1.0, 1.1, 1.2, etc.) deben ser inmutables y debe evitar los comodines "dev-" y "X. *" fuera del desarrollo inicial de características.

Confirmar el archivo de bloqueo es una regresión para su sistema de gestión de dependencias ya que la versión de dependencia ahora ha vuelto a definirse implícitamente.

Además, su proyecto nunca debería tener que ser reconstruido o tener sus dependencias readquiridas en cada entorno, especialmente productos. Su entregable (tar, zip, phar, un directorio, etc.) debe ser inmutable y promoverse a través de entornos sin cambios.

Josh Johnson
fuente
19
Convenido. Creo que tiene más sentido especificar versiones de dependencia en composer.jsonlas que las versiones requeridas se mencionan más explícitamente. Pero si no configura versiones específicas, es mejor que confirme el composer.lock. Es confuso si las versiones especificadas en composer.jsonson diferentes a las instaladas según a composer.lock. También depende de la aplicación (versión interna o general) y su ciclo de desarrollo. Por supuesto, los documentos del compositor dicen , en negrita, "Confirme el composer.lock de su aplicación (junto con composer.json) en el control de versiones" . Elija sabiamente =)
Quinn Comendant
10
Después de mucho buscar en el alma, he decidido, en este punto, los documentos del compositor están equivocados :) Tengo la regla de que no agrego material generado al VCS; Permito que el proceso de compilación maneje eso.
Josh Johnson
10
¿No es el código creado utilizando sus "pulsaciones de teclas" biomecánicas "material generado"? No estoy seguro de que sea un criterio sólido para basar una política. =)
Quinn Commandado
55
@borfast Sé que llego un poco tarde a la conversación, por lo que es posible que haya visto esto en este momento, pero puede especificar un hash en el composer.json. En la requiresección, puede poner: "repo": "dev-master#2633721877cae79ad461f3ca06f3f77fb4fce02e". Esto 1) irá a la rama, 2) pagará ese hash, 3) si el hash no se encuentra en la rama, sin embargo, revisará el encabezado de la rama especificada (maestro en este caso).
CEPA
55
@CEPA - Eso es extraño. Hubiera esperado que fallara si no se pudiera encontrar el hash. Parece peligroso
Nathan JB
31
  1. No debe actualizar sus dependencias directamente en Producción.
  2. Debe controlar la versión de su archivo composer.lock .
  3. No debe controlar la versión de sus dependencias reales.

1. No debe actualizar sus dependencias directamente en Producción , porque no sabe cómo esto afectará la estabilidad de su código. Podría haber errores introducidos con las nuevas dependencias, podría cambiar la forma en que se comporta el código que afecta a la suya, podría ser incompatible con otras dependencias, etc. Debe hacerlo en un entorno de desarrollo, seguido de un control de calidad adecuado y pruebas de regresión, etc. .

2. Debe controlar la versión de su archivo composer.lock , ya que esto almacena información sobre sus dependencias y sobre las dependencias de sus dependencias que le permitirán replicar el estado actual del código. Esto es importante porque todas sus pruebas y desarrollos se han realizado con un código específico. No preocuparse por la versión real del código que tiene es similar a cargar los cambios de código en su aplicación y no probarlos. Si está actualizando sus versiones de dependencias, esto debería ser un acto voluntario, y debe tener el cuidado necesario para asegurarse de que todo funcione. Perder una o dos horas de tiempo de inactividad volviendo a una versión anterior podría costarle mucho dinero.

Uno de los argumentos que verá acerca de no necesitar el composer.lock es que puede establecer la versión exacta que necesita en su archivo composer.json , y que de esta manera, cada vez que alguien se ejecute composer install, los instalará de la misma manera. código. Esto no es cierto, porque sus dependencias tienen sus propias dependencias, y su configuración puede especificarse en un formato que permita actualizaciones a subversiones, o tal vez incluso versiones completas.

Esto significa que incluso cuando especifique que desea Laravel 4.1.31 en su composer.json , Laravel en su archivo composer.json podría tener sus propias dependencias requeridas como Symfony event-dispatcher: 2. *. Con este tipo de configuración, podría terminar con Laravel 4.1.31 con Symfony event-dispatcher 2.4.1, y alguien más en su equipo podría tener Laravel 4.1.31 con event-dispatcher 2.6.5, todo dependería de cuándo fue la última vez que ejecutó la instalación del compositor.

Entonces, tener su archivo composer.lock en el sistema de versiones almacenará la versión exacta de estas subdependencias, por lo tanto, cuando usted y su compañero de equipo realicen una instalación de compositor (esta es la forma en que instalará sus dependencias en función de un compositor. bloqueo ) ambos obtendrán las mismas versiones.

¿Qué pasa si quieres actualizar? Luego, en su entorno de desarrollo composer update, ejecute:, esto generará un nuevo archivo composer.lock (si hay algo nuevo) y después de probarlo, y la prueba de control de calidad y la prueba de regresión lo prueban y esas cosas. Puede impulsarlo para que todos los demás descarguen el nuevo composer.lock , ya que es seguro actualizarlo.

3. No debe controlar la versión de sus dependencias reales , porque no tiene sentido. Con el composer.lock puede instalar la versión exacta de las dependencias y no necesitaría confirmarlas. ¿Por qué agregaría a su repositorio 10000 archivos de dependencias, cuando se supone que no debe actualizarlos? Si necesita cambiar uno de estos, debe bifurcarlo y hacer sus cambios allí. Y si le preocupa tener que buscar las dependencias reales cada vez que se compila o libera, el compositor tiene diferentes formas de aliviar este problema, caché, archivos zip, etc.

lebobbi
fuente
1
Gracias, creo que esta respuesta explica por qué deberías versionar composer.lock, y si no, cuáles son las consecuencias y si puedes vivir con ellas.
José Lozano Hernández
8

Luego, se compromete composer.jsoncon su proyecto y todos los demás en su equipo pueden ejecutar la instalación del compositor para instalar las dependencias de su proyecto.

El objetivo del archivo de bloqueo es registrar las versiones exactas que se instalan para que puedan reinstalarse. Esto significa que si tiene una especificación de versión de 1. * y su compañero de trabajo ejecuta la actualización de Composer que instala 1.2.4, y luego confirma el archivo composer.lock, cuando instala Composer, también obtendrá 1.2.4, incluso si se ha lanzado 1.3.0. Esto garantiza que todos los que trabajan en el proyecto tengan la misma versión exacta.

Esto significa que si se ha cometido algo desde la última vez que se realizó una instalación del compositor, entonces, sin un archivo de bloqueo, obtendrá un nuevo código de terceros .

Nuevamente, este es un problema si le preocupa que se rompa el código. Y es una de las razones por las que es importante pensar que Composer se centra en el archivo composer.lock.

Fuente: Compositor: se trata del archivo de bloqueo .


Confirme el composer.lock de su aplicación (junto con composer.json) en el control de versiones. Esto es importante porque el comando de instalación comprueba si hay un archivo de bloqueo y, si lo está, descarga las versiones especificadas allí (independientemente de lo que diga composer.json). Esto significa que cualquiera que configure el proyecto descargará exactamente la misma versión de las dependencias. Su servidor de CI, máquinas de producción, otros desarrolladores de su equipo, todo y todos se ejecutan en las mismas dependencias, lo que mitiga el potencial de errores que afectan solo algunas partes de las implementaciones. Incluso si se desarrolla solo, en seis meses al reinstalar el proyecto puede estar seguro de que las dependencias instaladas siguen funcionando incluso si sus dependencias lanzaron muchas versiones nuevas desde entonces.

Fuente: Compositor - Uso básico .

waanders
fuente
1

Si le preocupa la ruptura de su código, debe confirmarlo composer.locken su sistema de control de versiones para asegurarse de que todos los colaboradores de su proyecto estén utilizando la misma versión del código. Sin un archivo de bloqueo, obtendrá un nuevo código de terceros cada vez.

La excepción es cuando utiliza una meta aplicaciones, bibliotecas donde las dependencias deben actualizarse durante la instalación (como la aplicación Zend Framework 2 Skeleton ). Por lo tanto, el objetivo es tomar las últimas dependencias cada vez que desee comenzar a desarrollar.

Fuente: Compositor: se trata del archivo de bloqueo

Ver también: ¿Cuáles son las diferencias entre la actualización del compositor y la instalación del compositor?

kenorb
fuente
1

No hay una respuesta exacta a esto.

En términos generales, el compositor no debería estar haciendo lo que el sistema de compilación debe hacer y no debería poner composer.lock en VCS. El compositor podría tenerlo extrañamente al revés. Los usuarios finales en lugar de los productores no deberían usar archivos de bloqueo. Por lo general, su sistema de compilación mantiene instantáneas, directorios reutilizables, etc., en lugar de un directorio vacío cada vez. La gente que saca una lib del compositor puede querer que esa lib use un bloqueo para que las dependencias con las que se carga la lib se hayan probado.

Por otro lado, eso aumenta significativamente la carga de la administración de versiones, donde seguramente querrá múltiples versiones de cada biblioteca ya que las dependencias estarán estrictamente bloqueadas. Si es probable que cada biblioteca tenga una versión ligeramente diferente, entonces necesita un poco de soporte de versión de biblioteca múltiple y también puede ver rápidamente el tamaño de las dependencias necesarias, de ahí el consejo de mantenerlo en la hoja.

Tomando eso en cuenta, realmente no encuentro que los archivos de bloqueo sean útiles, ya sea bibliotecas o sus propios trabajos. Lo único que uso para mí es en mi plataforma de compilación / prueba que persiste cualquier activo adquirido externamente solo actualizándolos cuando se solicita, proporcionando compilaciones repetibles para probar, compilar e implementar. Si bien eso se puede mantener en VCS, no siempre se mantiene con el árbol de origen, los árboles de compilación estarán en otra parte de la estructura de VCS o serán administrados por otro sistema en otro lugar. Si se almacena en un VCS, es discutible si se debe mantener o no en el mismo repositorio que los árboles de origen porque de lo contrario cada extracción puede generar una gran cantidad de activos de construcción. Me gusta mucho tener todo en un repositorio bien organizado, con la excepción de la producción / credenciales sensibles y la hinchazón.

SVN puede hacerlo mejor que git, ya que no te obliga a adquirir el repositorio completo (aunque sospecho que tampoco es estrictamente necesario para git, pero el soporte para eso es limitado y no se usa comúnmente). Los repositorios de compilación simples generalmente son solo una rama superpuesta en la que fusiona / exporta el árbol de compilación. Algunas personas combinan recursos de ejercicio en su árbol de origen o separan árboles adicionales, externos, de construcción y de origen. Por lo general, tiene dos propósitos: el almacenamiento en caché de compilación y las compilaciones repetibles, pero a veces mantenerlo separado al menos en cierto nivel también permite compilaciones nuevas / en blanco y compilaciones múltiples fácilmente.

Hay una serie de estrategias para esto y ninguna de ellas funciona especialmente bien con la persistencia de la lista de fuentes a menos que mantenga una fuente externa en su árbol de fuentes.

También tienen cosas como hashes en el archivo, ¿cómo se fusionan cuando dos personas actualizan paquetes? Eso solo debería hacerte pensar que tal vez esto está mal interpretado.

Los argumentos que las personas exponen para los archivos de bloqueo son casos en los que han tomado una visión muy específica y restrictiva del problema. ¿Quieres compilaciones repetibles y compilaciones consistentes? Incluya la carpeta del proveedor en VCS. Luego, también acelera la recuperación de activos y no tiene que depender de recursos externos potencialmente rotos durante la compilación. Ninguna de las tuberías de compilación e implementación que creo requieren acceso externo a menos que sea absolutamente necesario. Si tiene que actualizar un recurso externo, es una vez y solo una vez. Lo que el compositor está tratando de lograr tiene sentido para un sistema distribuido, excepto como se mencionó antes, ya que no tiene sentido porque terminaría con un infierno de dependencia de la biblioteca para las actualizaciones de la biblioteca con choques comunes y actualizaciones tan lentas como el paquete de actualización más lento.

Además actualizo ferozmente. Cada vez que desarrollo, actualizo y pruebo todo. Hay una ventana muy muy pequeña para que la versión significativa se filtre. También de manera realista, cuando se mantiene el control de versiones semántico, que tiende a ser para el compositor, no se supone que tenga tantos problemas de compatibilidad o roturas.

En composer.json pones los paquetes que necesitas y sus versiones. Puede bloquear las versiones allí. Sin embargo, esos paquetes también tienen dependencias con versiones dinámicas que no serán bloqueadas por composer.json (aunque no veo por qué no podría ponerlas allí usted mismo si desea que se bloqueen las versiones) para que alguien más ejecute la instalación de Composer obtiene algo diferente sin la cerradura. Es posible que no le importe mucho eso o que le importe, depende. ¿Te debería importar? Probablemente al menos un poco, lo suficiente como para asegurarse de estar al tanto en cualquier situación e impacto potencial, pero puede que tampoco sea un problema si siempre tiene el tiempo para ejecutar DRY primero y arreglar cualquier cosa que se haya actualizado.

El compositor de problemas está tratando de evitar a veces simplemente no está allí y la molestia de tener archivos de bloqueo de compositor puede ser importante. No tienen absolutamente ningún derecho a decirles a los usuarios qué deben o no deben hacer con respecto a los activos de compilación versus fuente (ya sea que se unan o se separen en VCS), ya que eso no es asunto suyo, no son su jefe ni el mío. "Composer dice" no es una autoridad, no son su oficial superior ni le dan a nadie superioridad sobre este tema. Solo usted conoce su situación real y qué es lo mejor para eso. Sin embargo, podrían recomendar un curso de acción predeterminado para los usuarios que no entienden cómo funcionan las cosas, en cuyo caso es posible que desee seguir eso, pero personalmente no creo que ' es un verdadero sustituto para saber cómo funcionan las cosas y poder entrenar adecuadamente sus requisitos. En última instancia, su respuesta a esa pregunta es una mejor suposición. Las personas que hacen compositor no saben dónde debe guardar su compositor. Ni tampoco ellos. Su única responsabilidad es decirle qué es y qué hace. Fuera de eso, debes decidir qué es lo mejor para ti.

Mantener el archivo de bloqueo es problemático para la usabilidad porque el compositor es muy reservado sobre si usa bloqueo o JSON y no siempre es bueno usar ambos juntos. Si ejecuta install, solo usa el archivo de bloqueo, aparecerá así que si agrega algo a composer.json, entonces no se instalará porque no está en su bloqueo. No es intuitivo en absoluto lo que las operaciones realmente hacen y lo que están haciendo con respecto al archivo json / lock y, a veces, parece no tener sentido (la ayuda dice que la instalación toma un nombre de paquete, pero al intentar usarlo dice que no )

Para actualizar el bloqueo o básicamente aplicar cambios desde el json, debe usar la actualización y es posible que no desee actualizar todo. El bloqueo tiene prioridad para elegir lo que se debe instalar. Si hay un archivo de bloqueo, es lo que se usa. Puede restringir un poco la actualización, pero el sistema sigue siendo un desastre.

La actualización lleva una edad, conciertos de RAM. Sospecho también que si escoges un proyecto que no ha sido tocado por un tiempo y que parecía de las versiones que tenía, que habrá más con el tiempo y probablemente no lo haga de manera eficiente, lo que simplemente lo estrangula.

Son muy muy astutos cuando se trata de tener comandos compuestos secretos que no podrías esperar que sean compuestos. De forma predeterminada, el comando de eliminación de compositor aparece en los mapas para la actualización de compositor y la eliminación de compositor, por ejemplo.

La pregunta que realmente debe hacerse no es si debe mantener el bloqueo en su árbol de origen o, alternativamente, si debe persistir en algún lugar de alguna manera o no, sino que debe preguntarse qué hace realmente, luego puede decidir por sí mismo cuando necesitas persistir y dónde.

Señalaré que tener la capacidad de tener el bloqueo es una gran conveniencia cuando tienes una estrategia sólida de persistencia de dependencia externa, ya que te rastrea la información útil para rastrear eso (los orígenes) y actualizarlo, pero si no lo haces entonces no está ni aquí ni allá. No es útil cuando se te obliga a bajar por la garganta como una opción obligatoria para que contamine tus árboles de origen. Es algo muy común encontrar en las bases de códigos heredadas donde las personas han realizado muchos cambios en composer.json que realmente no se han aplicado y se rompen cuando las personas intentan usar composer. Sin composer.lock, sin problema de desincronización.

jgmjgm
fuente
0

Si obviamente.

Esto se debe a que un compositor instalado localmente dará preferencia al archivo composer.lock sobre composer.json.

Si el archivo de bloqueo no está disponible en vcs, el compositor apuntará al archivo composer.json para instalar las últimas dependencias o versiones.

El archivo composer.lock mantiene la dependencia con mayor profundidad, es decir, apunta a la confirmación real de la versión del paquete que incluimos en nuestro software, por lo tanto, este es uno de los archivos más importantes que maneja la dependencia con mayor precisión.

Dinesh Suthar
fuente