Perché Gradle Wrapper dovrebbe essere impegnato in VCS?


148

Dalla documentazione di Gradle: https://docs.gradle.org/current/dsl/org.gradle.api.tasks.wrapper.Wrapper.html

Gli script generati da questa attività sono destinati al commit nel sistema di controllo della versione. Questa attività genera anche un piccolo file JAR bootstrap gradle-wrapper.jar e un file delle proprietà che devono essere impegnati anche nel VCS. Gli script delegano a questo JAR.

Da: cosa NON dovrebbe essere sotto il controllo del codice sorgente?

Penso che Generated filesnon dovrebbe essere nel VCS.

Quando sono gradlewe sono gradle/gradle-wrapper.jarnecessari?

Perché non memorizzare un gradle versionnel build.gradlefile?


1
Ciò che potrebbe essere un'interessante discussione laterale, date le risposte di seguito, è l'utilità di questi file se stai usando una forma di strumento di integrazione continua. Quali controlleranno il wrapper di qualità e lo useranno se è lì?
lilbyrdie,

Risposte:


124

Perché il punto principale del gradle wrapper è di essere in grado, senza aver mai installato Gradle e senza nemmeno sapere come funziona, da dove scaricarlo, da quale versione, clonare il progetto dal VCS, eseguire lo script Gradlew contiene e per creare il progetto senza ulteriori passaggi.

Se tutto ciò che avevi era un numero di versione gradle in un file build.gradle, avresti bisogno di un README che spiegasse a tutti che la versione gradle X deve essere scaricata dall'URL Y e installata, e dovresti farlo ogni volta che la versione viene incrementata.


94
Questo è stupido. gradle-wrapper.jar non dovrebbe essere necessario sul VCS. Gradle dovrebbe essere in grado di scaricare qualsiasi versione una volta installata la prima, se necessario. La toolchain non ha nulla a che fare con un VCS ... Capisco che la tua risposta sia giusta, ed è il design di Gradle. Ma questo design è assurdo.
Marc Plano-Lesay,

26
Il punto è poter scaricare il gradle senza averlo installato prima. Qual è il problema nell'avere un file di 50 KB nel VCS?
JB Nizet,

59
Il problema è che non fa parte del progetto. È uno strumento che usi per costruire il progetto. Non memorizzerai il JDK in VCS, vero? Né GCC per un'applicazione C? Quindi perché conservare una parte Gradle? Se uno sviluppatore non è in grado di leggere e installare Gradle da solo, questo è un altro problema.
Marc Plano-Lesay,

26
Il problema è anche che non ricordi, 2 anni dopo che è stato rilasciato, quale versione di Gradle è stata utilizzata per creare la versione v1.0 del tuo software, che devi effettuare l'aggiornamento rapido per un cliente che sta ancora utilizzando questo 1.0 versione e impossibile eseguire l'aggiornamento. Il wrapper gradle risolve questo: clonate il tag 1.0 dal VCS, lo costruite usando gradlew e usa la versione gradle che è stata usata 2 anni fa per costruire la versione 1.0.
JB Nizet,

33
Concordo sul fatto che la versione Gradle da utilizzare debba essere indicata da qualche parte nel progetto. Ma Gradle è uno strumento esterno , niente di paragonabile a un README o qualsiasi cosa tu abbia elencato. Gradle dovrebbe essere in grado di recuperare la versione corrispondente stessa, senza dover memorizzare un vaso sul VCS.
Marc Plano-Lesay,

80

Perché l'intero punto dell'involucro gradle è poterlo fare, senza aver mai installato gradle

Lo stesso argomento vale per il JDK, vuoi impegnarlo anche tu? Impegni anche tutte le tue librerie dependencie?

Le dipendenze devono essere aggiornate continuamente man mano che vengono rilasciate nuove versioni. Per ottenere sicurezza e altre correzioni di bug. E perché se arrivi troppo indietro può essere un compito molto dispendioso in termini di tempo aggiornarsi di nuovo.

Se il wrapper gradle viene incrementato per ogni nuova versione e viene eseguito il commit, il repository diventerà molto grande. Il problema è evidente quando si lavora con VCS distribuito in cui un clone scaricherà tutte le versioni di tutto.

e senza nemmeno sapere come funziona

Crea uno script di build che scarica il wrapper e lo utilizza per creare. Non è necessario che tutti sappiano come funziona lo script, ma devono concordare che il progetto è stato realizzato eseguendolo.

, da dove scaricarlo, da quale versione

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

E poi

gradle wrapper

Per scaricare la versione corretta.

