Save 37% off PRO during our Black Friday Sale! »

Gradle ne fait pas que remplacer Maven

Gradle ne fait pas que remplacer Maven

Présentation sur Gradle comparé à Maven, réalisée pour Devoxx France

F929f5d80ef8a23b67ad8ac6f08416cd?s=128

Cédric Champeau

April 17, 2014
Tweet

Transcript

  1. @CedricChampeau #gradle Gradle ne fait pas que remplacer Maven @CedricChampeau

    Pivotal, http://melix.github.io/blog Groovy core developer
  2. @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
  3. @CedricChampeau #gradle Qui suis-je ?

  4. @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
  5. @CedricChampeau #gradle Plan •Qu'est-ce que Maven (rapidement) ? •Qu'est-ce que

    Gradle ? –Avec un seul « d » •Pourquoi vous ne reviendrez pas à Maven
  6. @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...
  7. @CedricChampeau #gradle Maven 1, 2, 3, … 4 ? Takari

    ? https://github.com/takari/maven-polyglot
  8. @CedricChampeau #gradle Qu'est-ce que Gradle ?

  9. @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 }
  10. @CedricChampeau #gradle Qu'est-ce que Gradle ?

  11. @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
  12. @CedricChampeau #gradle pom.xml •Descripteur de la build •Monolithique •1 pom

    = 1 artéfact •Mais sert aussi au déploiement ! Leaking abstraction !
  13. @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" } } }
  14. @CedricChampeau #gradle Gradle est polyglotte •Java •Groovy •Scala •C++ •Clojure

    •Golo •Kotlin •R •Javascript •...
  15. @CedricChampeau #gradle Maven : produire un jar des sources <plugin>

    <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-source-plugin</artifactId> <executions> <execution> <id>attach-sources</id> <goals> <goal>jar</goal> </goals> </execution> </executions> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-source-plugin</artifactId> <executions> <execution> <id>attach-sources</id> <goals> <goal>jar</goal> </goals> </execution> </executions> </plugin>
  16. @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 }
  17. @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 }
  18. @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 }
  19. @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 } }
  20. @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 }
  21. @CedricChampeau #gradle Gradle est-il lent ?

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

  23. @CedricChampeau #gradle Builds incrémentales •Dites adieu à mvn clean test

    •Gestion déclarative des entrées/sorties •Prise en compte dans le parallélisme
  24. @CedricChampeau @CedricChampeau #gradle D em o

  25. @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' } } }
  26. @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 } } }
  27. @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" } } }
  28. @CedricChampeau #gradle DevOps •Tests unitaires : ok / ok •Tests

    d'intégration : ok / bof •Tests fonctionnels : ok / oups •Provisionning ?
  29. @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 •...
  30. @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 }
  31. @CedricChampeau #DVXFR14{session hashtag} @CedricChampeau #gradle Ressources

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

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

  34. @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