Warum sollte der Gradle Wrapper an VCS gebunden sein?

147

Aus Gradles Dokumentation: https://docs.gradle.org/current/dsl/org.gradle.api.tasks.wrapper.Wrapper.html

Die von dieser Aufgabe generierten Skripte sollen an Ihr Versionskontrollsystem übergeben werden. Diese Aufgabe generiert auch eine kleine gradle-wrapper.jar-Bootstrap-JAR-Datei und eine Eigenschaftendatei, die auch für Ihr VCS festgeschrieben werden sollen. Die Skripte werden an diese JAR delegiert.

Von: Was sollte NICHT unter Quellcodeverwaltung sein?

Ich denke Generated filessollte nicht im VCS sein.

Wann werden gradlewund gradle/gradle-wrapper.jargebraucht?

Warum nicht ein gradle versionin der build.gradleDatei speichern?

Bauer1992
quelle
1
Was angesichts der folgenden Antworten eine interessante Nebendiskussion sein könnte, ist die Nützlichkeit dieser Dateien, wenn Sie eine Art kontinuierliches Integrationstool verwenden. Welche prüfen auf Grade-Wrapper und verwenden ihn, wenn er vorhanden ist?
Lilbyrdie

Antworten:

124

Denn der springende Punkt des Gradle-Wrappers ist, in der Lage zu sein, ohne jemals Gradle installiert zu haben und ohne zu wissen, wie es funktioniert, von wo es heruntergeladen werden kann, von welcher Version, das Projekt aus dem VCS zu klonen und das Gradlew-Skript auszuführen enthält, und das Projekt ohne zusätzlichen Schritt zu erstellen.

Wenn Sie nur eine Gradle-Versionsnummer in einer build.gradle-Datei hätten, benötigen Sie eine README-Datei, in der allen erklärt wird, dass die Gradle-Version X von der URL Y heruntergeladen und installiert werden muss, und Sie müssten dies jedes Mal tun, wenn die Version erhöht wird.

JB Nizet
quelle
94
Das ist blöd. gradle-wrapper.jar sollte auf dem VCS nicht benötigt werden. Gradle sollte in der Lage sein, jede Version herunterzuladen, sobald Sie eine erste installiert haben, falls erforderlich. Die Toolchain hat mit einem VCS nichts zu tun. Ich verstehe, dass Ihre Antwort richtig ist und dass es sich um Gradles Design handelt. Aber dieses Design ist absurd.
Marc Plano-Lesay
26
Der Punkt ist, Gradle herunterladen zu können, ohne vorher Gradle installiert zu haben . Was ist das Problem bei einer 50 KB großen Datei im VCS?
JB Nizet
59
Das Problem ist, dass es nicht Teil des Projekts ist. Es ist ein Tool, mit dem Sie das Projekt erstellen. Sie werden das JDK nicht in VCS speichern, oder? Noch GCC für eine C-Anwendung? Warum sollten Sie ein Gradle-Teil aufbewahren? Wenn ein Entwickler Gradle nicht selbst lesen und installieren kann, ist dies ein weiteres Problem.
Marc Plano-Lesay
26
Das Problem ist auch, dass Sie sich 2 Jahre nach der Veröffentlichung nicht erinnern können, welche Version von Gradle zum Erstellen der Version 1.0 Ihrer Software verwendet wurde und dass Sie einen Hotfix für einen Kunden durchführen müssen, der diese Version 1.0 noch verwendet Version und kann nicht aktualisiert werden. Der Gradle-Wrapper löst Folgendes: Sie klonen das 1.0-Tag aus dem VCS, erstellen es mit gradlew und verwenden die Gradle-Version, die vor zwei Jahren zum Erstellen der 1.0-Version verwendet wurde.
JB Nizet
32
Ich bin damit einverstanden, dass die zu verwendende Gradle-Version irgendwo im Projekt angegeben werden muss. Aber Gradle ist ein externes Tool, nichts Vergleichbares mit einer README-Datei oder etwas, das Sie aufgelistet haben. Gradle sollte in der Lage sein, die entsprechende Version selbst abzurufen, ohne ein Glas auf dem VCS speichern zu müssen.
Marc Plano-Lesay
80

