¿Por qué debería estar el Gradle Wrapper comprometido con VCS?

148

De la documentación de Gradle: https://docs.gradle.org/current/dsl/org.gradle.api.tasks.wrapper.Wrapper.html

Los scripts generados por esta tarea están destinados a comprometerse con su sistema de control de versiones. Esta tarea también genera un pequeño archivo JAR de bootstrap gradle-wrapper.jar y un archivo de propiedades que también debe confirmarse en su VCS. Los scripts delegan a este JAR.

De: ¿Qué NO debe estar bajo control de fuente?

Creo Generated filesque no debería estar en el VCS.

¿Cuándo son gradlewy se gradle/gradle-wrapper.jarnecesitan?

¿Por qué no almacenar un gradle versionen el build.gradlearchivo?

agricultor1992
fuente
1
Lo que podría ser una discusión paralela interesante, dadas las respuestas a continuación, es la utilidad de estos archivos si está utilizando alguna forma de herramienta de integración continua. ¿Cuáles verificarán el envoltorio de grado y lo usarán si está allí?
lilbyrdie 01 de

Respuestas:

124

Porque todo el objetivo del gradle wrapper es poder, sin haber instalado nunca gradle, y sin siquiera saber cómo funciona, dónde descargarlo, qué versión, clonar el proyecto desde el VCS, ejecutar el script gradlew contiene, y para construir el proyecto sin ningún paso adicional.

Si todo lo que tenía era un número de versión de Gradle en un archivo build.gradle, necesitaría un archivo README que explicara a todos que la versión de Gradle X debe descargarse de la URL Y e instalarse, y tendría que hacerlo cada vez que se incremente la versión.

JB Nizet
fuente
94
Eso es estúpido. gradle-wrapper.jar no debería ser necesario en el VCS. Gradle debería poder descargar cualquier versión una vez que haya instalado una primera, si es necesario. La cadena de herramientas no tiene nada que ver con un VCS ... Entiendo que su respuesta es correcta, y es el diseño de Gradle. Pero este diseño es absurdo.
Marc Plano-Lesay
26
El punto es poder descargar gradle sin haber instalado gradle antes. ¿Cuál es el problema de tener un archivo de 50 KB de tamaño en el VCS?
JB Nizet
59
El problema es que no es parte del proyecto. Es una herramienta que usas para construir el proyecto. No almacenarás el JDK en VCS, ¿verdad? ¿Ni GCC para una aplicación C? Entonces, ¿por qué guardarías una parte de Gradle? Si un desarrollador no puede leer e instalar Gradle, ese es otro problema.
Marc Plano-Lesay
26
El problema también es que no puedes recordar, 2 años después de su lanzamiento, qué versión de Gradle se usó para construir la versión v1.0 de tu software, que tienes que reparar para un cliente que todavía está usando este 1.0 versión y no se puede actualizar. El envoltorio de gradle resuelve eso: clonas la etiqueta 1.0 del VCS, la creas usando gradlew y usa la versión de gradle que se usó hace 2 años para construir la versión 1.0.
JB Nizet
33
Estoy de acuerdo en que la versión de Gradle que se utilizará debe indicarse en algún lugar del proyecto. Pero Gradle es una herramienta externa , nada comparable con un README o cualquier cosa que haya enumerado. Gradle debería poder obtener la versión correspondiente, sin tener que almacenar un jar en el VCS.
Marc Plano-Lesay
80

Porque todo el objetivo del envoltorio de gradle es poder, sin haber instalado nunca gradle

El mismo argumento va para el JDK, ¿quieres comprometer eso también? ¿También compromete todas sus bibliotecas dependientes?

Las dependencias deben actualizarse continuamente a medida que se lanzan nuevas versiones. Para obtener seguridad y otras correcciones de errores. Y porque si llegas muy lejos, puede ser una tarea que lleva mucho tiempo volver a ponerte al día.

Si el envoltorio de gradle se incrementa para cada nueva versión, y se confirma, el repositorio crecerá mucho. El problema es obvio cuando se trabaja con VCS distribuido donde un clon descargará todas las versiones de todo.

, y sin siquiera saber cómo funciona

Cree un script de compilación que descargue el contenedor y lo use para compilar. Todos no necesitan saber cómo funciona el script, deben estar de acuerdo en que el proyecto se construye ejecutándolo.

, dónde descargarlo, qué versión

task wrapper(type: Wrapper) {
 gradleVersion = 'X.X' 
}

Y entonces

gradle wrapper

Para descargar la versión correcta.

