Publicité
Publicité

Contenu connexe

Publicité
Publicité

Gradle_LyonJUG

  1. GRADLE Gregory BOISSINOT 23/11/2010 Lyon JUG - Présentation Gradle 1
  2. •  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 • ntroduction et déploiement de Gradle à grande échelle I •  Commiter Hudson – Intégration des châines de build Java (Gradle), C/C++, ADA Lyon JUG - Présentation Gradle 2
  3. INTERNET Lyon JUG - Présentation Gradle 3
  4. •  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^ .... Lyon JUG - Présentation Gradle 4
  5. •  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 Lyon JUG - Présentation Gradle 5
  6. 1ère génération 2ème génération 3ème génération 2000 2005 2008 2008 2001 3 2 1 Lyon JUG - 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') } Lyon JUG - Présentation Gradle 7
  8. •  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 Lyon JUG - Présentation Gradle 8
  9. •  Spécification du 'quoi' et pas du 'comment' Même ntion apply plugin:'java' > gradle clean build conve en av :clean que M repositories { :compileJava src mavenCentral() :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 Lyon JUG - Présentation Gradle 9
  10. 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 Lyon JUG - Présentation Gradle 10
  11. Écrire un script Gradle consiste à configurer un objet Project configurations build.gradle repositories dependencies Project ant Eléments task personnalisés artifacts API Lyon JUG - Présentation Gradle 11
  12. •  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 Lyon JUG - Présentation Gradle 12
  13. Possibilité d'écrire du code Java/Groovy sous forme d'unités réutilisables <!-- build.gradle --> task(boucleTask).doFirst{ for (int i:[1,2,3]){ print i } > gradle boucleTask } :boucleTask 123 void printMessage(String message){ println "Print " + message > gradle distribution } :distribution Print Distribution task(distribution).doFirst { > gradle release printMessage("Distribution") :distribution } Print Distribution :release task(release) Print Release release.dependsOn(distribution) release.doFirst{ println "Print Release" } Lyon JUG - Présentation Gradle 13
  14. task mycopy (type:Copy){ description ='Copies the resources dir' from(file('resources')) ConventionTask into(file('target')) include('**/*.txt', '**/*.xml') } SourceTask AbstractCopyTask Javadoc Copy AbstractArchiveTask Zip Tar public class Copy extends AbstractCopyTask { public AbstractCopyTask from(Object... sourcePaths); public AbstractCopyTask into(Object destDir); public AbstractCopyTask include(String... includes); . . . Jar } War Lyon JUG - Présentation Gradle 14
  15. <!– HelloTask.groovy --> class HelloTask extends DefaultTask { def message="Default Message" @TaskAction public void print(){ > gradle myhello println message :myhello } Default Message } > gradle myhello2 :myhello2 <!-- build.gradle --> Task Message task(myhello, type:HelloTask) task(myhello2, type:HelloTask){ message="Task Message" } Lyon JUG - Présentation Gradle 15
  16. • Les plugins Gradle • Insertion dans un environnement agile Lyon JUG - Présentation Gradle 16
  17. Chaque plugin - est un ensemble de tâches - expose un objet Java convention Plugins maven Java Configuration Object eclipse idea Jetty Configuration War Configuration Object Object code-quality war … … projects-reports java … jetty osgi scala Project Configuration Lyon JUG - Présentation Gradle 17
  18. Mise à disposition config-1.0.gradle <!– build.gradle --> task config { ... } Utilisation <!– build.gradle --> > gradle config apply from "http://repomanager/config-1.0.gradle" ... ... Lyon JUG - Présentation Gradle 18
  19. Lyon JUG - Présentation Gradle 19
  20. •  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 mettre en place des exclusions globales •  Possibilité de définir les dépendances transitives dans le script Gradle dependencies { runtime module("org.codehaus.groovy:groovy-all:1.7.5") { dependency("commons-cli:commons-cli:1.0") { transitive = false } } } Lyon JUG - Présentation Gradle 20
  21. apply plugin:'java' > gradle build –PskipTests processResources.enabled=false :compileJava :processResources SKIPPED :classes test.onlyIf{ :preJar !project.hasProperty('skipTests')} :jar :war //Add behavior in the lifecycle :assemble task(preJar) :compileTestJava jar.dependsOn preJar :processTestResources :testClasses //Change the output directory :test SKIPPED :check buildDirName='target' :build //Change the source directory BUILD SUCCESSFUL sourceSets{ main{ java.srcDirs file('src/java'), file('src/java2') } } Lyon JUG - Présentation Gradle 21
  22. apply plugin:'java' > gradle clean build :clean sourceSets{ :generateTask . . . myGenSourceSet { :compileMyGenSourceSetJava java { :processMyGenSourceSetResources srcDir 'build/generated' :myGenSourceSetClasses } . . . } } Lyon JUG - Présentation Gradle 22
  23. > gradle clean build sourceSets{ :clean myGenSourceSet { :generateTask java { :compileMyGenSourceSetJava srcDir 'build/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 } Lyon JUG - Présentation Gradle 23
  24. CONFIGURATION PHASE t1 t2 t3 t1 t2 t3 EXECUTION PHASE GRADLE t4 t4 HOOK SCRIPT Project Project Engine Convention 1 Convention 2 gradle –-properties version = 1.0 gradle –-tasks gradle.taskGraph.whenReady { taskGraph -> gradle –-dependencies if (! taskGraph.hasTask(':release')){ gradle –-dry-run build version+='-SNAPSHOT' } } // Other hooks gradle.taskGraph.beforeTask { task -> .. . gradle.beforeProject { project -> .. . ... Lyon JUG - Présentation Gradle 24
  25. 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() } } Lyon JUG - Présentation Gradle 25
  26. 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()) > } } Lyon JUG - Présentation Gradle 26
  27. Lyon JUG - Présentation Gradle 27
  28. 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") } } } Lyon JUG - Présentation Gradle 28
  29. build.xml <project> <target name="antTask"> <echo message="Hello from Ant"/> </target> </project> build.gradle ant.importBuild('build.xml') antTask.doLast { println('Hello from Gradle') } > gradle antTask :antTask Hello from Ant Hello from Gradle Lyon JUG - Présentation Gradle 29
  30. apply plugin:'java' repositories { mavenCental() flatDir(dirs:'destrepo', IVY name:'ivyrep’) } group='test' > gradle uploadArchives version='1.0' status='release' uploadArchives { repositories { add(repositories.ivyrep) } } Repository Ivy distant Artifacts + meta Ivy Lyon JUG - Présentation Gradle 30
  31. 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 Lyon JUG - Présentation Gradle 31
  32. • Gestion avancée d'un multi projet • Utilisation d'un cache • Exécution parallèle des tests • Build daemon Lyon JUG - Présentation Gradle 32
  33. // 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 } Lyon JUG - Présentation Gradle 33
  34. 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 Lyon JUG - Présentation Gradle 34
  35. 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 } Lyon JUG - Présentation Gradle 35
  36. EXECUTION Process 1 Process 6 TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST SUITE SUITE SUITE SUITE SUITE SUITE SUITE SUITE SUITE SUITE PARALLELISATION Process 2 Process 7 TEST TEST TEST TEST TEST TEST TEST SUITE SUITE SUITE SUITE SUITE SUITE SUITE Process 3 TEST TEST TEST TTEST TEST SUITE SUITE SUITE SUITE SUITE apply plugin:'java' Process 4 TEST TEST TTEST TEST TEST SUITE SUITE SUITE SUITE SUITE test { forkEvery = 5 maxParallelForks = 4 } Lyon JUG - Présentation Gradle 36
  37. •  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, ...) Lyon JUG - Présentation Gradle 37
  38. Lyon JUG - Présentation Gradle 38
  39. gmock spock security 4 Lyon JUG - Présentation Gradle 39
  40. •  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 Lyon JUG - Présentation Gradle 40
  41. Lyon JUG - Présentation Gradle 41
  42. •  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 Lyon JUG - Présentation Gradle 42
  43. Lyon JUG - Présentation Gradle 43
  44. • Essayez-le ! • Utilisez-le ! • Faites du buzz! Lyon JUG - Présentation Gradle 44
  45. Merci Lyon JUG - Présentation Gradle 45
Publicité