Pourquoi le Gradle Wrapper devrait-il être engagé dans VCS?

148

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

Les scripts générés par cette tâche sont destinés à être validés dans votre système de contrôle de version. Cette tâche génère également un petit fichier JAR d'amorçage gradle-wrapper.jar et un fichier de propriétés qui doivent également être validés dans votre VCS. Les scripts délèguent à ce JAR.

De: Que ne devrait PAS être sous le contrôle de la source?

Je pense Generated filesne devrait pas être dans le VCS.

Quand gradlewet quand sont -ils gradle/gradle-wrapper.jarnécessaires?

Pourquoi ne pas stocker un gradle versiondans le build.gradlefichier?

agriculteur1992
la source
1
Ce qui pourrait être une discussion parallèle intéressante, compte tenu des réponses ci-dessous, est l'utilité de ces fichiers si vous utilisez une forme d'outil d'intégration continue. Lesquels vérifieront le wrapper de qualité et l'utiliseront s'il y en a?
lilbyrdie

Réponses:

124

Parce que tout l'intérêt du wrapper gradle est de pouvoir, sans avoir jamais installé gradle, et sans même savoir comment il fonctionne, où le télécharger, quelle version, pour cloner le projet à partir du VCS, d'exécuter le script gradlew il contient et pour générer le projet sans aucune étape supplémentaire.

Si tout ce que vous aviez était un numéro de version gradle dans un fichier build.gradle, vous auriez besoin d'un README expliquant à tout le monde que la version gradle X doit être téléchargée à partir de l'URL Y et installée, et vous devriez le faire à chaque fois que la version est incrémentée.

JB Nizet
la source
94
C'est stupide. gradle-wrapper.jar ne devrait pas être nécessaire sur le VCS. Gradle devrait être en mesure de télécharger n'importe quelle version une fois que vous en avez installé une première, si nécessaire. La chaîne d'outils n'a rien à voir sur un VCS… Je comprends que votre réponse est juste, et c'est la conception de Gradle. Mais cette conception est absurde.
Marc Plano-Lesay
26
Le but est de pouvoir télécharger gradle sans avoir installé gradle auparavant. Quel est le problème d'avoir un fichier de 50 Ko dans le VCS?
JB Nizet
59
Le problème est que cela ne fait pas partie du projet. C'est un outil que vous utilisez pour construire le projet. Vous ne stockerez pas le JDK dans VCS, n'est-ce pas? Ni GCC pour une application C? Alors, pourquoi voudriez-vous stocker une pièce Gradle? Si un développeur est incapable de lire et d'installer Gradle lui-même, c'est un autre problème.
Marc Plano-Lesay
26
Le problème est également que vous ne vous souvenez plus, 2 ans après sa sortie, de la version de Gradle utilisée pour créer la version v1.0 de votre logiciel, que vous devez corriger un correctif pour un client qui utilise toujours cette version 1.0. version et ne peut pas mettre à niveau. L'encapsuleur gradle résout cela: vous clonez la balise 1.0 à partir du VCS, vous la construisez en utilisant gradlew, et il utilise la version gradle qui a été utilisée il y a 2 ans pour construire la version 1.0.
JB Nizet
33
Je conviens que la version Gradle à utiliser doit être indiquée quelque part dans le projet. Mais Gradle est un outil externe , rien de comparable avec un README ou tout ce que vous avez répertorié. Gradle devrait pouvoir récupérer la version correspondante lui-même, sans avoir à stocker un fichier jar sur le VCS.
Marc Plano-Lesay
80

Parce que tout l'intérêt du wrapper gradle est de pouvoir, sans avoir jamais installé gradle

Le même argument vaut pour le JDK, voulez-vous le valider également? Engagez-vous également toutes vos bibliothèques dépendantes?

Les dépendances doivent être mises à niveau en permanence à mesure que de nouvelles versions sont publiées. Pour obtenir des correctifs de sécurité et d'autres bogues. Et parce que si vous arrivez trop loin derrière, il peut être très fastidieux de se mettre à jour.

Si l'encapsuleur gradle est incrémenté à chaque nouvelle version et qu'il est validé, le dépôt deviendra très volumineux. Le problème est évident lorsque vous travaillez avec un VCS distribué où un clone téléchargera toutes les versions de tout.

, et sans même savoir comment ça marche

Créez un script de construction qui télécharge le wrapper et l'utilise pour créer. Tout le monde n'a pas besoin de savoir comment fonctionne le script, ils doivent accepter que le projet est construit en l'exécutant.

, où le télécharger, de quelle version

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

Puis

gradle wrapper

Pour télécharger la bonne version.

, pour cloner le projet à partir du VCS, pour exécuter le script gradlew qu'il contient et pour construire le projet sans aucune étape supplémentaire.

