Introduction à Gradle

1. Vue d’ensemble

Gradle est un système de gestion de build basé sur Groovy conçu spécifiquement pour la construction de projets basés sur Java.

Les instructions d’installation sont disponibles à l’adresse here .

2. Building Blocks - Projets et tâches

  • Dans Gradle, les constructions consistent en un ou plusieurs projets et chaque projet consiste en une ou plusieurs tâches. **

Un projet dans Gradle peut assembler un fichier jar , war ou même un fichier zip .

  • Une tâche est un travail unique. ** Cela peut inclure la compilation de classes ou la création et la publication d’archives Java/Web.

Une tâche simple peut être définie comme:

task hello {
    doLast {
        println 'Baeldung'
    }
}

Si nous exécutons la tâche ci-dessus à l’aide de la commande gradle -q hello à partir du même emplacement où réside build.gradle , nous devrions voir la sortie dans la console.

2.1. Les tâches

Les scripts de compilation de Gradle ne sont que Groovy:

task toLower {
    doLast {
        String someString = 'HELLO FROM BAELDUNG'
        println "Original: "+ someString
        println "Lower case: " + someString.toLowerCase()
    }
}

Nous pouvons définir des tâches qui dépendent d’autres tâches. La dépendance de tâche peut être définie en passant l’argument dependsOn: taskName dans une définition de tâche:

task helloGradle {
    doLast {
        println 'Hello Gradle!'
    }
}

task fromBaeldung(dependsOn: helloGradle) {
    doLast {
        println "I'm from Baeldung"
    }
}

2.2. Ajouter un comportement à une tâche

Nous pouvons définir une tâche et l’améliorer avec un comportement supplémentaire:

task helloBaeldung {
    doLast {
        println 'I will be executed second'
    }
}

helloBaeldung.doFirst {
    println 'I will be executed first'
}

helloBaeldung.doLast {
    println 'I will be executed third'
}

helloBaeldung {
    doLast {
        println 'I will be executed fourth'
    }
}

doFirst et doLast ajoutent des actions en haut et en bas de la liste d’actions, respectivement, et peuvent être définis plusieurs fois dans une même tâche .

2.3. Ajout des propriétés d’une tâche

Nous pouvons également définir des propriétés:

task ourTask {
    ext.theProperty = "theValue"
}

Ici, nous définissons «laValeur» comme le propriété de la tâche notre tâche__

3. Gestion des plugins

Il existe deux types de plugins dans Gradle - script, et binary.

Pour bénéficier d’une fonctionnalité supplémentaire, chaque plugin doit passer par deux phases: resolving et applying.

  • Resolving signifie trouver la version correcte du fichier jar du plug-in et l’ajouter au classpath du projet. **

  • Applying plugins exécute Plugin.apply (T) sur le projet ** .

3.1. Application de plugins de script

Dans le fichier aplugin.gradle, , nous pouvons définir une tâche:

task fromPlugin {
    doLast {
        println "I'm from plugin"
    }
}

Si nous voulons appliquer ce plugin à notre fichier projet build.gradle , il suffit d’ajouter cette ligne à notre build.gradle :

apply from: 'aplugin.gradle'

Maintenant, l’exécution de la commande gradle tasks devrait afficher la tâche fromPlugin dans la liste des tâches.

3.2. Application de plugins binaires à l’aide de plugins DSL

Dans le cas de l’ajout d’un plugin binaire principal, nous pouvons ajouter des noms abrégés ou un identifiant de plugin:

plugins {
    id 'application'
}

Maintenant, la tâche run du plugin application devrait être disponible dans un projet pour exécuter n’importe quel jar runnable . Pour appliquer un plugin de communauté, nous devons mentionner un identifiant de plugin pleinement qualifié:

plugins {
    id "org.shipkit.bintray" version "0.9.116"
}

Maintenant, les tâches Shipkit devraient être disponibles dans la liste gradle tasks .

Les limitations des plugins DSL sont:

  • Il ne prend pas en charge le code Groovy dans le bloc plugins

  • le bloc plugins doit être la déclaration de niveau supérieur dans la construction du projet

scripts (seul le bloc buildscripts \ {} est autorisé avant celui-ci) ** Les plugins DSL ne peuvent pas être écrits dans le plugin de scripts, settings.gradle

fichier ou dans les scripts init

Plugins DSL est toujours en incubation. La configuration DSL et une autre configuration peuvent changer dans les dernières versions de Gradle.

3.3. Ancienne procédure pour appliquer des plugins

Nous pouvons également appliquer des plugins en utilisant le «appliquer le plugin» :

apply plugin: 'war'

Si nous devons ajouter un plug-in de communauté, nous devons ajouter le fichier jar externe au chemin de classe de construction à l’aide du bloc buildscript \ {} .

Ensuite, nous pouvons appliquer le plugin dans les scripts de construction, mais uniquement après tout plugins \ {} block existant:

buildscript {
    repositories {
        maven {
            url "https://plugins.gradle.org/m2/"
        }
    }
    dependencies {
        classpath "org.shipkit:shipkit:0.9.117"
    }
}
apply plugin: "org.shipkit.bintray-release"

4. Gestion de la dépendance

Gradle prend en charge un système de gestion de la dépendance très flexible, compatible avec la grande variété d’approches disponibles.

Les meilleures pratiques pour la gestion des dépendances dans Gradle sont le contrôle de version, le contrôle de version dynamique, la résolution des conflits de version et la gestion des dépendances transitives.

4.1. Configuration de dépendance

Les dépendances sont regroupées dans différentes configurations. Une configuration a un nom et ils peuvent s’étendre .

Si nous appliquons le plug-in Java, nous aurons les configurations compile, testCompile, runtime disponibles pour regrouper nos dépendances. La _default c onfiguration étend « runtime» ._

