Gradle est un système de build innovant dont les fonctionnalités ne cessent de croître. Ce billet présente en exclusivité la fonctionnalité d’import d’un script Ant depuis un script Gradle. Cette fonctionnalité n'est disponible pour le moment que dans la branche développement du SCM de Gradle.
Nous savons déjà que Gradle permet la réutilisation de toute tâche Ant grâce à son DSL Groovy et à l’objet Groovy AntBuilder.
Par exemple, nous pouvons écrire
task viewProperties <<{ ant.echoproperties(destfile:'dump-properties.txt', format:'text') }
Mais, désormais Gradle supporte nativement un script Ant existant en pouvant l’importer. Chaque cible Ant est convertie en tâche Gradle.
Prenons le script Ant "build.xml" suivant, avec son fichier de propriétés "project.properties"
<project name="proj-ex1"> <property file="project.properties"/> <path id="compile.classpath"> <fileset dir="${lib.dir}"> <include name="**/*.jar"/> </fileset> </path> <target name="clean"> <delete dir="${dist.dir}"/> <delete dir="${distrib.dir}"/> </target> <target name="init" depends="clean"> <mkdir dir="${dist.dir}"/> <mkdir dir="${distrib.dir}"/> </target> <target name="compile" depends="init"> <javac srcdir="${src.dir}" destdir="${dist.dir}"> <classpath refid="compile.classpath"/> </javac> </target> </project>
Ce script définit la chaîne de build "clean->init->compile".
name=example1
lib.dir=lib
src.dir=src/main/java
dist.dir=build
distrib.dir=distrib
destfile=${dist.dir}/${name}.jar
Déclaration et utilisation
Un nouveau plugin Gradle permet d’importer un script Ant existant afin d’accéder à toutes les cibles Ant par des tâches Gradle, de surcharger des cibles Ant et d'hériter de cibles Ant existantes.
usePlugin 'ant' importAntBuild 'build.xml'
Le lancement de la commande suivante
gradle compile
va compiler le projet en lançant les tâches de nettoyage, d’initilisation et de compilation correspondant à la chaîne de cibles "clean->init->compile".
Surcharge
Il est également possible de surcharger le comportement d’une cible Ant
compile <<{ println "Compiling the source code" }
Nous surchargons la tâche "compile".
Heritage
Il est aussi possible de créer une nouvelle tâche Gradle héirtant d’une cible Ant
task jar (dependsOn: 'compile')<<{ ant.jar(destfile:project.ant.destfile, basedir:project.ant."dist.dir") }
Nous définissions ici une tâche Gradle "jar" qui package l'application. Cette tâche s'exécute après la tâche de compilation, définit en réalité par notre cible Ant "compile" existante.
De Ant vers Gradle
Et inversement, il est possible depuis une cible Ant, de dépendre d’une tâche Gradle
<target name="dist" depends="jar, sources"> <copy file="${destfile}" todir="${distrib.dir}"/> </target>
Notre cible Ant "dist" dépend des cibles "jar" et "sources" qui seront fournies sous forme de tâches Gradle.
Le code de la tâche Gradle "sources" est le suivant
task sources(type:Zip) { destinationDir= new File('C:/dev/gradle/ant/build') zipFileSet(dir:'src'){ include('**/*.*') } baseName='titi' }
gradle dist
va lancer la chaîne de build "clean->init->compile->jar->sources->dist".
Finalisation
Attention: dans ce cas, notre script Ant n’est plus autonome car dépendant de Gradle. Nous ne pouvons plus l'exécuter car les cibles "jar" et "sources" n'existent pas. En effet, la validité du graphe de cibles Ant est un pré-requis pour toute exécution de cibles Ant.
Il est ainsi plus judicieux de définir les cibles Ant "jar" et "sources" de type "hook" afin d’avoir un graphe de cibles Ant valide
<target name="jar" depends="compile"/> <target name="sources"/> <target name="dist" depends="jar, sources"> <copy file="${destfile}" todir="${distrib.dir}"/> </target>
Désormais, notre script Gradle ne va pas définir les tâches "jar" et "sources" car elles existent, mais notre script va les surcharger.
jar << { ant.jar(destfile:project.ant.destfile, basedir:project.ant."dist.dir") } task myZipTask(type:Zip) { destinationDir= new File('C:/dev/gradle/ant/build') zipFileSet(dir:'src'){ include('**/*.*') } baseName='titi' } sources << { myZipTask.execute() }
Conclusion
Vous trouverez plus d'informations sur la page officielle.
Avec cette nouvelle fonctionnalité, nous voyons de nouveau un cas d'utilisation de Gradle comme système de build complémentaire dans une infrastructure Ant existante. Et c’est vraiment sans aucun doute que l’adoption de Gradle sera croissante dans les mois et les années à venir.
Cliquez sur ce lien pour une version anglaise de ce billet [en].


Commentaires
Peut-on utiliser un fichier .properties avec gradle comme avec Ant?
Si oui comment?
Merci de votre réponse.
Si les propriétés sont dans un fichier nommé "gradle.properties", nous pouvons y accéder comme ceci
task test << {
println prop1
println project."prop1.ext"
println property("prop1.ext")
}
avec le contenu suivant du fichier gradle.properties
prop1=val1
prop1.ext=val2
Si le fichier de propriétés ne se nomme pas "gradle.properties", il est nécessaire de rajouter une tache d'initialisation chargeant toutes les propriétés.
task init {
Properties props = new Properties()
file('myproperties.properties').withInputStream {
props.load(it)
}
props.each { String name, value -> project.setProperty(name, value) }
}