Résolu par les étapes ci-dessus. Le téléchargement du wrapper gradle n'est pas différent du téléchargement d'autres dépendances. Le script pourrait être intelligent pour vérifier tout wrapper de gradle actuel et le télécharger uniquement s'il existe une nouvelle version.

Si le développeur n'a jamais utilisé Gradle auparavant et ne sait peut-être pas que le projet est construit avec Gradle. Ensuite, il est plus évident d'exécuter un "build.sh" par rapport à l'exécution de "gradlew build".

Si tout ce que vous aviez était un numéro de version gradle dans un fichier build.gradle, vous auriez besoin d'un README expliquant à tout le monde que la version gradle X doit être téléchargée à partir de l'URL Y et installée,

Non, vous n’avez pas besoin d’un fichier README. Vous pourriez en avoir un, mais nous sommes des développeurs et nous devons automatiser autant que possible. Créer un script est mieux.

et vous devrez le faire à chaque fois que la version est incrémentée.

Si les développeurs conviennent que le processus correct consiste à:

  1. Cloner le repo
  2. Exécuter le script de construction

Ensuite, la mise à niveau vers le dernier wrapper gradle ne pose aucun problème. Si la version est incrémentée depuis la dernière exécution, le script peut télécharger la nouvelle version.

Tomas Bjerre
la source
2
"Les dépendances doivent être mises à jour en permanence." Oui, dans une direction tournée vers l'avenir. Non, dans une direction rétrospective. Pour reproduire une ancienne version, vous devez disposer de versions spécifiques des dépendances. Gradle rend certains types de projets plus rapides et plus faciles à gérer. Ce serait un gâchis dans une organisation qui avait besoin de reproduction et de vérification.
lilbyrdie
3
Je ne sais pas vraiment ce que tu veux dire. Mais si vous avez build.gradledans le contrôle de version et que vous avez: task wrapper(type: Wrapper) { gradleVersion = 'X.X' } Ensuite gradle wrapper, vous téléchargerez le wrapper qui a été utilisé et vous pourrez reproduire l'ancienne version.
Tomas Bjerre
1
Fait référence à votre ligne sur les dépendances, pas à la version gradle. Bien sûr, vous voulez que vos bibliothèques aient toutes les dernières corrections de bogues et de sécurité, mais PAS lorsque vous essayez de reproduire une ancienne version, peut-être à des fins d'audit ou à des fins juridiques. Vous voulez que vos bibliothèques et processus de construction puissent produire une sortie binaire identique, si possible. Comme avec une dépendance de bibliothèque, il n'y a aucune garantie qu'une version spécifique serait disponible au moment de la construction ... que ce soit dans 2 semaines ou 2 décennies. Alors oui, c'est la même chose que les bibliothèques et les SDK, pour certains projets.
lilbyrdie
3
Je pense que l'emballage est là principalement pour des raisons historiques. Au début, tout le monde utilise Maven, et personne n'a installé Gradle. Il serait difficile de persuader un collègue d'installer des dépendances intrusives inconnues, de sorte que le wrapper les aide à démarrer. De nos jours, tout le monde a déjà Gradle et le wrapper devient redondant.
Franklin Yu
1
Proposez-vous d'exécuter gradle wrapperaprès le clonage sur chaque build? Cela rend fondamentalement le wrapper inutile, car son but est que vous n'avez pas à installer Gradle localement pour construire le projet !
Xerus
41

Je voudrais recommander une approche simple.

Dans le fichier README de votre projet, indiquez qu'une étape d'installation est requise, à savoir:

gradle wrapper --gradle-version 3.3

Cela fonctionne avec Gradle 2.4 ou supérieur. Cela crée un wrapper sans nécessiter l'ajout d'une tâche dédiée à "build.gradle".

Avec cette option, ignorez (ne archivez pas) ces fichiers / dossiers pour le contrôle de version:

  • ./gradle
  • Gradlew
  • gradlew.bat

Le principal avantage est que vous n'avez pas à archiver un fichier téléchargé dans le contrôle de code source. Cela coûte une étape supplémentaire lors de l'installation. Je pense que ça vaut le coup.

David J.
la source
15
pourquoi auriez-vous besoin d'un emballage alors? L'idée générale du wrapper est que vous pouvez créer un projet sans avoir de gradation sur votre système.
edio
4
Belle solution. Pas de binaires dans git et toujours une capacité à utiliser gradlew. @edio vous en aurez besoin pour télécharger et utiliser une version spécifique de gradle.
Kirill
3

Qu'est-ce que le «projet»?

Il existe peut-être une définition technique de cet idiome qui exclut les scripts de construction. Mais si nous acceptons cette définition, alors nous devons dire que votre "projet" n'est pas tout ce dont vous avez besoin pour versionner!

