Slide 1

Slide 1 text

@CedricChampeau #gradle Gradle ne fait pas que remplacer Maven @CedricChampeau Pivotal, http://melix.github.io/blog Groovy core developer

Slide 2

Slide 2 text

@CedricChampeau #gradle Qui suis-je ? •Développeur Groovy Core •Fonctionnalités avancées de scripting •Type checker et compilateur statique (Groovy 2) •Traits (Groovy 2.3) •Bugfixes... •Employé par Pivotal •https://github.com/melix

Slide 3

Slide 3 text

@CedricChampeau #gradle Qui suis-je ?

Slide 4

Slide 4 text

@CedricChampeau #gradle Pub ! A voir aussi •B.O.F : La planète Groovy –Ce soir, 19h30-20h30, Auditorium –G. Laforge, C. Champeau •Groovy en 2014 et au-delà –Vendredi, 17h-17h50, Seine B –G. Laforge

Slide 5

Slide 5 text

@CedricChampeau #gradle Plan •Qu'est-ce que Maven (rapidement) ? •Qu'est-ce que Gradle ? –Avec un seul « d » •Pourquoi vous ne reviendrez pas à Maven

Slide 6

Slide 6 text

@CedricChampeau #gradle Qu'est-ce que Maven ? •Structurateur de builds •Inventeur du « convention over configuration » •Lifecycle •Gestion de dépendances •Des centaines (milliers ? millions?) de plugins •Idées très arrêtées sur tout –Y compris les contributions externes...

Slide 7

Slide 7 text

@CedricChampeau #gradle Maven 1, 2, 3, … 4 ? Takari ? https://github.com/takari/maven-polyglot

Slide 8

Slide 8 text

@CedricChampeau #gradle Qu'est-ce que Gradle ?

Slide 9

Slide 9 text

@CedricChampeau #gradle Qu'est-ce que Gradle ? apply plugin:'java' // projet Java repositories { mavenCentral() // si dépendances vers des libs central } dependencies { testCompile "junit:junit:4.11" // on utilise JUnit pour les tests } apply plugin:'java' // projet Java repositories { mavenCentral() // si dépendances vers des libs central } dependencies { testCompile "junit:junit:4.11" // on utilise JUnit pour les tests }

Slide 10

Slide 10 text

@CedricChampeau #gradle Qu'est-ce que Gradle ?

Slide 11

Slide 11 text

@CedricChampeau #gradle Qu'est-ce que Gradle ? •Convention over configuration •Conventions over configuration •API riche •Modèle accessible durant la build •Ne pas mettre de bâtons dans les roues

Slide 12

Slide 12 text

@CedricChampeau #gradle pom.xml •Descripteur de la build •Monolithique •1 pom = 1 artéfact •Mais sert aussi au déploiement ! Leaking abstraction !

Slide 13

Slide 13 text

@CedricChampeau #gradle Gradle : convention over configuration android { compileSdkVersion 15 flavorGroups "abi", "version" productFlavors { arm { flavorGroup "abi" } x86 { flavorGroup "abi" } free { flavorGroup "version" packageName = "com.android.tests.flavored.free" versionName = "2.0.0-free" } paid { flavorGroup "version" packageName = "com.android.tests.flavored.paid" versionName = "1.0.0-paid" } } } android { compileSdkVersion 15 flavorGroups "abi", "version" productFlavors { arm { flavorGroup "abi" } x86 { flavorGroup "abi" } free { flavorGroup "version" packageName = "com.android.tests.flavored.free" versionName = "2.0.0-free" } paid { flavorGroup "version" packageName = "com.android.tests.flavored.paid" versionName = "1.0.0-paid" } } }

Slide 14

Slide 14 text

@CedricChampeau #gradle Gradle est polyglotte •Java •Groovy •Scala •C++ •Clojure •Golo •Kotlin •R •Javascript •...

Slide 15

Slide 15 text

@CedricChampeau #gradle Maven : produire un jar des sources org.apache.maven.plugins maven-source-plugin attach-sources jar org.apache.maven.plugins maven-source-plugin attach-sources jar

Slide 16

Slide 16 text

@CedricChampeau #gradle Gradle : produire un jar des sources task sourceJar(type: Jar) { classifier = 'sources' from sourceSets.main.allSource } task sourceJar(type: Jar) { classifier = 'sources' from sourceSets.main.allSource }

Slide 17

Slide 17 text

@CedricChampeau #gradle Gradle : produire un jar des sources task sourceJar(type: Jar) { classifier = 'sources' from sourceSets.main.allSource } task testSourceJar(type: Jar) { classifier = 'test-sources' from sourceSets.test.allSource } task sourceJar(type: Jar) { classifier = 'sources' from sourceSets.main.allSource } task testSourceJar(type: Jar) { classifier = 'test-sources' from sourceSets.test.allSource }

Slide 18

Slide 18 text

@CedricChampeau #gradle Gradle : produire un jar des sources task sourceJar(type: Jar) { classifier = 'sources' from sourceSets.main.allSource } task testSourceJar(type: Jar) { classifier = 'test-sources' from sourceSets.test.allSource } task integTestSourceJar(type: Jar) { classifier = 'integtest-sources' from sourceSets.integTest.allSource } task sourceJar(type: Jar) { classifier = 'sources' from sourceSets.main.allSource } task testSourceJar(type: Jar) { classifier = 'test-sources' from sourceSets.test.allSource } task integTestSourceJar(type: Jar) { classifier = 'integtest-sources' from sourceSets.integTest.allSource }

Slide 19

Slide 19 text