, per clonare il progetto dal VCS, eseguire lo script gradlew in esso contenuto e creare il progetto senza alcun passaggio aggiuntivo.

Risolto dai passaggi precedenti. Il download del wrapper gradle non è diverso dal download di altre dipendenze. Lo script potrebbe essere abbastanza intelligente per verificare la presenza di qualsiasi wrapper Gradle corrente e scaricarlo solo se è disponibile una nuova versione.

Se lo sviluppatore non ha mai usato Gradle prima e forse non sa che il progetto è stato creato con Gradle. Quindi è più ovvio eseguire un "build.sh" rispetto all'esecuzione di "build gradlew".

Se tutto ciò che avevi era un numero di versione gradle in un file build.gradle, avresti bisogno di un README che spiegasse a tutti che la versione gradle X deve essere scaricata dall'URL Y e installata,

No, non avresti bisogno di un file README. Potresti averne uno, ma siamo sviluppatori e dovremmo automatizzare il più possibile. Creare uno script è meglio.

e dovresti farlo ogni volta che la versione viene incrementata.

Se gli sviluppatori concordano sul fatto che il processo corretto è:

  1. Reposare clone
  2. Esegui lo script di compilazione

Quindi l'aggiornamento al wrapper Gradle più recente non è un problema. Se la versione viene incrementata dall'ultima esecuzione, lo script potrebbe scaricare la nuova versione.


2
"Le dipendenze dovrebbero essere aggiornate continuamente." Sì, in una direzione lungimirante. No, in una direzione che guarda indietro. Per riprodurre una vecchia build, è necessario disporre di versioni specifiche delle dipendenze. Gradle rende alcuni tipi di progetti più veloci e facili da gestire. Sarebbe un disastro in un'organizzazione che necessitava di riproduzione e auditing.
lilbyrdie,

3
Non so davvero cosa intendi. Ma se hai il build.gradlecontrollo della versione e in esso hai: task wrapper(type: Wrapper) { gradleVersion = 'X.X' } Quindi gradle wrapperscaricherà il wrapper che è stato utilizzato e puoi riprodurre la vecchia build.
Tomas Bjerre,

1
Mi riferivo alla tua linea sulle dipendenze, non sulla versione gradle. Certo, vuoi che le tue librerie abbiano tutte le ultime correzioni di sicurezza e bug ma NON quando stai provando a riprodurre una vecchia build, forse per scopi di controllo o legali. Volete che le vostre librerie e il processo di compilazione siano in grado di produrre un output binario identico, se possibile. Come per la dipendenza da una biblioteca, non esiste alcuna garanzia che una versione specifica sia disponibile al momento della costruzione ... sia tra 2 settimane o 2 decenni. Quindi sì, è lo stesso delle librerie e degli SDK, per alcuni progetti.
lilbyrdie,

3
Penso che il wrapper sia lì principalmente per motivi storici. All'inizio tutti usano Maven e nessuno ha installato Gradle. Sarebbe difficile convincere il collega a installare dipendenze intrusive sconosciute, quindi il wrapper li aiuta ad avviare il bootstrap. Oggi tutti hanno già Gradle e il wrapper diventa ridondante.
Franklin Yu,

1
Stai suggerendo di eseguire gradle wrapperdopo il clone su ogni build? Questo in pratica rende il wrapper inutile, perché il suo punto è che non è necessario installare Gradle localmente per costruire il progetto !
Xerus,

41

Vorrei raccomandare un approccio semplice.

Nel README del tuo progetto, documenta che è necessaria una fase di installazione, vale a dire:

gradle wrapper --gradle-version 3.3

Funziona con Gradle 2.4 o successivo. Questo crea un wrapper senza la necessità di aggiungere un'attività dedicata a "build.gradle".

Con questa opzione, ignora (non archiviare) questi file / cartelle per il controllo della versione:

  • ./gradle
  • gradlew
  • gradlew.bat

Il vantaggio principale è che non è necessario effettuare il check-in di un file scaricato per il controllo del codice sorgente. Costa un ulteriore passo sull'installazione. Penso ne valga la pena.


15
perché allora avresti bisogno di un wrapper? L'idea generale di wrapper è che puoi costruire progetti senza avere gradle sul tuo sistema.
edio,

4
Bella soluzione. Nessun binario in git e ancora una capacità di usare gradlew. @edio ti servirà per scaricare e utilizzare una versione specifica di Gradle.
Kirill

3

Qual è il "progetto"?

Forse esiste una definizione tecnica di questo linguaggio che esclude gli script di build. Ma se accettiamo questa definizione, allora dobbiamo dire che il tuo "progetto" non è tutto ciò di cui hai bisogno per la versione!