Denn der springende Punkt des Gradle-Wrappers ist es, in der Lage zu sein, ohne jemals Gradle installiert zu haben

Das gleiche Argument gilt für das JDK. Möchten Sie das auch festlegen? Übernehmen Sie auch alle Ihre Abhängigkeitsbibliotheken?

Die Abhängigkeiten sollten kontinuierlich aktualisiert werden, wenn neue Versionen veröffentlicht werden. Um Sicherheit und andere Fehlerbehebungen zu erhalten. Und wenn Sie zu weit zurückliegen, kann es eine sehr zeitaufwändige Aufgabe sein, wieder auf dem neuesten Stand zu sein.

Wenn der Gradle-Wrapper für jede neue Version erhöht und festgeschrieben wird, wird das Repo sehr groß. Das Problem ist offensichtlich, wenn Sie mit verteiltem VCS arbeiten, bei dem ein Klon alle Versionen von allem herunterlädt.

und ohne zu wissen, wie es funktioniert

Erstellen Sie ein Build-Skript, das den Wrapper herunterlädt und zum Erstellen verwendet. Jeder muss nicht wissen, wie das Skript funktioniert, er muss zustimmen, dass das Projekt durch Ausführen erstellt wird.

, wo kann man es herunterladen, von welcher Version

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

Und dann

gradle wrapper

Um die richtige Version herunterzuladen.

, um das Projekt aus dem VCS zu klonen, das darin enthaltene Gradlew-Skript auszuführen und das Projekt ohne zusätzlichen Schritt zu erstellen.

Gelöst durch die obigen Schritte. Das Herunterladen des Gradle-Wrappers unterscheidet sich nicht vom Herunterladen anderer Abhängigkeiten. Das Skript könnte klug genug sein, um nach einem aktuellen Gradle-Wrapper zu suchen und es nur herunterzuladen, wenn es eine neue Version gibt.

Wenn der Entwickler Gradle noch nie verwendet hat und möglicherweise nicht weiß, dass das Projekt mit Gradle erstellt wurde. Dann ist es offensichtlicher, eine "build.sh" auszuführen, als eine "gradlew build".

Wenn Sie nur eine Gradle-Versionsnummer in einer build.gradle-Datei hätten, benötigen Sie eine README-Datei, in der allen erklärt wird, dass die Gradle-Version X von der URL Y heruntergeladen und installiert werden muss.

Nein, Sie würden keine README-Datei benötigen. Sie könnten eine haben, aber wir sind Entwickler und sollten so viel wie möglich automatisieren. Das Erstellen eines Skripts ist besser.

und Sie müssten es jedes Mal tun, wenn die Version inkrementiert wird.

Wenn die Entwickler zustimmen, dass der richtige Prozess ist:

  1. Repo klonen
  2. Führen Sie das Build-Skript aus

Dann ist ein Upgrade auf den neuesten Gradle Wrapper kein Problem. Wenn die Version seit der letzten Ausführung erhöht wurde, kann das Skript die neue Version herunterladen.