@CedricChampeau #gradle Gradle : produire un jar des sources sourceSets.each { set -> task "source${set.name}Jar"(type:Jar) { classifier = 'sources' if (set.name!='main') { classifier = "${set.name.toLowerCase()}-sources" } from set.allSource } } sourceSets.each { set -> task "source${set.name}Jar"(type:Jar) { classifier = 'sources' if (set.name!='main') { classifier = "${set.name.toLowerCase()}-sources" } from set.allSource } }

Slide 20

Slide 20 text

@CedricChampeau #gradle Gradle : produire un jar des sources sourceSets { integTest { java.srcDir file('src/integration-test/java') resources.srcDir file('src/integration-test/resources') compileClasspath += main.output + test.output runtimeClasspath += main.output + test.output } } configurations { integTestCompile.extendsFrom testCompile integTestRuntime.extendsFrom testRuntime } sourceSets { integTest { java.srcDir file('src/integration-test/java') resources.srcDir file('src/integration-test/resources') compileClasspath += main.output + test.output runtimeClasspath += main.output + test.output } } configurations { integTestCompile.extendsFrom testCompile integTestRuntime.extendsFrom testRuntime }

Slide 21

Slide 21 text

@CedricChampeau #gradle Gradle est-il lent ?

Slide 22

Slide 22 text

@CedricChampeau #DVXFR14{session hashtag} @CedricChampeau #gradle N o return

Slide 23

Slide 23 text

@CedricChampeau #gradle Builds incrémentales •Dites adieu à mvn clean test •Gestion déclarative des entrées/sorties •Prise en compte dans le parallélisme

Slide 24

Slide 24 text

@CedricChampeau @CedricChampeau #gradle D em o

Slide 25

Slide 25 text

@CedricChampeau #gradle Résolution de dépendances // forcer une version, même pour dépendances transitives... configurations.all { resolutionStrategy.eachDependency { details -> if (details.requested.group == 'org.hibernate') { details.useVersion '3.5.4-Final' } } } // forcer une version, même pour dépendances transitives... configurations.all { resolutionStrategy.eachDependency { details -> if (details.requested.group == 'org.hibernate') { details.useVersion '3.5.4-Final' } } }

Slide 26

Slide 26 text

@CedricChampeau #gradle Résolution de dépendances // rechercher un numéro de version validé configurations.all { resolutionStrategy.eachDependency { details -> if (details.requested.version == 'default') { def version = findDefaultVersionInCatalog(details.requested.group, details.requested.name) details.useVersion version } } } // rechercher un numéro de version validé configurations.all { resolutionStrategy.eachDependency { details -> if (details.requested.version == 'default') { def version = findDefaultVersionInCatalog(details.requested.group, details.requested.name) details.useVersion version } } }

Slide 27

Slide 27 text

@CedricChampeau #gradle Résolution de dépendances // remplacer log4j par slf4j configurations.all { resolutionStrategy.eachDependency { details -> if (details.requested.name == 'log4j') { details.useTarget "org.slf4j:log4j-over-slf4j:1.7.5" } } } // remplacer log4j par slf4j configurations.all { resolutionStrategy.eachDependency { details -> if (details.requested.name == 'log4j') { details.useTarget "org.slf4j:log4j-over-slf4j:1.7.5" } } }

Slide 28

Slide 28 text

@CedricChampeau #gradle DevOps •Tests unitaires : ok / ok •Tests d'intégration : ok / bof •Tests fonctionnels : ok / oups •Provisionning ?

Slide 29

Slide 29 text

@CedricChampeau #gradle DevOps : plugins • Vagrant : https://github.com/bmuschko/gradle-vagrant-plugin • Docker : https://github.com/Transmode/gradle-docker • Provisionning (Amazon, VirtualBox): https://github.com/danveloper/provisioning-gradle-plugin • Sshoogr : https://github.com/aestasit/sshoogr-gradle •...

Slide 30

Slide 30 text

@CedricChampeau #gradle Gradle : exemple Vagrant vagrant { boxDir = file('~/dev/my-vagrant-box') environmentVariables { variable 'IP', '192.168.1.33' variable 'OPERATINGSYSTEM', 'redhat' } } task vagrantEcho(type: VagrantSsh) { description = 'Runs remote SSH command in Vagrant box.' sshCommand = "echo 'hello'" dependsOn vagrantUp finalizedBy vagrantDestroy } vagrant { boxDir = file('~/dev/my-vagrant-box') environmentVariables { variable 'IP', '192.168.1.33' variable 'OPERATINGSYSTEM', 'redhat' } } task vagrantEcho(type: VagrantSsh) { description = 'Runs remote SSH command in Vagrant box.' sshCommand = "echo 'hello'" dependsOn vagrantUp finalizedBy vagrantDestroy }

Slide 31

Slide 31 text

@CedricChampeau #DVXFR14{session hashtag} @CedricChampeau #gradle Ressources

Slide 32

Slide 32 text

@CedricChampeau #gradle Resources •Docs : http://gradle.org •Gradleware : http://www.gradleware.com

Slide 33

Slide 33 text

@CedricChampeau #DVXFR14{session hashtag} @CedricChampeau #gradle Q & A

Slide 34

Slide 34 text

@CedricChampeau #gradle Crédit image / Creative Commons • Rue pavée — By-Nc-Sa •http://www.flickr.com/photos/22914687@N05/4957591422/sizes/l/ • Sous la Tour Eiffel — By-Nc-Sa •http://www.flickr.com/photos/stewiedewie/244850735/sizes/l/in/photostream/ • Sous le pont — photo par B.Monginoux - By-Nc-Nd •http://www.landscape-photo.net/displayimage.php?pid=5194 • Le Louvre – Photo par Anthony Gaudun - By-Nc-Sa •http://www.flickr.com/photos/anthonygaudun/7474397964/sizes/o/in/photostream/ • Slide template created by @glaforge, completed by @nmartignole for Devoxx FR2014