4.2. Déclaration de dépendances

Voyons un exemple d’ajout de dépendances (Spring et Hibernate) de différentes manières:

dependencies {
    compile group:
      'org.springframework', name: 'spring-core', version: '4.3.5.RELEASE'
    compile 'org.springframework:spring-core:4.3.5.RELEASE',
            'org.springframework:spring-aop:4.3.5.RELEASE'
    compile(
       [group: 'org.springframework', name: 'spring-core', version: '4.3.5.RELEASE'],
       [group: 'org.springframework', name: 'spring-aop', version: '4.3.5.RELEASE']    )
    testCompile('org.hibernate:hibernate-core:5.2.12.Final') {
        transitive = true
    }
    runtime(group: 'org.hibernate', name: 'hibernate-core', version: '5.2.12.Final') {
        transitive = false
    }
}

Nous déclarons des dépendances dans différentes configurations: compile , testCompile et runtime dans divers formats.

Parfois, nous avons besoin de dépendances comportant plusieurs artefacts. Dans de tels cas, nous pouvons ajouter une notation uniquement artefact @ extensionName (ou ext dans le formulaire développé) pour télécharger l’artefact souhaité:

runtime "org.codehaus.groovy:groovy-all:[email protected]"
runtime group: 'org.codehaus.groovy', name: 'groovy-all', version: '2.4.11', ext: 'jar'

Ici, nous avons ajouté la notation @ jar pour ne télécharger que l’artefact jar sans les dépendances.

Pour ajouter des dépendances à des fichiers locaux, nous pouvons utiliser quelque chose comme ceci:

compile files('libs/joda-time-2.2.jar', 'libs/junit-4.12.jar')
compile fileTree(dir: 'libs', include: '** .jar')
  • Lorsque nous voulons éviter les dépendances transitives, nous pouvons le faire au niveau de la configuration ou du niveau de dépendance ** :

configurations {
    testCompile.exclude module: 'junit'
}

testCompile("org.springframework.batch:spring-batch-test:3.0.7.RELEASE"){
    exclude module: 'junit'
}

5. Constructions multi-projets

5.1. Construire le cycle de vie

  • Au cours de la phase d’initialisation, Gradle détermine les projets qui participeront à une construction multi-projets. **

Ceci est généralement mentionné dans le fichier settings.gradle , situé à la racine du projet. Gradle crée également des instances des projets participants.

  • Lors de la phase de configuration, toutes les instances de projets créées sont configurées en fonction de la configuration des fonctionnalités de Gradle à la demande.

Dans cette fonctionnalité, seuls les projets requis sont configurés pour l’exécution d’une tâche spécifique. De cette façon, le temps de configuration est fortement réduit pour une construction multi-projet volumineuse. Cette fonctionnalité est toujours en incubation.

Enfin, dans la phase d’exécution, un sous-ensemble de tâches, créées et configurées, est exécuté. Nous pouvons inclure du code dans les fichiers settings.gradle et build.gradle pour percevoir ces trois phases.

Dans settings.gradle :

println 'At initialization phase.'

Dans build.gradle :

println 'At configuration phase.'

task configured { println 'Also at the configuration phase.' }

task execFirstTest { doLast { println 'During the execution phase.' } }

task execSecondTest {
    doFirst { println 'At first during the execution phase.' }
    doLast { println 'At last during the execution phase.' }
    println 'At configuration phase.'
}

5.2. Création d’une construction multi-projet

Nous pouvons exécuter la commande gradle init dans le dossier racine pour créer un squelette pour les fichiers settings.gradle et build.gradle .

Toutes les configurations courantes seront conservées dans le script de construction racine:

allprojects {
    repositories {
        mavenCentral()
    }
}

subprojects {
    version = '1.0'
}

Le fichier de paramètres doit inclure le nom du projet racine et le nom du sous-projet:

rootProject.name = 'multi-project-builds'
include 'greeting-library','greeter'

Maintenant, nous avons besoin de deux sous-projets nommés greeting-library et greeter pour avoir une démonstration d’une construction multi-projet. Chaque sous-projet doit avoir un script de construction individuel pour configurer ses dépendances individuelles et les autres configurations nécessaires.

Si nous souhaitons que notre projet greeter dépende de greeting-library , nous devons inclure la dépendance dans le script de construction de greeter :

dependencies {
    compile project(':greeting-library')
}

6. Utilisation de Gradle Wrapper

Si un projet Gradle contient le fichier gradlew pour Linux et le fichier gradlew.bat pour Windows, il n’est pas nécessaire d’installer Gradle pour générer le projet.

Si nous exécutons gradlew build sous Windows et ./gradlew build sous Linux, une distribution Gradle spécifiée dans le fichier gradlew sera automatiquement téléchargée.

Si nous souhaitons ajouter le wrapper Gradle à notre projet:

gradle wrapper --gradle-version 4.2.1

La commande doit être exécutée à partir de la racine du projet. Cela créera tous les fichiers et dossiers nécessaires pour lier Gradle wrapper au projet. L’autre façon de faire la même chose est d’ajouter la tâche d’emballage au script de construction:

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

Nous devons maintenant exécuter la tâche wrapper et celle-ci liera notre projet au wrapper. Outre les fichiers gradlew , un dossier wrapper est généré dans le dossier gradle contenant un jar et un fichier de propriétés.

Si nous voulons passer à une nouvelle version de Gradle, il suffit de modifier une entrée dans gradle-wrapper.properties .

7. Conclusion

Dans cet article, nous avons examiné Gradle et constaté qu’il disposait d’une plus grande flexibilité que les autres outils de génération existants en termes de résolution des conflits de versions et de gestion des dépendances transitives.

Le code source de cet article est disponible à l’adresse over sur GitHub .

Suivant "