Progetti autonomi: dipendenze Gradle e Maven offline

4

Sto cercando di ottenere un progetto di programmazione Java configurato in modo che possa essere compilato completamente offline solo dai file nel controllo di versione, su qualsiasi macchina, senza prerequisiti da installare. (Eccezione unica: JDK)

Non conosco molto Maven, ma sto attualmente imparando Gradle. Per la build sto utilizzando Gradle con il wrapper, ho modificato gradle-wrapper.properties in modo che distributionUrl non punti a un URL remoto ma a un file all'interno della cartella del progetto. Quindi lo stesso Gradle è già fatto.

Per le dipendenze però, questo è un puro incubo. Ho già provato a gestirlo semplicemente indirizzando direttamente a singoli JAR o raccolte di JAR, ma come sicuramente sai questo finisce in totale confusione se hai interdipendenze e / o dipendenze transitive.

Fondamentalmente quello che voglio è Gradle / Maven configurato (solo per questo progetto) in modo tale che usino una directory diversa per la loro cache delle dipendenze locale - non una che sia condivisa da qualsiasi cosa tu faccia sul tuo account utente, nella tua directory home, ma invece una cartella all'interno della cartella del progetto (così posso verificarla anche nel controllo della versione) che è usata solo per quel progetto. In una sola volta, prendere Gradle / Maven in modalità online, eseguire una volta la build per scaricare tutte le dipendenze attualmente necessarie nella directory della cache locale all'interno della cartella del progetto (il cui contenuto viene quindi inserito in VC), quindi metterlo in modalità offline per tutte le successive build.

Non ho ancora trovato un modo per riconfigurare quel percorso della cache locale solo per questo progetto (deve essere qualcosa che posso semplicemente inserire nel mio build.gradle ). Qualcuno ha un vantaggio per me?

Modifica: Un'altra cosa sarebbe avere questo repository locale all'interno della cartella del progetto come un repository Maven "reale" (anziché solo una cache). Ma ciò implicherebbe il lavoro manuale per un modo che immaginavo: si avvia una copia locale di Sonatype Nexus che ha un repository proxy configurato per tutti i repository Maven a cui si fa riferimento in build.gradle ; si modificano gli URL del repository nel proprio script di build in modo che facciano riferimento al Nexus locale, quindi si esegue una volta il build in modo che Nexus scarichi i deps e li inserisca nella propria directory di lavoro nella "normale" struttura di repository Maven; quindi copi quella struttura in una cartella all'interno della cartella del progetto e modifica gli URL del repository buildscript in modo che facciano riferimento alla cartella in cui hai appena copiato i file. Un sacco di lavoro che può a malapena essere automatizzato.

    
posta Julian 23.09.2016 - 13:57
fonte

1 risposta

1

Bene, quindi ho trovato un modo che funziona per me, ed è automatizzabile.

Ho trovato questo snippet che consente di creare un'attività Gradle che copierà determinate dipendenze del progetto in una cartella arbitraria in Struttura delle directory di Maven. Avevo bisogno di di modificarlo leggermente in modo che non lo faccia solo per una singola configurazione, ma per tutte le configurazioni definite dal progetto.

Il mio script di build ora appare così:

apply plugin: 'java'

repositories {
    maven {
        url './dependencies-maven/'
    }
    mavenCentral()
    jcenter()
    // whatever other external repos your deps come from
}

dependencies {
    // ...
}

task offlineRepo (type:OfflineMavenRepository) {
    repoDir = new File(project.projectDir, 'dependencies-maven')
}

Quindi, si attiva semplicemente l'attività offlineRepo una volta: tutte le dipendenze del progetto corrente verranno scaricate nella cache locale di Gradle e quindi copiate in una sottocartella nella directory del progetto (nella struttura del repository Maven). La prossima volta che eseguirai la build con la directory di progetto in questo stato, il repository locale appena popolato verrà interrogato per primo, e dal momento che contiene (dovrebbe contenere) tutti i deps, niente dovrebbe essere preso dalla cache delle cartelle utente di Gradle né da il web.

A questo punto puoi portare l'intera cartella del progetto su qualsiasi altra macchina con solo Gradle installato e dovrebbe essere in grado di fare la build senza mai andare online per recuperare alcuni dati aggiuntivi.

Ogni volta che si desidera aggiornare alcune dipendenze del progetto o aggiungerne di nuove, è sufficiente eseguire nuovamente il task offlineRepo . Ricorda che questo non cancellerà la vecchia versione della dipendenza che aggiorni, quindi se non vuoi finire con un repository ingombrante, devi fare un po 'di pulizia manuale qui.

Con questo, oltre a mettere offline anche il wrapper Gradle (descritto nella mia domanda originale), ho reso il mio progetto costruibile completamente offline e con prerequisiti minimi: non è richiesta alcuna connessione a Internet, nemmeno un'installazione Gradle richiesta. Solo il JDK.

Nota: quando ho impostato questo in un progetto fittizio completamente vuoto, ho dovuto creare una directory di origine java e alcuni file java di esempio, altrimenti Gradle avrebbe solo scaricato / copiato alcune POM ma non il JAR corrispondenti.

Aggiunta: lo snippet ottimizzato si occuperà solo delle dipendenze del progetto. Ma se si utilizza un plug-in personalizzato, che è una dipendenza da script, lo script mancherà. Dovrai aggiungere altro codice al metodo build() :

for(Configuration configuration : project.buildscript.configurations.findAll())
{
    copyJars(configuration)
    copyPoms(configuration)
}
    
risposta data 28.09.2016 - 19:08
fonte

Leggi altre domande sui tag