1Lyon JUG - Présentation Gradle
GRADLE
Gregory BOISSINOT
23/11/2010
2Lyon JUG - Présentation Gradle
• Consultant et formateur Zenika
– Mes spécialités: le build et l'intégration continue
– Responsable technique de la solution d'intégration continue
chez Thales
• Introduction et déploiement de Gradle à grande échelle
• Commiter Hudson
– Intégration des châines de build Java (Gradle), C/C++, ADA
3Lyon JUG - Présentation Gradle
INTERNET
4Lyon JUG - Présentation Gradle
• Transformation d'une production humaine (le code
source) en une représentation machine (le binaire)
Fichier
Source
JAR
JVM
println "Hello World"
for (int i:[1,2,3]){
print i
}
A;^A^@^Am^A^@^T()Ljava/lang/Object;^C^
@^@^@^@^A^@^KHello World^H^@2^A^@-
org/codehaus/groovy/runtime/callsite/
CallSite^G^@4^A^@^KcallCurrent^A^@@
(Lgroovy/lang/GroovyObject;
Ljava/lang/Object;)Ljava/lang/Object;
^L^@6^@7^K^@5^@8^C^@^@^@^A^L^@^H^
....
Fichier
Binaire
5Lyon JUG - Présentation Gradle
• Les besoins d'automatisation ont augmentés
significativement ces dernières années
• La nature des besoins d'automatisation a changé
Un build peut faire beaucoup plus de choses que la
simple création d'une archive Java
6Lyon JUG - Présentation Gradle
1ère génération
2008
2001
2
1
3
2ème génération 3ème génération
2000 2005 2008
7Lyon JUG - Présentation Gradle
<!–- ANT -- build.xml -->
<project>
<target name="retrieceDeps>
...
</target>
<target name="compile" ...
</project>
<!–- GRADLE– build.gradle -->
apply plugin:'java'
version=1.0
repositories {
mavenCental()
flatDir(dirs:'lib')
}
dependencies {
compile(
group:'org.apache.wicket',
name:'wicket',
version:'1.4.7')
}
<!–- MAVEN – pom.xml-->
<?xml version="1.0" encoding="UTF-8"?>
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>org.lyonjug</groupId>
<artifactId>maven</artifactId>
<version>1.0</version>
<dependencies>
<dependency>
<groupId>org.apache.wicket</groupId>
<artifactId>wicket</artifactId>
<version>1.4.7</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>
8Lyon JUG - Présentation Gradle
• Système de build complet focalisé sur le build des
applications d'entreprise Java, Web, Groovy, Scala et
OSGI
• Modèle de description du build très riche à travers une
API et une DSL Groovy
• Flexible à la Ant avec les conventions de Maven à la
demande
• Support et insertion totale dans des infrastructures Maven
et Ant/Ivy existantes
9Lyon JUG - Présentation Gradle
• Spécification du 'quoi' et pas du 'comment'
Même
convention
que Maven
apply plugin:'java'
repositories {
mavenCental()
}
dependencies {
compile
"jdom:jdom:1.1"
testCompile
"junit:junit:4.8"
}
myLib
.jar
src
main
java
test
java
> gradle clean build
:clean
:compileJava
:processResources
:classes
:jar
:assemble
:compileTestJava
:processTestResources
:testClasses
:test
:check
:build
BUILD SUCCESSFUL resources
resources
10Lyon JUG - Présentation Gradle
On ne peut pas anticiper tous les besoins
Il est nécessaire de fournir le même niveau de support entre les
anciens projets et les nouveaux projets
11Lyon JUG - Présentation Gradle
Project
repositories
dependencies
task
configurations
artifacts
API
ant
Écrire un script Gradle consiste à configurer un objet Project
build.gradle
Eléments
personnalisés
12Lyon JUG - Présentation Gradle
• Conçu pour répondre à tous les scénarios possibles
– Plusieurs répertoires de sources par projet
– Une version de JDK par répertoire
– Plusieurs artefacts par projet
– ....
• De nombreux points d'extension pour enrichir les
éléments existant
• La possibilité de fournir ses propres éléments qui vont
former un modèle de build
13Lyon JUG - Présentation Gradle
<!-- build.gradle -->
task(boucleTask).doFirst{
for (int i:[1,2,3]){ print i }
}
void printMessage(String message){
println "Print " + message
}
task(distribution).doFirst {
printMessage("Distribution")
}
task(release)
release.dependsOn(distribution)
release.doFirst{
println "Print Release"
}
> gradle boucleTask
:boucleTask
123
> gradle distribution
:distribution
Print Distribution
> gradle release
:distribution
Print Distribution
:release
Print Release
Possibilité d'écrire du code Java/Groovy sous forme d'unités réutilisables
14Lyon JUG - Présentation Gradle
task mycopy (type:Copy){
description ='Copies the resources dir'
from(file('resources'))
into(file('target'))
include('**/*.txt', '**/*.xml')
}
AbstractCopyTask
AbstractArchiveTask
Zip
Jar
War
Tar
SourceTask
Javadoc
ConventionTask
Copy
public class Copy extends AbstractCopyTask {
public AbstractCopyTask from(Object... sourcePaths);
public AbstractCopyTask into(Object destDir);
public AbstractCopyTask include(String... includes);
. . .
}
15Lyon JUG - Présentation Gradle
<!– HelloTask.groovy -->
class HelloTask extends DefaultTask {
def message="Default Message"
@TaskAction
public void print(){
println message
}
}
> gradle myhello
:myhello
Default Message
> gradle myhello2
:myhello2
Task Message<!-- build.gradle -->
task(myhello, type:HelloTask)
task(myhello2, type:HelloTask){
message="Task Message"
}
16Lyon JUG - Présentation Gradle
• Les plugins Gradle
• Insertion dans un environnement agile
17Lyon JUG - Présentation Gradle
java
war
maven
osgi
code-quality
jetty
scala
eclipse idea
projects-reports
Java Configuration
Object
War Configuration
Object
Jetty Configuration
Object
…
Plugins
Project
Configuration
…
…
Chaque plugin
- est un ensemble de tâches
- expose un objet Java convention
18Lyon JUG - Présentation Gradle
> gradle config
...
<!– build.gradle -->
task config {
...
}
<!– build.gradle -->
apply from "http://repomanager/config-1.0.gradle"
...
config-1.0.gradle
Mise à
disposition
Utilisation
19Lyon JUG - Présentation Gradle
20Lyon JUG - Présentation Gradle
• Flexibilité dans la définition des dépôts
• Possibilité de mettre en place des exclusions globales
• Possibilité de définir les dépendances transitives dans le
script Gradle
repositories{
mavenCentral()
mavenRepo urls: "http://download.java.net/maven/2/"
flatDir name: 'localRepository', dirs: 'lib'
}
dependencies {
runtime module("org.codehaus.groovy:groovy-all:1.7.5") {
dependency("commons-cli:commons-cli:1.0") {
transitive = false
}
}
}
21Lyon JUG - Présentation Gradle
apply plugin:'java'
processResources.enabled=false
test.onlyIf{
!project.hasProperty('skipTests')}
//Add behavior in the lifecycle
task(preJar)
jar.dependsOn preJar
//Change the output directory
buildDirName='target'
//Change the source directory
sourceSets{
main{
java.srcDirs file('src/java'),
file('src/java2')
}
}
> gradle build –PskipTests
:compileJava
:processResources SKIPPED
:classes
:preJar
:jar
:war
:assemble
:compileTestJava
:processTestResources
:testClasses
:test SKIPPED
:check
:build
BUILD SUCCESSFUL
22Lyon JUG - Présentation Gradle
apply plugin:'java'
sourceSets{
myGenSourceSet {
java {
srcDir 'build/generated'
}
}
}
> gradle clean build
:clean
:generateTask
. . .
:compileMyGenSourceSetJava
:processMyGenSourceSetResources
:myGenSourceSetClasses
. . .
23Lyon JUG - Présentation Gradle
sourceSets{
myGenSourceSet {
java {
srcDir 'build/generated'
}
main {
compileClasspath =
configurations.compile
+sourceSets.myGenSourceSet.classes
runtimeClasspath =
classes
+ configurations.runtime
+ sourceSets.myGenSourceSet.classes
}
}
jar {
from sourceSets.myGenSourceSet.classes
}
> gradle clean build
:clean
:generateTask
:compileMyGenSourceSetJava
:processMyGenSourceSetResources
:myGenSourceSetClasses
:compileJava
:processResources
:classes
. . .
24Lyon JUG - Présentation Gradle
version = 1.0
gradle.taskGraph.whenReady { taskGraph ->
if (! taskGraph.hasTask(':release')){
version+='-SNAPSHOT' }
}
GRADLE
SCRIPT
Engine
CONFIGURATIONPHASE
t1 t2
t4
Project
Convention 1
HOOK
t3 t1 t2
t4
Project
Convention 2
t3
EXECUTIONPHASE
gradle –-properties
gradle –-tasks
gradle –-dependencies
gradle –-dry-run build
// Other hooks
gradle.taskGraph.beforeTask { task -> .. .
gradle.beforeProject { project -> .. .
...
25Lyon JUG - Présentation Gradle
Soyez informé des événements: TestListener,
BuildListener, TaskActionListener, …
class MyTestListener implements TestListener{
void beforeTest(TestDescriptor test) {
println 'testStarting: '+test.getName()
}
void afterTest(TestDescriptor test,
TestResult result) {
println 'testFinished: '+test.getName()
+', result: '+result.getResultType()
}
}
Test
(junit)
GRADLE
beforeTest
afterTest
26Lyon JUG - Présentation Gradle
import org.junit.Assert
task myzip (type:Zip) {
from 'somedir'
include '*.txt'
baseName='zipname'
doLast {
Assert.assertEquals('zipname.zip',
myzip.archiveName)
Assert.assertEquals(file('build/distributions'),
myzip.destinationDir)
Assert.assertTrue(
!zipTree(myzip.archivePath).isEmpty())
txtfiles = fileTree('somedir').include('*.txt')
ziptxtfiles=zipTree(myzip.archivePath).matching{
include('*.txt')
}
Assert.assertEquals (
txtfiles.getFiles().size(),
ziptxtfiles.getFiles().size())
}
}
zipname
.zip
createZip
check
> gradle myzip
:myzip
BUILD SUCCESSFUL
>
27Lyon JUG - Présentation Gradle
28Lyon JUG - Présentation Gradle
task generateTask(dependsOn:preSchemaGen) << {
ant.echo (message:"Generating ...")
ant {
def schemagenTaskPath = path {
fileset(dirs:'lib', includes: '*.jar')
}
taskdef (
name: "xjc", classname: "com.sun.tools.xjc.XJCTask",
classpath: schemagenTaskPath
)
xjc(destdir:generatedSources,
package:"com.zenika.lib.model"){
schema(dir:"src/main/resources", includes:"**/*.xsd")
}
}
}
29Lyon JUG - Présentation Gradle
build.gradle
build.xml
ant.importBuild('build.xml')
antTask.doLast {
println('Hello from Gradle')
}
<project>
<target name="antTask">
<echo message="Hello from Ant"/>
</target>
</project>
> gradle antTask
:antTask
Hello from Ant
Hello from Gradle
30Lyon JUG - Présentation Gradle
IVY
Repository
Ivy
distant Artifacts +
meta Ivy
apply plugin:'java'
repositories {
mavenCental()
flatDir(dirs:'destrepo',
name:'ivyrep’)
}
group='test'
version='1.0'
status='release'
uploadArchives {
repositories {
add(repositories.ivyrep)
}
}
> gradle uploadArchives
31Lyon JUG - Présentation Gradle
Repository
Maven
distant Artifacts +
meta Maven
Maven
Ant
Tasks
Repository
Maven
Local Artifacts +
meta Maven
apply plugin:'java'
apply plugin:'maven'
group='test'
version='1.0-SNAPSHOT'
uploadArchives {
repositories {
mavenDeployer {
repository(
url: remoteRepo)
}
}
}
> gradle
uploadArchives
> gradle
install
32Lyon JUG - Présentation Gradle
• Gestion avancée d'un multi projet
• Utilisation d'un cache
• Exécution parallèle des tests
• Build daemon
33Lyon JUG - Présentation Gradle
// settings.gradle
include 'api',
'shared',
'services:webservices'
// root build.gradle
subprojects {
apply plugin: 'java'
}
project(':api') {
dependencies {
compile project(':shared')
}
}
// webservices/build.gradle
apply plugin:'war'
dependencies {
compile
project(':shared'),
project(':api'),
'commons-io:commons-io:1.2'
}
shared
webservices api
api > gradle buildNeeded
:shared:jar
:api:jar
:api:test
:shared:test
api > gradle buildDependents
:shared:jar
:api:jar
:api:test
:webservices:war
:webservices:test
api > gradle jar –-no-rebuild
api:jar
34Lyon JUG - Présentation Gradle
1.  Le script Gradle est compilé uniquement en cas de
changement
2.  Détéction des changements pour chaque entrée et
chaque sortie pour la plupart des tâches fournies
> gradle myzip
:myzip
> gradle myzip
:myzip UP-TO-DATE
> gradle myzip –-cache rebuild
:myzip
35Lyon JUG - Présentation Gradle
class GenerateSchemaType extends DefaultTask {
String depsPath
@InputFiles
SourceDirectorySet inputXsdDirs
@OutputDirectory
File outputFile
@TaskAction
void generate() {
ant { ...}
}
}
task generateTask(type:GenerateSchemaType) {
inputXsdDirs = sourceSets.main.resources
outputFile = generatedSources
depsPath = configurations.jaxb.asPath
}
> gradle build
:generateTask UP-TO-DATE
:compileGeneratedJava UP-TO-DATE
:processGeneratedResources UP-TO-DATE
:generatedClasses UP-TO-DATE
:compileJava UP-TO-DATE
...
36Lyon JUG - Présentation Gradle
apply plugin:'java'
test {
forkEvery = 5
maxParallelForks = 4
}
Process 1
TEST
SUITE
TEST
SUITE
TEST
SUITE
TEST
SUITE
TEST
SUITE
Process 7
TEST
SUITE
TEST
SUITE
Process 2
TEST
SUITE
TEST
SUITE
TEST
SUITE
TEST
SUITE
TEST
SUITE
Process 3
TEST
SUITE
TEST
SUITE
TEST
SUITE
TTEST
SUITE
TEST
SUITE
EXECUTION
Process 4
TEST
SUITE
TEST
SUITE
TTEST
SUITE
TEST
SUITE
TEST
SUITE
Process 6
TEST
SUITE
TEST
SUITE
TEST
SUITE
TEST
SUITE
TEST
SUITE
PARALLELISATION
37Lyon JUG - Présentation Gradle
• Utilisation d'un processus parallèle pour éviter le cout de
lancement
• Va favoriser l'intégration de Gradle avec Gradle UI et les
IDE (Eclipse, IDEA, ...)
> gradle build
...
Total time: 3s
> gradle build –daemon
...
Total time: 3s
> gradle build
...
Total time: 1s
38Lyon JUG - Présentation Gradle
39Lyon JUG - Présentation Gradle
gmock
spock
security
4
40Lyon JUG - Présentation Gradle
• Mailing List très active
• User guide très riche (+280 pages)
• Nombreuses contributions de plugins
• Le nombre d'articles et de conférences sur le sujet
augmentent
41Lyon JUG - Présentation Gradle
42Lyon JUG - Présentation Gradle
• Nouveau DSL de gestion des dépendances
• Introduction de modèles de JVM basés sur la nature des
applications
• Fourniture d'un DSL de composition du build
• Amélioration du DSL du graphe des tâches
• Réutilisation possible des plugins Maven
• Un livre en préparation
43Lyon JUG - Présentation Gradle
44Lyon JUG - Présentation Gradle
• Essayez-le !
• Utilisez-le !
• Faites du buzz!
45Lyon JUG - Présentation Gradle
Merci

Présentation Gradle au LyonJUG par Grégory Boissinot - Zenika

  • 1.
    1Lyon JUG -Présentation Gradle GRADLE Gregory BOISSINOT 23/11/2010
  • 2.
    2Lyon JUG -Présentation Gradle • Consultant et formateur Zenika – Mes spécialités: le build et l'intégration continue – Responsable technique de la solution d'intégration continue chez Thales • Introduction et déploiement de Gradle à grande échelle • Commiter Hudson – Intégration des châines de build Java (Gradle), C/C++, ADA
  • 3.
    3Lyon JUG -Présentation Gradle INTERNET
  • 4.
    4Lyon JUG -Présentation Gradle • Transformation d'une production humaine (le code source) en une représentation machine (le binaire) Fichier Source JAR JVM println "Hello World" for (int i:[1,2,3]){ print i } A;^A^@^Am^A^@^T()Ljava/lang/Object;^C^ @^@^@^@^A^@^KHello World^H^@2^A^@- org/codehaus/groovy/runtime/callsite/ CallSite^G^@4^A^@^KcallCurrent^A^@@ (Lgroovy/lang/GroovyObject; Ljava/lang/Object;)Ljava/lang/Object; ^L^@6^@7^K^@5^@8^C^@^@^@^A^L^@^H^ .... Fichier Binaire
  • 5.
    5Lyon JUG -Présentation Gradle • Les besoins d'automatisation ont augmentés significativement ces dernières années • La nature des besoins d'automatisation a changé Un build peut faire beaucoup plus de choses que la simple création d'une archive Java
  • 6.
    6Lyon JUG -Présentation Gradle 1ère génération 2008 2001 2 1 3 2ème génération 3ème génération 2000 2005 2008
  • 7.
    7Lyon JUG -Présentation Gradle <!–- ANT -- build.xml --> <project> <target name="retrieceDeps> ... </target> <target name="compile" ... </project> <!–- GRADLE– build.gradle --> apply plugin:'java' version=1.0 repositories { mavenCental() flatDir(dirs:'lib') } dependencies { compile( group:'org.apache.wicket', name:'wicket', version:'1.4.7') } <!–- MAVEN – pom.xml--> <?xml version="1.0" encoding="UTF-8"?> <project> <modelVersion>4.0.0</modelVersion> <groupId>org.lyonjug</groupId> <artifactId>maven</artifactId> <version>1.0</version> <dependencies> <dependency> <groupId>org.apache.wicket</groupId> <artifactId>wicket</artifactId> <version>1.4.7</version> <scope>compile</scope> </dependency> </dependencies> </project>
  • 8.
    8Lyon JUG -Présentation Gradle • Système de build complet focalisé sur le build des applications d'entreprise Java, Web, Groovy, Scala et OSGI • Modèle de description du build très riche à travers une API et une DSL Groovy • Flexible à la Ant avec les conventions de Maven à la demande • Support et insertion totale dans des infrastructures Maven et Ant/Ivy existantes
  • 9.
    9Lyon JUG -Présentation Gradle • Spécification du 'quoi' et pas du 'comment' Même convention que Maven apply plugin:'java' repositories { mavenCental() } dependencies { compile "jdom:jdom:1.1" testCompile "junit:junit:4.8" } myLib .jar src main java test java > gradle clean build :clean :compileJava :processResources :classes :jar :assemble :compileTestJava :processTestResources :testClasses :test :check :build BUILD SUCCESSFUL resources resources
  • 10.
    10Lyon JUG -Présentation Gradle On ne peut pas anticiper tous les besoins Il est nécessaire de fournir le même niveau de support entre les anciens projets et les nouveaux projets
  • 11.
    11Lyon JUG -Présentation Gradle Project repositories dependencies task configurations artifacts API ant Écrire un script Gradle consiste à configurer un objet Project build.gradle Eléments personnalisés
  • 12.
    12Lyon JUG -Présentation Gradle • Conçu pour répondre à tous les scénarios possibles – Plusieurs répertoires de sources par projet – Une version de JDK par répertoire – Plusieurs artefacts par projet – .... • De nombreux points d'extension pour enrichir les éléments existant • La possibilité de fournir ses propres éléments qui vont former un modèle de build
  • 13.
    13Lyon JUG -Présentation Gradle <!-- build.gradle --> task(boucleTask).doFirst{ for (int i:[1,2,3]){ print i } } void printMessage(String message){ println "Print " + message } task(distribution).doFirst { printMessage("Distribution") } task(release) release.dependsOn(distribution) release.doFirst{ println "Print Release" } > gradle boucleTask :boucleTask 123 > gradle distribution :distribution Print Distribution > gradle release :distribution Print Distribution :release Print Release Possibilité d'écrire du code Java/Groovy sous forme d'unités réutilisables
  • 14.
    14Lyon JUG -Présentation Gradle task mycopy (type:Copy){ description ='Copies the resources dir' from(file('resources')) into(file('target')) include('**/*.txt', '**/*.xml') } AbstractCopyTask AbstractArchiveTask Zip Jar War Tar SourceTask Javadoc ConventionTask Copy public class Copy extends AbstractCopyTask { public AbstractCopyTask from(Object... sourcePaths); public AbstractCopyTask into(Object destDir); public AbstractCopyTask include(String... includes); . . . }
  • 15.
    15Lyon JUG -Présentation Gradle <!– HelloTask.groovy --> class HelloTask extends DefaultTask { def message="Default Message" @TaskAction public void print(){ println message } } > gradle myhello :myhello Default Message > gradle myhello2 :myhello2 Task Message<!-- build.gradle --> task(myhello, type:HelloTask) task(myhello2, type:HelloTask){ message="Task Message" }
  • 16.
    16Lyon JUG -Présentation Gradle • Les plugins Gradle • Insertion dans un environnement agile
  • 17.
    17Lyon JUG -Présentation Gradle java war maven osgi code-quality jetty scala eclipse idea projects-reports Java Configuration Object War Configuration Object Jetty Configuration Object … Plugins Project Configuration … … Chaque plugin - est un ensemble de tâches - expose un objet Java convention
  • 18.
    18Lyon JUG -Présentation Gradle > gradle config ... <!– build.gradle --> task config { ... } <!– build.gradle --> apply from "http://repomanager/config-1.0.gradle" ... config-1.0.gradle Mise à disposition Utilisation
  • 19.
    19Lyon JUG -Présentation Gradle
  • 20.
    20Lyon JUG -Présentation Gradle • Flexibilité dans la définition des dépôts • Possibilité de mettre en place des exclusions globales • Possibilité de définir les dépendances transitives dans le script Gradle repositories{ mavenCentral() mavenRepo urls: "http://download.java.net/maven/2/" flatDir name: 'localRepository', dirs: 'lib' } dependencies { runtime module("org.codehaus.groovy:groovy-all:1.7.5") { dependency("commons-cli:commons-cli:1.0") { transitive = false } } }
  • 21.
    21Lyon JUG -Présentation Gradle apply plugin:'java' processResources.enabled=false test.onlyIf{ !project.hasProperty('skipTests')} //Add behavior in the lifecycle task(preJar) jar.dependsOn preJar //Change the output directory buildDirName='target' //Change the source directory sourceSets{ main{ java.srcDirs file('src/java'), file('src/java2') } } > gradle build –PskipTests :compileJava :processResources SKIPPED :classes :preJar :jar :war :assemble :compileTestJava :processTestResources :testClasses :test SKIPPED :check :build BUILD SUCCESSFUL
  • 22.
    22Lyon JUG -Présentation Gradle apply plugin:'java' sourceSets{ myGenSourceSet { java { srcDir 'build/generated' } } } > gradle clean build :clean :generateTask . . . :compileMyGenSourceSetJava :processMyGenSourceSetResources :myGenSourceSetClasses . . .
  • 23.
    23Lyon JUG -Présentation Gradle sourceSets{ myGenSourceSet { java { srcDir 'build/generated' } main { compileClasspath = configurations.compile +sourceSets.myGenSourceSet.classes runtimeClasspath = classes + configurations.runtime + sourceSets.myGenSourceSet.classes } } jar { from sourceSets.myGenSourceSet.classes } > gradle clean build :clean :generateTask :compileMyGenSourceSetJava :processMyGenSourceSetResources :myGenSourceSetClasses :compileJava :processResources :classes . . .
  • 24.
    24Lyon JUG -Présentation Gradle version = 1.0 gradle.taskGraph.whenReady { taskGraph -> if (! taskGraph.hasTask(':release')){ version+='-SNAPSHOT' } } GRADLE SCRIPT Engine CONFIGURATIONPHASE t1 t2 t4 Project Convention 1 HOOK t3 t1 t2 t4 Project Convention 2 t3 EXECUTIONPHASE gradle –-properties gradle –-tasks gradle –-dependencies gradle –-dry-run build // Other hooks gradle.taskGraph.beforeTask { task -> .. . gradle.beforeProject { project -> .. . ...
  • 25.
    25Lyon JUG -Présentation Gradle Soyez informé des événements: TestListener, BuildListener, TaskActionListener, … class MyTestListener implements TestListener{ void beforeTest(TestDescriptor test) { println 'testStarting: '+test.getName() } void afterTest(TestDescriptor test, TestResult result) { println 'testFinished: '+test.getName() +', result: '+result.getResultType() } } Test (junit) GRADLE beforeTest afterTest
  • 26.
    26Lyon JUG -Présentation Gradle import org.junit.Assert task myzip (type:Zip) { from 'somedir' include '*.txt' baseName='zipname' doLast { Assert.assertEquals('zipname.zip', myzip.archiveName) Assert.assertEquals(file('build/distributions'), myzip.destinationDir) Assert.assertTrue( !zipTree(myzip.archivePath).isEmpty()) txtfiles = fileTree('somedir').include('*.txt') ziptxtfiles=zipTree(myzip.archivePath).matching{ include('*.txt') } Assert.assertEquals ( txtfiles.getFiles().size(), ziptxtfiles.getFiles().size()) } } zipname .zip createZip check > gradle myzip :myzip BUILD SUCCESSFUL >
  • 27.
    27Lyon JUG -Présentation Gradle
  • 28.
    28Lyon JUG -Présentation Gradle task generateTask(dependsOn:preSchemaGen) << { ant.echo (message:"Generating ...") ant { def schemagenTaskPath = path { fileset(dirs:'lib', includes: '*.jar') } taskdef ( name: "xjc", classname: "com.sun.tools.xjc.XJCTask", classpath: schemagenTaskPath ) xjc(destdir:generatedSources, package:"com.zenika.lib.model"){ schema(dir:"src/main/resources", includes:"**/*.xsd") } } }
  • 29.
    29Lyon JUG -Présentation Gradle build.gradle build.xml ant.importBuild('build.xml') antTask.doLast { println('Hello from Gradle') } <project> <target name="antTask"> <echo message="Hello from Ant"/> </target> </project> > gradle antTask :antTask Hello from Ant Hello from Gradle
  • 30.
    30Lyon JUG -Présentation Gradle IVY Repository Ivy distant Artifacts + meta Ivy apply plugin:'java' repositories { mavenCental() flatDir(dirs:'destrepo', name:'ivyrep’) } group='test' version='1.0' status='release' uploadArchives { repositories { add(repositories.ivyrep) } } > gradle uploadArchives
  • 31.
    31Lyon JUG -Présentation Gradle Repository Maven distant Artifacts + meta Maven Maven Ant Tasks Repository Maven Local Artifacts + meta Maven apply plugin:'java' apply plugin:'maven' group='test' version='1.0-SNAPSHOT' uploadArchives { repositories { mavenDeployer { repository( url: remoteRepo) } } } > gradle uploadArchives > gradle install
  • 32.
    32Lyon JUG -Présentation Gradle • Gestion avancée d'un multi projet • Utilisation d'un cache • Exécution parallèle des tests • Build daemon
  • 33.
    33Lyon JUG -Présentation Gradle // settings.gradle include 'api', 'shared', 'services:webservices' // root build.gradle subprojects { apply plugin: 'java' } project(':api') { dependencies { compile project(':shared') } } // webservices/build.gradle apply plugin:'war' dependencies { compile project(':shared'), project(':api'), 'commons-io:commons-io:1.2' } shared webservices api api > gradle buildNeeded :shared:jar :api:jar :api:test :shared:test api > gradle buildDependents :shared:jar :api:jar :api:test :webservices:war :webservices:test api > gradle jar –-no-rebuild api:jar
  • 34.
    34Lyon JUG -Présentation Gradle 1.  Le script Gradle est compilé uniquement en cas de changement 2.  Détéction des changements pour chaque entrée et chaque sortie pour la plupart des tâches fournies > gradle myzip :myzip > gradle myzip :myzip UP-TO-DATE > gradle myzip –-cache rebuild :myzip
  • 35.
    35Lyon JUG -Présentation Gradle class GenerateSchemaType extends DefaultTask { String depsPath @InputFiles SourceDirectorySet inputXsdDirs @OutputDirectory File outputFile @TaskAction void generate() { ant { ...} } } task generateTask(type:GenerateSchemaType) { inputXsdDirs = sourceSets.main.resources outputFile = generatedSources depsPath = configurations.jaxb.asPath } > gradle build :generateTask UP-TO-DATE :compileGeneratedJava UP-TO-DATE :processGeneratedResources UP-TO-DATE :generatedClasses UP-TO-DATE :compileJava UP-TO-DATE ...
  • 36.
    36Lyon JUG -Présentation Gradle apply plugin:'java' test { forkEvery = 5 maxParallelForks = 4 } Process 1 TEST SUITE TEST SUITE TEST SUITE TEST SUITE TEST SUITE Process 7 TEST SUITE TEST SUITE Process 2 TEST SUITE TEST SUITE TEST SUITE TEST SUITE TEST SUITE Process 3 TEST SUITE TEST SUITE TEST SUITE TTEST SUITE TEST SUITE EXECUTION Process 4 TEST SUITE TEST SUITE TTEST SUITE TEST SUITE TEST SUITE Process 6 TEST SUITE TEST SUITE TEST SUITE TEST SUITE TEST SUITE PARALLELISATION
  • 37.
    37Lyon JUG -Présentation Gradle • Utilisation d'un processus parallèle pour éviter le cout de lancement • Va favoriser l'intégration de Gradle avec Gradle UI et les IDE (Eclipse, IDEA, ...) > gradle build ... Total time: 3s > gradle build –daemon ... Total time: 3s > gradle build ... Total time: 1s
  • 38.
    38Lyon JUG -Présentation Gradle
  • 39.
    39Lyon JUG -Présentation Gradle gmock spock security 4
  • 40.
    40Lyon JUG -Présentation Gradle • Mailing List très active • User guide très riche (+280 pages) • Nombreuses contributions de plugins • Le nombre d'articles et de conférences sur le sujet augmentent
  • 41.
    41Lyon JUG -Présentation Gradle
  • 42.
    42Lyon JUG -Présentation Gradle • Nouveau DSL de gestion des dépendances • Introduction de modèles de JVM basés sur la nature des applications • Fourniture d'un DSL de composition du build • Amélioration du DSL du graphe des tâches • Réutilisation possible des plugins Maven • Un livre en préparation
  • 43.
    43Lyon JUG -Présentation Gradle
  • 44.
    44Lyon JUG -Présentation Gradle • Essayez-le ! • Utilisez-le ! • Faites du buzz!
  • 45.
    45Lyon JUG -Présentation Gradle Merci