Tomas Bjerre
quelle
2
"Die Abhängigkeiten sollten kontinuierlich aktualisiert werden." Ja, in eine vorausschauende Richtung. Nein, in eine rückwärts gerichtete Richtung. Um einen alten Build zu reproduzieren, benötigen Sie bestimmte Versionen der Abhängigkeiten. Gradle macht einige Arten von Projekten schneller und einfacher zu bearbeiten. Es wäre ein Chaos in einer Organisation, die Reproduktion und Prüfung benötigt.
Lilbyrdie
3
Ich bin mir nicht sicher, was du meinst. Aber wenn Sie build.gradlein der Versionskontrolle haben und darin haben Sie: task wrapper(type: Wrapper) { gradleVersion = 'X.X' } Dann gradle wrapperwird der Wrapper heruntergeladen, der verwendet wurde, und Sie können den alten Build reproduzieren.
Tomas Bjerre
1
Bezog sich auf Ihre Zeile über die Abhängigkeiten, nicht auf die Gradle-Version. Sicher, Sie möchten, dass Ihre Bibliotheken über die neuesten Sicherheits- und Fehlerkorrekturen verfügen, aber NICHT, wenn Sie versuchen, einen alten Build zu reproduzieren, möglicherweise zu Prüfungs- oder rechtlichen Zwecken. Sie möchten, dass Ihre Bibliotheken und Ihr Erstellungsprozess möglichst eine binäre identische Ausgabe erzeugen können. Wie bei einer Bibliotheksabhängigkeit gibt es keine Garantie dafür, dass eine bestimmte Version zum Zeitpunkt der Erstellung verfügbar ist ... sei es in 2 Wochen oder in 2 Jahrzehnten. Ja, für einige Projekte ist es dasselbe wie für Bibliotheken und SDKs.
Lilbyrdie
3
Ich denke, der Wrapper ist hauptsächlich aus historischen Gründen da. Am Anfang benutzt jeder Maven und niemand hat Gradle installiert. Es ist schwierig, Mitarbeiter davon zu überzeugen, unbekannte aufdringliche Abhängigkeiten zu installieren, sodass der Wrapper ihnen beim Bootstrap hilft. Heutzutage hat jeder bereits Gradle und der Wrapper wird überflüssig.
Franklin Yu
1
Schlagen Sie vor, gradle wrapperbei jedem Build nach dem Klonen auszuführen ? Dies macht Wrapper im Grunde genommen unbrauchbar, da der springende Punkt darin besteht, dass Sie Gradle nicht lokal installieren müssen, um das Projekt zu erstellen !
Xerus
41

Ich möchte einen einfachen Ansatz empfehlen.

Dokumentieren Sie in der README Ihres Projekts, dass ein Installationsschritt erforderlich ist, nämlich:

gradle wrapper --gradle-version 3.3

Dies funktioniert mit Gradle 2.4 oder höher. Dadurch wird ein Wrapper erstellt, ohne dass eine dedizierte Aufgabe zu "build.gradle" hinzugefügt werden muss.

Ignorieren Sie mit dieser Option diese Dateien / Ordner zur Versionskontrolle (nicht einchecken):

  • ./gradle
  • gradlew
  • gradlew.bat

Der Hauptvorteil besteht darin, dass Sie keine heruntergeladene Datei zur Quellcodeverwaltung einchecken müssen. Die Installation kostet einen zusätzlichen Schritt. Ich denke es lohnt sich.

David J.
quelle
15
Warum brauchst du dann einen Wrapper? Die ganze Idee von Wrapper ist, dass Sie ein Projekt erstellen können, ohne Gradle auf Ihrem System zu haben.
Edio
4
Schöne Lösung. Keine Binärdateien in Git und trotzdem eine Fähigkeit zu verwenden gradlew. @edio Sie benötigen es, um eine bestimmte Version von gradle herunterzuladen und zu verwenden .
Kirill
3

Was ist das "Projekt"?

Möglicherweise gibt es eine technische Definition dieser Redewendung, die Build-Skripte ausschließt. Aber wenn wir diese Definition akzeptieren, müssen wir sagen, dass Ihr "Projekt" nicht alles ist, was Sie versionieren müssen!

Aber wenn wir sagen "Ihr Projekt" ist alles , was Sie getan haben . Dann können wir sagen, dass Sie es und nur es einschließen müssen in VCS aufnehmen müssen.

Dies ist sehr theoretisch und bei unseren Entwicklungsarbeiten möglicherweise nicht praktikabel. Deshalb ändern wir es in " Ihr Projekt ist jede Datei (oder jeder Ordner), die Sie benötigen, um sie direkt zu bearbeiten ".

"direkt" bedeutet "nicht indirekt" und "indirekt" bedeutet durch Bearbeiten einer anderen Datei, und dann wird ein Effekt in dieser Datei wiedergegeben .

Also haben wir das gleiche erreichen , dass OP sagte (und gesagt wird , hier ):

Ich denke, generierte Dateien sollten nicht im VCS sein.

Ja. Weil du sie nicht erstellt hast . Sie sind also gemäß der zweiten Definition nicht Teil von "Ihrem Projekt".


