Chapitre Premiers pas avec Gradle
Création d'un plugin pour PlantUML
Cet exercice complet reprend l'ensemble des concepts et des fonctionnalités de Gradle de manière progressive.
Introduction
Vous devez construire un plugin Gradle en Groovy qui permette de générer des images à partir d'un répertoire de sources PlantUML.
Si vous ne connaissez pas PlantUML, vous pouvez découvrir ce générateur de diagrammes : PlantUML
Etape 1
Cloner le projet à l'adresse Squelette de plugin
Etape 2
Le projet contient les répertoires suivants :
src/plantuml <=== where the plant UML diagrams are stored
lib/plantuml-1.2022.5.jar
build.gradle <== basic gradle file
Etape 3 : "créer la tache listPML"
Objectif de cette étape : créer une tâche qui liste les ressources PlantUML disponibles dans l'application
- Créer la tâche dans le script
build.gradle
- Extraire la tâche dans une classe Groovy codée dans le script
build.gradle
- Externaliser les variables dans le projet
Etape 4 : créer la tâche "createOutputFolder"
Objectif de cette étape : créer une tâche qui liste les ressources PlantUML disponibles dans l'application
- Créer la tâche dans le script
build.gradle
- Extraire la tâche dans une classe Groovy codée dans le script
build.gradle
- Vérifier que la tâche s'exécute tout le temps même quand le répertoire existe deja
- Utiliser la notion de
@OutputDirectory
Etape 5 : créer la tâche "createOutputFolder"
Objectif de cette étape : créer une tâche qui compile les ressources plantuml
- Créer la tâche dans le script
build.gradle
- Extraire la tâche dans une classe Groovy codée dans le script
build.gradle
- Définir les entrées et les sorties de la tache
Attention les linputs et les outputs doîvent être initialisés
- Implémenter la fonction
Vérifier ce qui se produit quand on exécute deux fois la fonction de génération Vérifier ce qui se produit quand un diagramme est modifié
Etape 6 : créer une tâche de zip des schémas
Objectif de cette étape : créer une tâche qui crée une archive avec les diagrammes.
- Créer la tâche dans le script
build.gradle
- Extraire la tâche dans une classe Groovy codée dans le script
build.gradle
- Ajouter les dépendances a la tache
buildPlantUML
etcreateOutputFolder
Etape 7 : Déplacer le code dans buildSrc/
Nous allons déplacer tout le code dans buildSrc
pour nettoyer le projet et préparer le plugin.
Rappel : le code source doit se trouver dans
buildSrc/main/groovy
Si vous n'avez pas réussi la création de la tâche 6, utilisez ce code :
/**
* Available tasks for the project
*
* <ul>
* <li>createOutputFolder</li> : task to create the output folder
* <li>listPML : list the available plant uml in the </li>
* <li>findOutdatedPML : list the PML that requires an update. </li>
* <li>buildPlantuml : build all the plantUml files</li>
* <li>plantUmlTest : test PlantUml installation</li>*
* <li>plantUmlGui : launch PlantUML Gui</li>*
* </ul>
*/
// build.gradle
plugins {
id("application")
}
class ListPmlTask extends DefaultTask {
@OutputFiles
def getPlantFiles() {
def plantFiles = project.fileTree('src/plantuml')
plantFiles.include "**/*.puml"
plantFiles.builtBy "listPML"
return plantFiles
}
@TaskAction
def listResources() {
println "Liste des ressources PlantUML disponibles :"
getPlantFiles().visit { FileVisitDetails details ->
println details.relativePath
}
}
}
class CreateOutputFolderTask extends DefaultTask {
@OutputDirectory
def outputDir = project.file(project.buildDir.path + '/outputFolder')
@TaskAction
def creationDuRepertoireDeSortie() {
//outputs.dir 'build/outputFolder'
println "Création du répertoire de sortie"
outputDir.mkdirs()
}
}
abstract class PlantUMLCompilationTask extends DefaultTask {
@Input
abstract Property<FileTree> getPlantFiles()
@Input
abstract Property<File> getOutputFolder()
@TaskAction
def generationSchemas() {
println "Compilation des ressources PlantUML"
// Implémenter la logique de compilation ici
// Example: Generate PlantUML diagram from Groovy script
def planTree = plantFiles.get()
planTree.visit { pml ->
def plantUMLJarPath = project.projectDir.absolutePath +"/lib/plantuml-1.2022.5.jar"
def inputPlantUMLFile = pml.file.absolutePath
def outputImageFile = project.file(outputFolder.get().absolutePath + '/' + pml.name +".png")
// Execute PlantUML command
def command = "java -jar $plantUMLJarPath $inputPlantUMLFile -tpng -o $outputImageFile"
println command
def process = command.execute()
process.waitFor()
// Check if the command was successful
if (process.exitValue() == 0) {
println "PlantUML diagram generated successfully at: $outputImageFile"
} else {
println "Error generating PlantUML diagram. Check the PlantUML command and try again."
println "Exit code: ${process.exitValue()}"
}
}
}
}
tasks.register("listPML", ListPmlTask)
tasks.register("createOutputFolder", CreateOutputFolderTask)
tasks.register("compilePlantUML", PlantUMLCompilationTask) {
dependsOn "createOutputFolder", "listPML"
plantFiles = tasks.listPML.plantFiles
outputFolder = tasks.createOutputFolder.outputDir
}
// build.gradle
task zipDiagrams(type: Zip) {
dependsOn 'compilePlantUML', 'createOutputFolder'
from 'build/outputFolder'
archiveFileName = 'diagrams.zip'
destinationDirectory = file('build')
}
tasks.named('build').get().dependsOn zipDiagrams
Etape 8 : Créer le plugin PlantUMLPlugin
En vous basant sur la documentation de Gradle, créez le plugin et déclarez les tâches dedans.
Créez une extension pour stocker la configuration.
Etape 9 : Créer deux sous projets
Créer un sous-projet plantuml
dans le projet actuel et un projet no-plantuml
.
Ce projet plantuml doit contenir les schémas plantuml, l'autre projet ne contient rien.
Lancer la tâche de génération des diagrammes, que se passe t'il au niveau des sous-projets ?
Utilisez l'instruction allprojects
ou subprojects
pour régler le problème.
Etape 10 : Optimisation
La tâche de génération plante quand un sous-projet ne contient pas de sources.
Tentez de résoudre le problème en utilisant onlyIf
.
Améliorer la situation en utilisant une Input correcte et l'annotation :
@SkipWhenEmpty
@InputDirectory
File contentDir
Etape 11 : Intégration
Utiliser la notion de configuration
et de sourcesSet
pour réupérer les répertoires et les schémas à analyser.
Solutions / Aide
Voici un exemple non optimisé qui peut être utilisé comme guide pour la suite des exercises :
/**
* Available tasks for the project
*
* <ul>
* <li>createOutputFolder</li> : task to create the output folder
* <li>listPML : list the available plant uml in the </li>
* <li>findOutdatedPML : list the PML that requires an update. </li>
* <li>buildPlantuml : build all the plantUml files</li>
* <li>plantUmlTest : test PlantUml installation</li>*
* <li>plantUmlGui : launch PlantUML Gui</li>*
* </ul>
*/
// build.gradle
plugins {
id("application")
}
task listPML {
doLast {
println "Liste des ressources PlantUML disponibles :"
fileTree('src/plantuml').visit { FileVisitDetails details ->
println details.relativePath
}
}
}
// build.gradle
task createOutputFolder {
outputs.dir 'build/outputFolder'
doLast {
println "Création du répertoire de sortie"
file('build/outputFolder').mkdirs()
}
}
// build.gradle
task compilePlantUML {
inputs.dir 'src/plantuml'
outputs.dir 'build/outputFolder'
doLast {
println "Compilation des ressources PlantUML"
// Implémenter la logique de compilation ici
}
}
// build.gradle
task zipDiagrams(type: Zip) {
dependsOn 'compilePlantUML', 'createOutputFolder'
from 'build/outputFolder'
archiveFileName = 'diagrams.zip'
destinationDirectory = file('build')
}
tasks.named('build').get().dependsOn zipDiagrams