Ma se diciamo "il tuo progetto" è tutto ciò che hai fatto . Quindi possiamo dire che devi includerlo e solo esso in VCS.

Questo è molto teorico e forse non pratico nel caso dei nostri lavori di sviluppo. Quindi lo cambiamo in "il tuo progetto è ogni file (o cartella) che devi modificare direttamente ".

"direttamente" significa "non indirettamente" e "indirettamente" significa modificando un altro file e quindi un effetto si rifletterà in questo file .

Quindi raggiungiamo lo stesso che ha detto OP (e si dice qui ):

Penso che i file generati non dovrebbero essere nel VCS.

Sì. Perché tu non li hai creato. Quindi non fanno parte del "tuo progetto" secondo la seconda definizione.


Qual è il risultato di questi file:

  • build.gradle : Sì. Dobbiamo modificarlo. I nostri lavori dovrebbero essere sottoposti a versione.

    Nota: non vi è alcuna differenza nel punto in cui lo si modifica. Sia nell'ambiente dell'editor di testo che nell'ambiente della GUI di Project Structure . Comunque lo fai direttamente !

  • gradle-wrapper.properties : Sì. Dobbiamo almeno determinare la versione Gradle in questo file.

  • gradle-wrapper.jar e gradlew [.bat] : non li ho creati o modificati in nessuno dei miei lavori di sviluppo, fino ad ora! Quindi la risposta è no". Se lo hai fatto, la risposta è "Sì" su di te in quel lavoro (e sullo stesso file che hai modificato).


La nota importante sull'ultimo caso è l'utente che clona il tuo repository, deve eseguire questo comando sui repository<root-directory> per generare automaticamente i file wrapper:

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

$ve $distTypesono determinati da gradle-wrapper.properties :

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

Vedi https://gradle.org/install/ per maggiori informazioni.

gradlel'eseguibile è bin/gradle[.bat]nella distribuzione locale. Non è necessario che la distribuzione locale sia uguale a quella determinata nel repository. Dopo aver creato i file wrapper, ègradlew[.bat] possibile scaricare automaticamente la determinata distribuzione Gradle (se non esiste localmente). Quindi probabilmente deve rigenerare i file wrapper usando il nuovo gradleeseguibile (nella distribuzione scaricata) usando le istruzioni sopra.


Nota: nelle istruzioni precedenti, si suppone che l'utente abbia almeno una distribuzione Gradle localmente (ad es ~/.gradle/wrapper/dists/gradle-4.10-bin/bg6py687nqv2mbe6e1hdtk57h/gradle-4.10.). Copre quasi tutti i casi reali. Ma cosa succede se l'utente non ha già alcuna distribuzione?

Lui / Lei può scaricarlo manualmente usando l'URL nel .propertiesfile. Ma se lui / lei non localizzarlo nel percorso che l' involucro previsto, l'involucro sarà scaricarlo di nuovo! Il percorso previsto è completamente prevedibile ma è fuori tema (vedi qui per la parte più complessa).

Ci sono anche alcuni modi più semplici (ma sporchi). Ad esempio, può copiare i file wrapper (tranne i .propertiesfile) da qualsiasi altro repository locale / remoto nel proprio repository e quindi eseguirli gradlewsul proprio repository. Scarica automaticamente la distribuzione adatta.


1

Secondo i documenti di Gradle , l'aggiunta gradle-wrapper.jara VCS è prevista in quanto rendere Gradle Wrapper disponibile per gli sviluppatori è parte dell'approccio Gradle:

Per rendere i file Wrapper disponibili per altri sviluppatori e ambienti di esecuzione, è necessario controllarli nel controllo della versione. Tutti i file Wrapper, incluso il file JAR, sono di dimensioni molto ridotte. È prevista l'aggiunta del file JAR al controllo versione. Alcune organizzazioni non consentono ai progetti di inviare file binari al controllo versione. Al momento non ci sono opzioni alternative all'approccio.


1

Vecchia domanda, nuova risposta. Se non aggiorni il gradle spesso (la maggior parte di noi non lo fa), è meglio affidarlo a VCS. E il motivo principale per me è aumentare la velocità di generazione sul server CI. Al giorno d'oggi, la maggior parte dei progetti viene realizzata e installata da server CI, ogni volta istanze server diverse.

Se non lo commetti, il server CI scaricherà un jar per ogni build e aumenterà notevolmente i tempi di compilazione. Esistono altri modi per gestire questo problema, ma trovo questo il più facile da mantenere.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.