, clonar el proyecto desde el VCS, ejecutar el script gradlew que contiene y construir el proyecto sin ningún paso adicional.

Resuelto por los pasos anteriores. Descargar el gradle wrapper no es diferente de descargar otras dependencias. El script podría ser inteligente para verificar cualquier envoltura de gradle actual y solo descargarlo si hay una nueva versión.

Si el desarrollador nunca ha usado Gradle antes y tal vez no sabe que el proyecto está construido con Gradle. Entonces es más obvio ejecutar un "build.sh" en comparación con ejecutar "gradlew build".

Si todo lo que tiene es un número de versión de Gradle en un archivo build.gradle, necesitará un archivo README que explique a todos que la versión X de Gradle debe descargarse de la URL Y instalada,

No, no necesitarías un archivo README. Podría tener uno, pero somos desarrolladores y deberíamos automatizar lo más posible. Crear un guión es mejor.

y tendrías que hacerlo cada vez que se incremente la versión.

Si los desarrolladores aceptan que el proceso correcto es:

  1. Repositorio de clones
  2. Ejecutar script de compilación

Luego, actualizar al último gradle wrapper no es un problema. Si la versión se incrementa desde la última ejecución, el script podría descargar la nueva versión.

Tomás Bjerre
fuente
2
"Las dependencias deben actualizarse continuamente". Sí, en una dirección prospectiva. No, en una dirección que mira hacia atrás. Para reproducir una compilación anterior, debe tener versiones específicas de las dependencias. Gradle hace que algunos tipos de proyectos sean más rápidos y fáciles de tratar. Sería un desastre en una organización que necesitara reproducción y auditoría.
lilbyrdie 01 de
3
No estoy seguro de lo que quieres decir. Pero si tiene build.gradlecontrol de versiones y tiene: task wrapper(type: Wrapper) { gradleVersion = 'X.X' } entonces gradle wrapperdescargará el contenedor que se usó y podrá reproducir la versión anterior.
Tomas Bjerre
1
Se refería a su línea sobre las dependencias, no a la versión gradle. Claro, desea que sus bibliotecas tengan todas las últimas correcciones de seguridad y errores, pero NO cuando intenta reproducir una compilación anterior, tal vez con fines de auditoría o legales. Desea que sus bibliotecas y el proceso de compilación puedan producir una salida binaria idéntica, si es posible. Al igual que con una dependencia de biblioteca, no hay garantía de que una versión específica esté disponible en el momento de la construcción ... ya sea dentro de 2 semanas o dentro de 2 décadas. Entonces, sí, es lo mismo que las bibliotecas y los SDK para algunos proyectos.
lilbyrdie
3
Creo que el contenedor está allí principalmente por razones históricas. Al principio, todos usan Maven, y nadie tiene instalado Gradle. Sería difícil persuadir a sus compañeros de trabajo para instalar dependencias intrusivas desconocidas, por lo que el contenedor les ayuda a arrancar. Hoy en día todos tienen Gradle, y el contenedor se vuelve redundante.
Franklin Yu
1
¿Sugiere ejecutar gradle wrapperdespués de clonar en cada compilación? Básicamente, esto hace que el envoltorio sea inútil, porque su objetivo es que no tiene que instalar Gradle localmente para construir el proyecto .
Xerus
41

Me gustaría recomendar un enfoque simple.

En el archivo README de su proyecto, documente que se requiere un paso de instalación, a saber:

gradle wrapper --gradle-version 3.3

Esto funciona con Gradle 2.4 o superior. Esto crea un contenedor sin requerir que se agregue una tarea dedicada a "build.gradle".

Con esta opción, ignore (no registre) estos archivos / carpetas para el control de versiones:

  • ./gradle
  • gradlew
  • gradlew.bat

El beneficio clave es que no tiene que registrar un archivo descargado para controlar la fuente. Cuesta un paso adicional en la instalación. Creo que vale la pena.

David J.
fuente
15
¿por qué necesitarías envoltura entonces? La idea general de wrapper es que puedes construir proyectos sin tener gradle en tu sistema.
edio
44
Buena solución No hay binarios en git y aún así una capacidad de uso gradlew. @edio lo necesitará para descargar y usar una versión específica de gradle.
Kirill
3

¿Qué es el "proyecto"?

Tal vez hay una definición técnica de este idioma que excluye los scripts de compilación. Pero si aceptamos esta definición, ¡entonces debemos decir que su "proyecto" no es todo lo que necesita versionar!

Pero si decimos "su proyecto" es todo lo que ha hecho . Entonces podemos decir que debe incluirlo y solo en VCS.