Mais si nous disons "votre projet", c'est tout ce que vous avez fait . Ensuite, nous pouvons dire que vous devez l'inclure et seulement cela dans VCS.

Ceci est très théorique et peut-être pas pratique dans le cas de nos travaux de développement. Nous le changeons donc en " votre projet est tous les fichiers (ou dossiers) dont vous avez besoin pour les éditer directement ".

«directement» signifie «pas indirectement» et «indirectement» signifie en éditant un autre fichier et un effet sera alors reflété dans ce fichier .

Nous arrivons donc à la même chose qu'OP a dit (et est dit ici ):

Je pense que les fichiers générés ne devraient pas être dans le VCS.

Oui. Parce que vous ne les avez pas créés. Ils ne font donc pas partie de "votre projet" selon la deuxième définition.


Quel est le résultat de ces fichiers:

  • build.gradle : Oui. Nous devons le modifier. Nos travaux doivent être versionnés.

    Remarque: il n'y a aucune différence là où vous le modifiez. Que ce soit dans votre environnement d'éditeur de texte ou dans l' environnement GUI de la structure de projet . Quoi qu'il en soit, vous le faites directement !

  • gradle-wrapper.properties : Oui. Nous devons au moins déterminer la version de Gradle dans ce fichier.

  • gradle-wrapper.jar et gradlew [.bat] : Je ne les ai pas créés ou modifiés dans aucun de mes travaux de développement, jusqu'à ce moment! Donc la réponse est non". Si vous l'avez fait, la réponse est "Oui" à propos de vous à ce travail (et du même fichier que vous avez édité).


La note importante concernant le dernier cas est que l'utilisateur qui clone votre dépôt doit exécuter cette commande sur les dépôts<root-directory> pour générer automatiquement des fichiers wrapper:

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

$vet $distTypesont déterminés à partir de gradle-wrapper.properties :

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

Voir https://gradle.org/install/ pour plus d'informations.

gradlel'exécutable est bin/gradle[.bat]en distribution locale. Il n'est pas nécessaire que la distribution locale soit la même que celle déterminée dans le repo. Une fois les fichiers wrapper créés, vous gradlew[.bat]pouvez télécharger automatiquement la distribution Gradle déterminée (si elle n'existe pas localement). Ensuite, il / elle doit probablement régénérer les fichiers wrapper en utilisant le nouvel gradleexécutable (dans la distribution téléchargée) en utilisant les instructions ci-dessus.


Remarque: Dans les instructions ci-dessus, on suppose que l'utilisateur a au moins une distribution Gradle localement (par exemple ~/.gradle/wrapper/dists/gradle-4.10-bin/bg6py687nqv2mbe6e1hdtk57h/gradle-4.10). Il couvre presque tous les cas réels. Mais que se passe-t-il si l'utilisateur n'a déjà aucune distribution?

Il / Elle peut le télécharger manuellement en utilisant l'URL dans le .propertiesfichier. Mais s'il / elle n'a pas le localiser dans le chemin que l' emballage prévu, l' emballage sera le télécharger à nouveau! Le chemin attendu est complètement prévisible mais est hors du sujet (voir ici pour la partie la plus complexe).

Il existe également des moyens plus faciles (mais sales). Par exemple, il / elle peut copier des fichiers wrapper (à l'exception du .propertiesfichier) de n'importe quel autre référentiel local / distant vers son référentiel, puis les exécuter gradlewsur son référentiel. Il téléchargera automatiquement la distribution appropriée.

Mir-Ismaili
la source
1

Selon la documentation de Gradle , l'ajout gradle-wrapper.jarà VCS est attendu car rendre Gradle Wrapper disponible pour les développeurs fait partie de l'approche Gradle:

Pour rendre les fichiers Wrapper disponibles à d'autres développeurs et environnements d'exécution, vous devrez les archiver dans le contrôle de version. Tous les fichiers Wrapper, y compris le fichier JAR, sont de très petite taille. L'ajout du fichier JAR au contrôle de version est attendu. Certaines organisations n'autorisent pas les projets à soumettre des fichiers binaires au contrôle de version. Pour le moment, il n'y a pas d'alternative à l'approche.

Arthur Khazbs
la source
1

Ancienne question, réponse fraîche. Si vous ne mettez pas à jour gradle souvent (la plupart d'entre nous ne le font pas), il est préférable de le valider dans VCS. Et la raison principale pour moi est d'augmenter la vitesse de construction sur le serveur CI. De nos jours, la plupart des projets sont construits et installés par des serveurs CI, une instance de serveur différente à chaque fois.

Si vous ne le validez pas, le serveur CI téléchargera un fichier JAR pour chaque build et cela augmentera considérablement le temps de build. Il existe d'autres moyens de gérer ce problème, mais je trouve que celui-ci est le plus simple à maintenir.

smgn
la source