GRADLE
                                  Grégory BOISSINOT
                                       (@gboissinot)
                                        18/05/2011




 ToursJUG - Présentation Gradle                        1
•  Consultant et formateur Zenika
    – En charge du comité technique Intégration continue

•  Contributeur et Committer pour Hudson/Jenkins
    – Intégration des chaînes de build Java (Gradle), C/C++, ADA
    – Maintenance corrective et évolutive des plugins réalisés
    – Développement de solutions transverses




                          ToursJUG - Présentation Gradle           2
•  Transformation d'une production humaine (le code
   source) en une représentation machine (le binaire)




       Fichier
                                                              JAR
       Source
                                                               Fichier
                                                               Binaire

                                                                             JVM


     println "Hello World"                    A;^A^@^Am^A^@^T()Ljava/lang/Object;^C^
     for (int i:[1,2,3]){                     @^@^@^@^A^@^KHello World^H^@2^A^@-
       print i                                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^
                                              ....
                             ToursJUG - Présentation Gradle                            3
INTERNET


Change




           Polling

     ENV




                     ToursJUG - Présentation Gradle              4
•  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




•  Les besoins d'automatisation ont augmentés
   significativement ces dernières années

                       ToursJUG - Présentation Gradle    5
1ère génération   2ème génération                   3ème génération
    2000                    2004                           2008

                                                    2008

2001


                                                                       3


                                              2

               1

                   ToursJUG - Présentation Gradle                          6
<!–- ANT -- build.xml -->
<project>
   <target name="retrieceDeps>
                               <!–- MAVEN – pom.xml-->
     ...
                               <?xml version="1.0" encoding="UTF-8"?>
   </target>
                               <project>
   <target name="compile" ...
                                 <modelVersion>4.0.0</modelVersion>
</project>
                                 <groupId>org.lyonjug</groupId>
                                 <artifactId>maven</artifactId>
<!–- GRADLE– build.gradle -->    <version>1.0</version>
apply plugin:'java'              <dependencies>
                                   <dependency>
version=1.0                          <groupId>org.apache.wicket</groupId>
                                     <artifactId>wicket</artifactId>
repositories {                       <version>1.4.7</version>
   mavenCental()                     <scope>compile</scope>
   flatDir(dirs:'lib')             </dependency>
}                                </dependencies>
                               </project>
dependencies {
  compile(
    group:'org.apache.wicket',
    name:'wicket',
    version:'1.4.7')
}
                            ToursJUG - Présentation Gradle              7
•  Système de build complet focalisé sur le build des
   applications d'entreprise Java, Web, Groovy, Scala et
   OSGI

•  Flexible à la Ant avec les conventions de Maven à la
   demande

•  Support et insertion totale dans des infrastructures Maven
   et Ant/Ivy existantes

•  Modèle de description du build très riche à travers une
   API Java et une DSL Groovy


                        ToursJUG - Présentation Gradle          8
Central       java.net
                            Maven


                       JBoss                                 …
                                      Codehaus

                                                         Artifacts +
                                                         maven meta




                      Ivy
                   Repository
                   Artifacts +
                    ivy meta
                                        Other
                                      Repository
                                           Artifacts +
                                          custom meta


ToursJUG - Présentation Gradle                                         9
•  Spécification du 'quoi' et pas du 'comment'
                             iture
                        Fourn le
                              yc
                        d'un c
                           de vie
                                                                                Même
                                                                                    ntion
apply plugin:'java'    > gradle clean build                                   conve en
                                                                                     av
                       :clean                                                  que M
repositories {         :compileJava
                                                                                   src
  mavenCental()        :processResources
}                      :classes                                       myLib              main
                                                                      .jar
                       :jar
dependencies {                                                                                  java
                       :assemble
  compile              :compileTestJava                                                         resources
   "jdom:jdom:1.1"     :processTestResources
  testCompile          :testClasses
   "junit:junit:4.8"   :test                                                             test
}                      :check
                                                                                                java
                       :build

                       BUILD SUCCESSFUL                                                         resources




                                     ToursJUG - Présentation Gradle                                         10
On ne peut pas anticiper tous les besoins
    Aucun projet n'est réellement pareil!
    Le projet évolue et donc son processus d'intégration évolue aussi




Il est important de fournir au minimum le même niveau de support
pour les anciens projets que les nouveaux projets




                            ToursJUG - Présentation Gradle               11
Écrire un script Gradle consiste à configurer un élément 'Project'



                                                   configurations
build.gradle
                          repositories
                                                                     dependencies




                                   Project                                  ant



                                                                 Eléments
                        task                                     personnalisés


                                           artifacts




                                                 Public
                                                  API
                                ToursJUG - Présentation Gradle                      12
•  Conçu pour répondre à un maximum de scénarios
    – Plusieurs répertoires de sources par projet
    – Plusieurs artefacts générés par projet
    – Gestion de classpath distinct pour les tests
      d'intégration
    – ....

•  De nombreux points d'extension pour enrichir les
   éléments existants
      Possibilité de former un modèle de build (un
      ensemble de conventions), le tout dans une
      approche déclarative


                       ToursJUG - Présentation Gradle   13
La mise en œuvre de l'API à
                                        travers des tâches de
                                        traitement




    compile   jar     test         custom

                                                 build
              war


Un processus Gradle
est un ensemble de tâches

                    ToursJUG - Présentation Gradle                    14
Possibilité d'écrire du code Java/Groovy sous forme d'unités de
traitement réutilisables

<!-- build.gradle -->                          Gradle
task(boucleTask).doLast{
  for (int i:[1,2,3]){ print i }
}                                               Java/
                                               Groovy

void printMessage(String message){
                                                       > gradle boucleTask
  println "Print " + message                           :boucleTask
}                                                      123
task(distribution).doLast {
    printMessage("Distribution")                       > gradle distribution
}                                                      :distribution
                                                       Print Distribution
task(release)
release.dependsOn(distribution)                        > gradle release
                                                       :distribution
release.doLast{                                        Print Distribution
    println "Print Release"                            :release
}                                                      Print Release

                            ToursJUG - Présentation Gradle                     15
ConventionTask                                          Mise à disposition d'un ensemble
                                                         de tâches prédéfinies
                                                         - réutilisables
                                                         - faciles à étendre
 AbstractCopyTask     SourceTask




AbstractArchiveTask     Copy                 Javadoc



                                   public class Copy extends AbstractCopyTask {
                                      public AbstractCopyTask from(Object... sourcePaths);
   Zip          Tar                   public AbstractCopyTask into(Object destDir);
                                      public AbstractCopyTask include(String... includes);
                                      . . .
                                   }

   Jar
                                   task mycopy (type:Copy){
                                     description ='Copies the resources dir'
                                     from(file('resources'))
                                     into(file('destination'))
  War
                                     include('**/*.txt', '**/*.xml')
                                   }

                                     ToursJUG - Présentation Gradle                          16
• Les plugins Gradle

• Insertion dans un environnement agile




                   ToursJUG - Présentation Gradle   17
Chaque plugin
- est un ensemble de tâches préconfigurées
- expose un objet de configuration (avec des conventions)



     Plugins              maven
                                                                             Java Configuration
                                                                                   Object
       eclipse       idea
                                                              Jetty Configuration    War Configuration
                                                                     Object               Object
    code-quality          war
 projects-reports    java
                                                                      …                       …


       jetty         osgi                                              …

        scala
                    ...                                                  Project
                                                                       Configuration

                                  ToursJUG - Présentation Gradle                                         18
Java Configuration
    java                        Object




public class JavaPluginConvention {
   public SouceSetContainer sourceSets();
   public void setSourceCompatibility(Object value);
   public void setTargetCompatibility(Object value);
   public Manifest manifest()

    . . .
}

           <!-- build.gradle -->
                                                              Facile à
           apply plugin:'java'                                mettre en
                                                                          Simple à
                                                              place et
                                                                          apprendre
                                                               facile à
           sourceCompatibility = 1.6                          maintenir
           targetCompatibility = 1.6


                             ToursJUG - Présentation Gradle                           19
Mise à
                          disposition




                                                                globalConfig-1.0.gradle
 <!– build.gradle -->
 task globalConfig {
   ...
 }
                                     Utilisation




<!– build.gradle -->                                                             > gradle config
apply from "http://repomanager/globalConfig-1.0.gradle"                          ...
...

                               ToursJUG - Présentation Gradle                                      20
ToursJUG - Présentation Gradle   21
•  Possibilité de mettre en place des exclusions globales
•  Flexibilité dans la définition des dépôts
 repositories{
   mavenCentral()
   mavenRepo urls:"http://download.java.net/maven/2/"
   flatDir name:'localRepository', dirs: 'lib'
 }

•  Possibilité de définir les dépendances et les déepdances
   transitives directement dans le script Gradle

 dependencies {
     runtime module("org.codehaus.groovy:groovy-all:1.7.5") {
         dependency("commons-cli:commons-cli:1.0") {
             transitive = false
         }
     }
 }
                         ToursJUG - Présentation Gradle         22
apply plugin:'java'

processResources.enabled=false
test.onlyIf{
 !project.hasProperty('skipTests')}

task(preJar)                                              > gradle build –PskipTests
jar.dependsOn preJar                                      :compileJava
                                                          :processResources SKIPPED
//Change the source directory                             :classes
sourceSets{                                               :preJar
  main{                                                   :jar
                                                          :assemble
    java.srcDirs file('src/java'),                        :compileTestJava
                 file('src/java2')                        :processTestResources
  }                                                       :testClasses
}                                                         :test SKIPPED
                                                          :check
//Création d'un uberjar                                   :build
jar {
  configurations.compile.each {                           BUILD SUCCESSFUL
      from zipTree (it) }
}
                         ToursJUG - Présentation Gradle                           23
apply plugin:'java'                             > gradle clean build
                                                :clean
sourceSets{                                     :generateTask
                                                . . .
  myGenSourceSet {                              :compileMyGenSourceSetJava
    java {                                      :processMyGenSourceSetResources
      srcDir 'output/generated'                 :myGenSourceSetClasses
    }                                           . . .
  }
}



  Mise à disposition automatique d'un ensemble de tâches de traitement
                    pour le nouveau besoin fonctionnel




                            ToursJUG - Présentation Gradle                        24
> gradle clean build
sourceSets{                                         :clean
 myGenSourceSet {                                   :generateTask
 java {                                             :compileMyGenSourceSetJava
    srcDir 'output/generated'                       :processMyGenSourceSetResources
  }                                                 :myGenSourceSetClasses
                                                    :compileJava
    main {                                          :processResources
     compileClasspath =                             :classes
      configurations.compile                        . . .
       + sourceSets.myGenSourceSet.classes

     runtimeClasspath =
      classes
        + configurations.runtime
        + sourceSets.myGenSourceSet.classes
    }
}

jar {
  from sourceSets.myGenSourceSet.classes
}
                            ToursJUG - Présentation Gradle                            25
CONFIGURATION PHASE

                                t1         t2   t3                           t1            t2   t3




                                                                                                     EXECUTION PHASE
GRADLE
                                      t4                                              t4




                                                                HOOK
SCRIPT


                                       Project                                         Project                         Engine
                                     Convention 1                                    Convention 2




gradle   –-properties                           gradle.taskGraph.whenReady { taskGraph ->
gradle   –-tasks                                  if (taskGraph.hasTask(':release')){
gradle   –-dependencies                                 status = 'release'
gradle   –-dry-run build                          }
                                                }

                                                // Other hooks
                                                gradle.taskGraph.beforeTask { task -> .. .
                                                gradle.beforeProject { project -> .. .
                                                ...
                                                    ToursJUG - Présentation Gradle                                              26
Soyez informé des événements: TestListener,
     BuildListener, TaskActionListener, …

class MyTestListener implements TestListener{
                                                                        beforeTest
    void beforeTest(TestDescriptor test) {




                                                               GRADLE
      println 'testStarting: '+test.getName()
    }                                                                    Test
                                                                           (junit)
    void afterTest(TestDescriptor test,
                   TestResult result) {
      println 'testFinished: '+test.getName()                           afterTest
           +', result: '+result.getResultType()
    }
}




                              ToursJUG - Présentation Gradle                         27
import org.junit.Assert
                                                                   > gradle myzip
task myzip (type:Zip) {                                            :myzip
  from('somedir')
  include('*.txt')
  baseName='zipname'
  doLast {
   Assert.assertEquals('zipname.zip',
                         myzip.archiveName)                         createZip
   Assert.assertEquals(file('build/distributions'),
                        myzip.destinationDir)

        Assert.assertTrue(                                                      zipname
                                                                                .zip
                 !zipTree(myzip.archivePath).isEmpty())

        txtfiles = fileTree('somedir').include('*.txt')
                                                                     check
        ziptxtfiles=zipTree(myzip.archivePath).matching{
                include('*.txt')
              }
        Assert.assertEquals (
              txtfiles.getFiles().size(),                          BUILD SUCCESSFUL
              ziptxtfiles.getFiles().size())                       >
    }
}




                                  ToursJUG - Présentation Gradle                          28
ToursJUG - Présentation Gradle   29
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")
     }
   }
}




                        ToursJUG - Présentation Gradle         30
build.xml
                 <project>
                   <target name="antTarget">
                     <echo message="Hello from Ant"/>
                   </target>
                 </project>



 build.gradle
                 ant.importBuild('build.xml')
                 antTarget.doLast {
                    println('Hello from Gradle')
                 }



> gradle antTarget
:antTarget
Hello from Ant
Hello from Gradle

                ToursJUG - Présentation Gradle          31
apply plugin:'java'

repositories {
  mavenCental()
  flatDir(dirs:'destrepo',                                    IVY
          name:'ivyrep’)
}

group='com.zenika.gradledemos'                                  > gradle uploadArchives
version='1.0'
status='release'

uploadArchives {
  repositories {
    add(repositories.ivyrep)
  }
}                                                         Repository
                                                             Ivy
                                                           distant Artifacts +
                                                                       meta Ivy



                         ToursJUG - Présentation Gradle                                   32
apply plugin:'java'
apply plugin:'maven'                                      Maven
                                                           Ant
group='test'                                              Tasks
version='1.0-SNAPSHOT'

uploadArchives {
  repositories {
    mavenDeployer {
      repository(                        > gradle           > gradle
                                           install            uploadArchives
         url: remoteRepo)
    }
  }
}



                            Repository                    Repository
                              Maven                         Maven
                              Local Artifacts +            distant Artifacts +
                                            meta Maven
                                                                      meta Maven


                         ToursJUG - Présentation Gradle                            33
• Gestion avancée d'un multi projet

• Utilisation d'un cache

• Exécution parallèle des tests

• Build daemon


                    ToursJUG - Présentation Gradle   34
// settings.gradle                                                   shared
include 'api',
        'shared',
        'services:webservices'
                                                            webservices       api
// root build.gradle
subprojects {                                  api > gradle buildNeeded
  apply plugin: 'java'                         :shared:jar
}                                              :api:jar
project(':api') {                              :api:test
  dependencies {                               :shared:test
    compile project(':shared')
  }
}                                              api > gradle buildDependents
                                               :shared:jar
                                               :api:jar
// webservices/build.gradle
apply plugin:'war'                             :api:test
                                               :webservices:war
dependencies {
                                               :webservices:test
  compile
    project(':shared'),
    project(':api'),                           api > gradle jar –-no-rebuild
   'commons-io:commons-io:1.2'                 api:jar
}
                           ToursJUG - Présentation Gradle                           35
1.  Le script Gradle est compilé uniquement en cas de
    changement


2.  Détection 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



                       ToursJUG - Présentation Gradle     36
class GenerateSchemaType extends DefaultTask {

    String depsPath

    @InputFiles
    SourceDirectorySet inputXsdDirs

    @OutputDirectory
    File outputFile
                                      > gradle build
                                      :generateTask UP-TO-DATE
    @TaskAction                       :compileGeneratedJava UP-TO-DATE
    void generate() {                 :processGeneratedResources UP-TO-DATE
      ant { ...}                      :generatedClasses UP-TO-DATE
    }                                 :compileJava UP-TO-DATE
}                                     ...

task generateTask(type:GenerateSchemaType) {
  inputXsdDirs = sourceSets.main.resources
  outputFile = generatedSources
  depsPath = configurations.jaxb.asPath
}
                          ToursJUG - Présentation Gradle                  37
EXECUTION
                                                         Process 1                                              Process 6
                   TEST    TEST    TEST    TEST    TEST                  TEST        TEST    TEST    TEST    TEST
                  CLASS   CLASS   CLASS   CLASS   CLASS                 CLASS       CLASS   CLASS   CLASS   CLASS
PARALLELISATION




                                                         Process 2                                              Process 7
                   TEST    TEST    TEST    TEST    TEST                  TEST        TEST
                  CLASS   CLASS   CLASS   CLASS   CLASS                 CLASS       CLASS

                                                          Process 3
                   TEST    TEST    TEST    TEST    TEST
                  CLASS   CLASS   CLASS   CLASS   CLASS
                                                                           apply plugin:'java'
                                                          Process 4
                   TEST    TEST    TEST    TEST    TEST
                  CLASS   CLASS   CLASS   CLASS   CLASS                    test {
                                                                             forkEvery = 5
                                                                             maxParallelForks = 4
                                                                           }




                                                   ToursJUG - Présentation Gradle                                      38
•  Utilisation d'un processus parallèle pour éviter le cout de
   lancement
             > gradle build
             ...
             Total time: 3s

             > gradle build –daemon
             ...
             Total time: 3s

             > gradle build
             ...
             Total time: 1s



•  Va favoriser l'intégration de Gradle avec Gradle UI et les
   IDE (Eclipse, IDEA, ...)


                         ToursJUG - Présentation Gradle          39
IDE                           Maturité
NetBeans
Eclipse                       +
IntelliJ                      ++



           ToursJUG - Présentation Gradle   40
ToursJUG - Présentation Gradle   41
gmock

                                                   security
 spock



                                          integration




                                                        4



         ToursJUG - Présentation Gradle                       42
•  Mailing List très active

•  User guide très riche (300 pages)

•  Nombreuses contributions de plugins

•  Le nombre d'articles et de conférences sur le sujet
   augmentent




                              ToursJUG - Présentation Gradle   43
•  Fourniture de consulting et de formation




                        ToursJUG - Présentation Gradle   44
ToursJUG - Présentation Gradle   45
•  Introduction de modèles de JVM basés sur la nature des
   applications

•  Amélioration du DSL du graphe des tâches

•  Réutilisation possible des plugins Maven

•  Un livre en préparation

•  Une communauté plus large




                         ToursJUG - Présentation Gradle     46
ToursJUG - Présentation Gradle   47
• Essayez-le !

• Utilisez-le !

• Faites du buzz!




                  ToursJUG - Présentation Gradle   48

Gradle_ToursJUG

  • 1.
    GRADLE Grégory BOISSINOT (@gboissinot) 18/05/2011 ToursJUG - Présentation Gradle 1
  • 2.
    •  Consultant etformateur Zenika – En charge du comité technique Intégration continue •  Contributeur et Committer pour Hudson/Jenkins – Intégration des chaînes de build Java (Gradle), C/C++, ADA – Maintenance corrective et évolutive des plugins réalisés – Développement de solutions transverses ToursJUG - Présentation Gradle 2
  • 3.
    •  Transformation d'uneproduction humaine (le code source) en une représentation machine (le binaire) Fichier JAR Source Fichier Binaire JVM println "Hello World" A;^A^@^Am^A^@^T()Ljava/lang/Object;^C^ for (int i:[1,2,3]){ @^@^@^@^A^@^KHello World^H^@2^A^@- print i 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^ .... ToursJUG - Présentation Gradle 3
  • 4.
    INTERNET Change Polling ENV ToursJUG - Présentation Gradle 4
  • 5.
    •  La naturedes besoins d'automatisation a changé Un build peut faire beaucoup plus de choses que la simple création d'une archive Java •  Les besoins d'automatisation ont augmentés significativement ces dernières années ToursJUG - Présentation Gradle 5
  • 6.
    1ère génération 2ème génération 3ème génération 2000 2004 2008 2008 2001 3 2 1 ToursJUG - Présentation Gradle 6
  • 7.
    <!–- ANT --build.xml --> <project> <target name="retrieceDeps> <!–- MAVEN – pom.xml--> ... <?xml version="1.0" encoding="UTF-8"?> </target> <project> <target name="compile" ... <modelVersion>4.0.0</modelVersion> </project> <groupId>org.lyonjug</groupId> <artifactId>maven</artifactId> <!–- GRADLE– build.gradle --> <version>1.0</version> apply plugin:'java' <dependencies> <dependency> version=1.0 <groupId>org.apache.wicket</groupId> <artifactId>wicket</artifactId> repositories { <version>1.4.7</version> mavenCental() <scope>compile</scope> flatDir(dirs:'lib') </dependency> } </dependencies> </project> dependencies { compile( group:'org.apache.wicket', name:'wicket', version:'1.4.7') } ToursJUG - Présentation Gradle 7
  • 8.
    •  Système debuild complet focalisé sur le build des applications d'entreprise Java, Web, Groovy, Scala et OSGI •  Flexible à la Ant avec les conventions de Maven à la demande •  Support et insertion totale dans des infrastructures Maven et Ant/Ivy existantes •  Modèle de description du build très riche à travers une API Java et une DSL Groovy ToursJUG - Présentation Gradle 8
  • 9.
    Central java.net Maven JBoss … Codehaus Artifacts + maven meta Ivy Repository Artifacts + ivy meta Other Repository Artifacts + custom meta ToursJUG - Présentation Gradle 9
  • 10.
    •  Spécification du'quoi' et pas du 'comment' iture Fourn le yc d'un c de vie Même ntion apply plugin:'java' > gradle clean build conve en av :clean que M repositories { :compileJava src mavenCental() :processResources } :classes myLib main .jar :jar dependencies { java :assemble compile :compileTestJava resources "jdom:jdom:1.1" :processTestResources testCompile :testClasses "junit:junit:4.8" :test test } :check java :build BUILD SUCCESSFUL resources ToursJUG - Présentation Gradle 10
  • 11.
    On ne peutpas anticiper tous les besoins  Aucun projet n'est réellement pareil!  Le projet évolue et donc son processus d'intégration évolue aussi Il est important de fournir au minimum le même niveau de support pour les anciens projets que les nouveaux projets ToursJUG - Présentation Gradle 11
  • 12.
    Écrire un scriptGradle consiste à configurer un élément 'Project' configurations build.gradle repositories dependencies Project ant Eléments task personnalisés artifacts Public API ToursJUG - Présentation Gradle 12
  • 13.
    •  Conçu pourrépondre à un maximum de scénarios – Plusieurs répertoires de sources par projet – Plusieurs artefacts générés par projet – Gestion de classpath distinct pour les tests d'intégration – .... •  De nombreux points d'extension pour enrichir les éléments existants Possibilité de former un modèle de build (un ensemble de conventions), le tout dans une approche déclarative ToursJUG - Présentation Gradle 13
  • 14.
    La mise enœuvre de l'API à travers des tâches de traitement compile jar test custom build war Un processus Gradle est un ensemble de tâches ToursJUG - Présentation Gradle 14
  • 15.
    Possibilité d'écrire ducode Java/Groovy sous forme d'unités de traitement réutilisables <!-- build.gradle --> Gradle task(boucleTask).doLast{ for (int i:[1,2,3]){ print i } } Java/ Groovy void printMessage(String message){ > gradle boucleTask println "Print " + message :boucleTask } 123 task(distribution).doLast { printMessage("Distribution") > gradle distribution } :distribution Print Distribution task(release) release.dependsOn(distribution) > gradle release :distribution release.doLast{ Print Distribution println "Print Release" :release } Print Release ToursJUG - Présentation Gradle 15
  • 16.
    ConventionTask Mise à disposition d'un ensemble de tâches prédéfinies - réutilisables - faciles à étendre AbstractCopyTask SourceTask AbstractArchiveTask Copy Javadoc public class Copy extends AbstractCopyTask { public AbstractCopyTask from(Object... sourcePaths); Zip Tar public AbstractCopyTask into(Object destDir); public AbstractCopyTask include(String... includes); . . . } Jar task mycopy (type:Copy){ description ='Copies the resources dir' from(file('resources')) into(file('destination')) War include('**/*.txt', '**/*.xml') } ToursJUG - Présentation Gradle 16
  • 17.
    • Les plugins Gradle • Insertiondans un environnement agile ToursJUG - Présentation Gradle 17
  • 18.
    Chaque plugin - estun ensemble de tâches préconfigurées - expose un objet de configuration (avec des conventions) Plugins maven Java Configuration Object eclipse idea Jetty Configuration War Configuration Object Object code-quality war projects-reports java … … jetty osgi … scala ... Project Configuration ToursJUG - Présentation Gradle 18
  • 19.
    Java Configuration java Object public class JavaPluginConvention { public SouceSetContainer sourceSets(); public void setSourceCompatibility(Object value); public void setTargetCompatibility(Object value); public Manifest manifest() . . . } <!-- build.gradle --> Facile à apply plugin:'java' mettre en Simple à place et apprendre facile à sourceCompatibility = 1.6 maintenir targetCompatibility = 1.6 ToursJUG - Présentation Gradle 19
  • 20.
    Mise à disposition globalConfig-1.0.gradle <!– build.gradle --> task globalConfig { ... } Utilisation <!– build.gradle --> > gradle config apply from "http://repomanager/globalConfig-1.0.gradle" ... ... ToursJUG - Présentation Gradle 20
  • 21.
  • 22.
    •  Possibilité demettre en place des exclusions globales •  Flexibilité dans la définition des dépôts repositories{ mavenCentral() mavenRepo urls:"http://download.java.net/maven/2/" flatDir name:'localRepository', dirs: 'lib' } •  Possibilité de définir les dépendances et les déepdances transitives directement dans le script Gradle dependencies { runtime module("org.codehaus.groovy:groovy-all:1.7.5") { dependency("commons-cli:commons-cli:1.0") { transitive = false } } } ToursJUG - Présentation Gradle 22
  • 23.
    apply plugin:'java' processResources.enabled=false test.onlyIf{ !project.hasProperty('skipTests')} task(preJar) > gradle build –PskipTests jar.dependsOn preJar :compileJava :processResources SKIPPED //Change the source directory :classes sourceSets{ :preJar main{ :jar :assemble java.srcDirs file('src/java'), :compileTestJava file('src/java2') :processTestResources } :testClasses } :test SKIPPED :check //Création d'un uberjar :build jar { configurations.compile.each { BUILD SUCCESSFUL from zipTree (it) } } ToursJUG - Présentation Gradle 23
  • 24.
    apply plugin:'java' > gradle clean build :clean sourceSets{ :generateTask . . . myGenSourceSet { :compileMyGenSourceSetJava java { :processMyGenSourceSetResources srcDir 'output/generated' :myGenSourceSetClasses } . . . } } Mise à disposition automatique d'un ensemble de tâches de traitement pour le nouveau besoin fonctionnel ToursJUG - Présentation Gradle 24
  • 25.
    > gradle cleanbuild sourceSets{ :clean myGenSourceSet { :generateTask java { :compileMyGenSourceSetJava srcDir 'output/generated' :processMyGenSourceSetResources } :myGenSourceSetClasses :compileJava main { :processResources compileClasspath = :classes configurations.compile . . . + sourceSets.myGenSourceSet.classes runtimeClasspath = classes + configurations.runtime + sourceSets.myGenSourceSet.classes } } jar { from sourceSets.myGenSourceSet.classes } ToursJUG - Présentation Gradle 25
  • 26.
    CONFIGURATION PHASE t1 t2 t3 t1 t2 t3 EXECUTION PHASE GRADLE t4 t4 HOOK SCRIPT Project Project Engine Convention 1 Convention 2 gradle –-properties gradle.taskGraph.whenReady { taskGraph -> gradle –-tasks if (taskGraph.hasTask(':release')){ gradle –-dependencies status = 'release' gradle –-dry-run build } } // Other hooks gradle.taskGraph.beforeTask { task -> .. . gradle.beforeProject { project -> .. . ... ToursJUG - Présentation Gradle 26
  • 27.
    Soyez informé desévénements: TestListener, BuildListener, TaskActionListener, … class MyTestListener implements TestListener{ beforeTest void beforeTest(TestDescriptor test) { GRADLE println 'testStarting: '+test.getName() } Test (junit) void afterTest(TestDescriptor test, TestResult result) { println 'testFinished: '+test.getName() afterTest +', result: '+result.getResultType() } } ToursJUG - Présentation Gradle 27
  • 28.
    import org.junit.Assert > gradle myzip task myzip (type:Zip) { :myzip from('somedir') include('*.txt') baseName='zipname' doLast { Assert.assertEquals('zipname.zip', myzip.archiveName) createZip Assert.assertEquals(file('build/distributions'), myzip.destinationDir) Assert.assertTrue( zipname .zip !zipTree(myzip.archivePath).isEmpty()) txtfiles = fileTree('somedir').include('*.txt') check ziptxtfiles=zipTree(myzip.archivePath).matching{ include('*.txt') } Assert.assertEquals ( txtfiles.getFiles().size(), BUILD SUCCESSFUL ziptxtfiles.getFiles().size()) > } } ToursJUG - Présentation Gradle 28
  • 29.
  • 30.
    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") } } } ToursJUG - Présentation Gradle 30
  • 31.
    build.xml <project> <target name="antTarget"> <echo message="Hello from Ant"/> </target> </project> build.gradle ant.importBuild('build.xml') antTarget.doLast { println('Hello from Gradle') } > gradle antTarget :antTarget Hello from Ant Hello from Gradle ToursJUG - Présentation Gradle 31
  • 32.
    apply plugin:'java' repositories { mavenCental() flatDir(dirs:'destrepo', IVY name:'ivyrep’) } group='com.zenika.gradledemos' > gradle uploadArchives version='1.0' status='release' uploadArchives { repositories { add(repositories.ivyrep) } } Repository Ivy distant Artifacts + meta Ivy ToursJUG - Présentation Gradle 32
  • 33.
    apply plugin:'java' apply plugin:'maven' Maven Ant group='test' Tasks version='1.0-SNAPSHOT' uploadArchives { repositories { mavenDeployer { repository( > gradle > gradle install uploadArchives url: remoteRepo) } } } Repository Repository Maven Maven Local Artifacts + distant Artifacts + meta Maven meta Maven ToursJUG - Présentation Gradle 33
  • 34.
    • Gestion avancée d'unmulti projet • Utilisation d'un cache • Exécution parallèle des tests • Build daemon ToursJUG - Présentation Gradle 34
  • 35.
    // settings.gradle shared include 'api', 'shared', 'services:webservices' webservices api // root build.gradle subprojects { api > gradle buildNeeded apply plugin: 'java' :shared:jar } :api:jar project(':api') { :api:test dependencies { :shared:test compile project(':shared') } } api > gradle buildDependents :shared:jar :api:jar // webservices/build.gradle apply plugin:'war' :api:test :webservices:war dependencies { :webservices:test compile project(':shared'), project(':api'), api > gradle jar –-no-rebuild 'commons-io:commons-io:1.2' api:jar } ToursJUG - Présentation Gradle 35
  • 36.
    1.  Le scriptGradle est compilé uniquement en cas de changement 2.  Détection 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 ToursJUG - Présentation Gradle 36
  • 37.
    class GenerateSchemaType extendsDefaultTask { String depsPath @InputFiles SourceDirectorySet inputXsdDirs @OutputDirectory File outputFile > gradle build :generateTask UP-TO-DATE @TaskAction :compileGeneratedJava UP-TO-DATE void generate() { :processGeneratedResources UP-TO-DATE ant { ...} :generatedClasses UP-TO-DATE } :compileJava UP-TO-DATE } ... task generateTask(type:GenerateSchemaType) { inputXsdDirs = sourceSets.main.resources outputFile = generatedSources depsPath = configurations.jaxb.asPath } ToursJUG - Présentation Gradle 37
  • 38.
    EXECUTION Process 1 Process 6 TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST CLASS CLASS CLASS CLASS CLASS CLASS CLASS CLASS CLASS CLASS PARALLELISATION Process 2 Process 7 TEST TEST TEST TEST TEST TEST TEST CLASS CLASS CLASS CLASS CLASS CLASS CLASS Process 3 TEST TEST TEST TEST TEST CLASS CLASS CLASS CLASS CLASS apply plugin:'java' Process 4 TEST TEST TEST TEST TEST CLASS CLASS CLASS CLASS CLASS test { forkEvery = 5 maxParallelForks = 4 } ToursJUG - Présentation Gradle 38
  • 39.
    •  Utilisation d'unprocessus parallèle pour éviter le cout de lancement > gradle build ... Total time: 3s > gradle build –daemon ... Total time: 3s > gradle build ... Total time: 1s •  Va favoriser l'intégration de Gradle avec Gradle UI et les IDE (Eclipse, IDEA, ...) ToursJUG - Présentation Gradle 39
  • 40.
    IDE Maturité NetBeans Eclipse + IntelliJ ++ ToursJUG - Présentation Gradle 40
  • 41.
  • 42.
    gmock security spock integration 4 ToursJUG - Présentation Gradle 42
  • 43.
    •  Mailing Listtrès active •  User guide très riche (300 pages) •  Nombreuses contributions de plugins •  Le nombre d'articles et de conférences sur le sujet augmentent ToursJUG - Présentation Gradle 43
  • 44.
    •  Fourniture deconsulting et de formation ToursJUG - Présentation Gradle 44
  • 45.
  • 46.
    •  Introduction demodèles de JVM basés sur la nature des applications •  Amélioration du DSL du graphe des tâches •  Réutilisation possible des plugins Maven •  Un livre en préparation •  Une communauté plus large ToursJUG - Présentation Gradle 46
  • 47.
  • 48.
    • Essayez-le ! • Utilisez-le ! • Faitesdu buzz! ToursJUG - Présentation Gradle 48