Was ist das Ergebnis dieser Dateien:

  • build.gradle : Ja. Wir müssen es bearbeiten. Unsere Werke sollten versioniert sein.

    Hinweis: Es gibt keinen Unterschied, wo Sie es bearbeiten. Ob in Ihrer Texteditor-Umgebung oder in der Projektstruktur- GUI-Umgebung. Wie auch immer, du machst es direkt !

  • gradle-wrapper.properties : Ja. Wir müssen mindestens die Gradle-Version in dieser Datei bestimmen.

  • gradle-wrapper.jar und gradlew [.bat] : Ich habe sie bis jetzt in keiner meiner Entwicklungsarbeiten erstellt oder bearbeitet! Die Antwort lautet also "Nein". Wenn Sie dies getan haben, lautet die Antwort "Ja" über Sie bei dieser Arbeit (und über dieselbe Datei, die Sie bearbeitet haben).


Der wichtige Hinweis über den aktuellen Fall ist der Benutzer, Ihre Repo - Klone auf diesen Befehl ausführen muss Repo<root-directory> zu automatisch generieren Wrapper - Dateien:

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

$vund $distTypewerden aus gradle-wrapper.properties bestimmt :

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

Weitere Informationen finden Sie unter https://gradle.org/install/ .

gradleDie ausführbare Datei befindet sich bin/gradle[.bat]in lokaler Verteilung. Es ist nicht erforderlich, dass die lokale Verteilung mit der im Repo festgelegten übereinstimmt. Nachdem Wrapper-Dateien erstellt wurden, gradlew[.bat]kann die bestimmte Gradle-Verteilung automatisch heruntergeladen werden (falls nicht lokal vorhanden). Dann muss er / sie wahrscheinlich Wrapper-Dateien unter Verwendung einer neuen gradleausführbaren Datei (in heruntergeladener Distribution) unter Verwendung der obigen Anweisungen neu generieren.


Hinweis: In den obigen Anweisungen wird davon ausgegangen, dass der Benutzer lokal mindestens eine Gradle-Verteilung hat (z ~/.gradle/wrapper/dists/gradle-4.10-bin/bg6py687nqv2mbe6e1hdtk57h/gradle-4.10. B. ). Es deckt fast alle realen Fälle ab. Aber was passiert, wenn der Benutzer noch keine Distribution hat?

Er / Sie kann es manuell über die URL in der .propertiesDatei herunterladen . Wenn er es jedoch nicht in dem Pfad findet, den der Wrapper erwartet hat, lädt der Wrapper es erneut herunter! Der erwartete Pfad ist vollständig vorhersehbar, liegt jedoch außerhalb des Themas (siehe hier) für den komplexesten Teil).

Es gibt auch einige einfachere (aber schmutzige) Wege. Beispielsweise kann er Wrapper-Dateien (außer .propertiesDateien) von jedem anderen lokalen / Remote-Repository in sein Repository kopieren und dann in seinem Repository ausführen gradlew. Es wird automatisch die passende Distribution heruntergeladen.

Mir-Ismaili
quelle
0

Laut Gradle-Dokumenten wird das Hinzufügen gradle-wrapper.jarzu VCS erwartet, da die Bereitstellung von Gradle Wrapper für Entwickler Teil des Gradle-Ansatzes ist:

Um die Wrapper-Dateien anderen Entwicklern und Ausführungsumgebungen zur Verfügung zu stellen, müssen Sie sie in die Versionskontrolle einchecken. Alle Wrapper-Dateien einschließlich der JAR-Datei sind sehr klein. Das Hinzufügen der JAR-Datei zur Versionskontrolle wird erwartet. Einige Organisationen erlauben Projekten nicht, Binärdateien an die Versionskontrolle zu senden. Derzeit gibt es keine alternativen Optionen für den Ansatz.

Arthur Khazbs
quelle
0

Alte Frage, frische Antwort. Wenn Sie gradle nicht oft aktualisieren (die meisten von uns nicht), ist es besser, es auf VCS zu übertragen. Der Hauptgrund für mich ist, die Build-Geschwindigkeit auf dem CI-Server zu erhöhen. Heutzutage werden die meisten Projekte von CI-Servern erstellt und installiert, die jedes Mal eine andere Serverinstanz haben.

Wenn Sie es nicht festschreiben, lädt der CI-Server für jeden Build ein JAR herunter und verlängert die Build-Zeit erheblich. Es gibt andere Möglichkeiten, um dieses Problem zu lösen, aber ich finde, dass diese am einfachsten zu warten ist.

smgn
quelle