Esto es muy teórico y quizás no práctico en el caso de nuestros trabajos de desarrollo. Entonces lo cambiamos a " su proyecto es cada archivo (o carpeta) que necesita para editarlos directamente ".

"directamente" significa "no indirectamente" e "indirectamente" significa al editar otro archivo y luego se reflejará un efecto en este archivo .

Entonces llegamos a lo mismo que OP dijo (y se dice aquí ):

Creo que los archivos generados no deberían estar en el VCS.

Si. Porque no los has creado. Por lo tanto, no forman parte de "su proyecto" según la segunda definición.


¿Cuál es el resultado de estos archivos?

  • build.gradle : sí. Necesitamos editarlo. Nuestros trabajos deben ser versionados.

    Nota: No hay diferencia donde lo editas. Ya sea en su entorno de editor de texto o en el entorno de GUI de Project Structure De todos modos lo haces directamente !

  • gradle-wrapper.properties : Sí. Necesitamos al menos determinar la versión de Gradle en este archivo.

  • gradle-wrapper.jar y gradlew [.bat] : ¡No los he creado o editado en ninguno de mis trabajos de desarrollo, hasta este momento! Por tanto, la respuesta es no". Si lo ha hecho, la respuesta es "Sí" sobre usted en ese trabajo (y sobre el mismo archivo que editó).


La nota importante sobre el último caso es el usuario que clona su repositorio, necesita ejecutar este comando en los repositorios<root-directory> para generar automáticamente archivos de envoltura:

> gradle wrapper --gradle-version=$v --distribution-type=$distType

$vy $distTypese determinan a partir de gradle-wrapper.properties :

distributionUrl=https\://services.gradle.org/distributions/gradle-{$v}-{$distType}.zip

Consulte https://gradle.org/install/ para obtener más información.

gradleEl ejecutable está bin/gradle[.bat]en distribución local. No se requiere que la distribución local sea la misma que la determinada en el repositorio. Después de crear los archivos de contenedor , gradlew[.bat]puede descargar automáticamente la distribución de Gradle determinada (si no existe localmente). Entonces, él / ella probablemente debe regenerar los archivos de envoltura usando un nuevo gradleejecutable (en la distribución descargada) usando las instrucciones anteriores.


Nota: En las instrucciones anteriores, se supone que el usuario tiene al menos una distribución de Gradle localmente (por ejemplo ~/.gradle/wrapper/dists/gradle-4.10-bin/bg6py687nqv2mbe6e1hdtk57h/gradle-4.10). Cubre casi todos los casos reales. Pero, ¿qué sucede si el usuario no tiene ninguna distribución ya?

Él / Ella puede descargarlo manualmente usando la URL en el .propertiesarchivo. Pero si él / ella no se localice en el camino que el envoltorio se esperaba, el envoltorio se descargará de nuevo! La ruta esperada es completamente predecible pero está fuera del tema (ver aquí la parte más compleja).

También hay algunas formas más fáciles (pero sucias). Por ejemplo, él / ella puede copiar archivos de contenedor (excepto el .propertiesarchivo) desde cualquier otro repositorio local / remoto a su repositorio y luego ejecutarlo gradlewen su repositorio. Descargará automáticamente la distribución adecuada.

Mir-Ismaili
fuente
1

Según los documentos de Gradle , gradle-wrapper.jarse espera que agregar a VCS ya que Gradle Wrapper esté disponible para los desarrolladores es parte del enfoque de Gradle:

Para que los archivos Wrapper estén disponibles para otros desarrolladores y entornos de ejecución, deberá verificarlos en el control de versiones. Todos los archivos Wrapper, incluido el archivo JAR, son muy pequeños. Se espera agregar el archivo JAR al control de versiones. Algunas organizaciones no permiten que los proyectos envíen archivos binarios al control de versiones. Por el momento no hay opciones alternativas al enfoque.

Arthur Khazbs
fuente
1

Vieja pregunta, nueva respuesta. Si no actualiza Gradle a menudo (la mayoría de nosotros no), es mejor comprometerlo a VCS. Y la razón principal para mí es aumentar la velocidad de compilación en el servidor CI. Hoy en día, la mayoría de los proyectos están siendo construidos e instalados por servidores CI, instancias de servidores diferentes cada vez.

Si no lo confirma, el servidor CI descargará un jar para cada compilación y aumentará significativamente el tiempo de compilación. Hay otras formas de manejar este problema, pero creo que esta es la más fácil de mantener.

smgn
fuente