Gradle, je t'aime, moi non plus…

Gradle, je t'aime, moi non plus…

Slides de notre talk avec @dwursteisen à Devoxx FR 2019.

05dd369062f7c4e450e1e08d1471da5b?s=128

Jeremie Martinez

April 19, 2019
Tweet

Transcript

  1. Gradle, je t’aime, 
 … moi non plus @JeremMartinez -

    @dwursteisen
  2. None
  3. David Wursteisen Jeremie Martinez

  4. Satisfait de votre banque ?

  5. Une banque pour entreprise

  6. Nous construisons notre propre CBS.

  7. Nous construisons notre propre Core Banking System.

  8. Data Payments Backend Core

  9. Data Payments Backend Core Created Deposited Withdraw Withdraw Closed WRITE

    Event store Reporting Accounting Regulators Data sciences GDPR Users Transfers Customers Collections Cards KYC Limit controller
  10. Un outil de build est comme une banque. On ne

    choisit pas le meilleur mais le moins pire. Un outil de build est comme une banque. On ne choisit pas le meilleur mais le moins pire.
  11. Choix de l’outil de build : 2017 Choix de l’outil

    de build : 2017
  12. Bazel Buck

  13. Construction incrementale DSL en Groovy Dynamisme du produit

  14. Système à base de tâche.

  15. Tâche Entrée Sortie

  16. Assemble

  17. Jar Assemble

  18. Compile Jar Assemble

  19. Compile Jar Assemble

  20. Compile Jar Assemble Compile [ Up-to-date ] [ Up-to-date ]

    [ Up-to-date ] Jar Assemble
  21. On ne construit que le nécessaire. On ne construit que

    le nécessaire.
  22. Développeur Mainteneur de scripts Build master 1 2 3

  23. Développeur Mainteneur de scripts Build master 1

  24. Support IDE.

  25. None
  26. None
  27. None
  28. None
  29. None
  30. Gradle Wrapper.

  31. None
  32. distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists distributionUrl=https://services.gradle.org/distributions/gradle-5.3-bin.zip

  33. distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists distributionUrl=https://services.gradle.org/distributions/gradle-5.3-bin.zip

  34. distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists distributionUrl=https://internal/gradle/gradle/gradle/5.3/gradle-5.3-bin.zip

  35. distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists distributionUrl=https://internal/gradle/gradle/gradle/5.3/gradle-5.3-bin.zip distributionSha256Sum=53b71812f18cdb2777e9f1b2a0f2038683907c90bdc406bc6

  36. distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists distributionUrl=https://internal/gradle/gradle/gradle/5.3/gradle-5.3-bin.zip distributionSha256Sum=53b71812f18cdb2777e9f1b2a0f2038683907c90bdc406bc6

  37. distributionhttps://internal/gradle/gradle/gradle/5.3/gradle-5.3-bin.zip distributionSha256Sum=53b71812f18cdb2777e9f1b2a0f2038683907c90bdc406bc6 Ne sont pas des variables d’environment valides !

  38. None
  39. 4 Go =

  40. Gestion des dépendances

  41. src main module kotlin test kotlin resources custom kotlin

  42. dependencies { }

  43. dependencies { compile("io.swagger:swagger-annotations:1.5.0") }

  44. dependencies { compile("io.swagger:swagger-annotations:1.5.0") compile(group = "io.swagger", name = "swagger-annotations", version

    = "1.5.0") }
  45. dependencies { compile("io.swagger:swagger-annotations:1.5.0") compile(group = "io.swagger", name = "swagger-annotations", version

    = "1.5.0") compile(project(":otherProject")) }
  46. dependencies { compile("io.swagger:swagger-annotations:1.5.0") compile(group = "io.swagger", name = "swagger-annotations", version

    = "1.5.0") compile(project(":otherProject")) testCompile("io.mockk:mockk:1.9.3") }
  47. dependencies { compile("io.swagger:swagger-annotations:1.5.0") compile(group = "io.swagger", name = "swagger-annotations", version

    = "1.5.0") compile(project(":otherProject")) testCompile("io.mockk:mockk:1.9.3") customCompile("org.codehaus.janino:janino:2.5.16") }
  48. customCompile("org.codehaus.janino:janino:2.5.16") sourceSet configuration

  49. compile("org.codehaus.janino:janino:2.5.16") compileOnly("org.codehaus.janino:janino:2.5.16") runtime("org.codehaus.janino:janino:2.5.16") annotationProcessor("org.codehaus.janino:janino:2.5.16")

  50. compile("org.codehaus.janino:janino:2.5.16") compileOnly("org.codehaus.janino:janino:2.5.16") runtime("org.codehaus.janino:janino:2.5.16") annotationProcessor("org.codehaus.janino:janino:2.5.16")

  51. compile("org.codehaus.janino:janino:2.5.16") compileOnly("org.codehaus.janino:janino:2.5.16") runtime("org.codehaus.janino:janino:2.5.16") annotationProcessor("org.codehaus.janino:janino:2.5.16") runtimeOnly("org.codehaus.janino:janino:2.5.16") api("org.codehaus.janino:janino:2.5.16") implementation("org.codehaus.janino:janino:2.5.16")

  52. runtimeOnly("org.codehaus.janino:janino:2.5.16") api("org.codehaus.janino:janino:2.5.16") implementation("org.codehaus.janino:janino:2.5.16")

  53. mailer-service mailer-api amazing-mail com.lib.mailer.api com.lib.mailer.impl MailerService MailerApi webapp fr.amazing.client ClientMail

  54. mailer-service mailer-api amazing-mail com.lib.mailer.api com.lib.mailer.impl MailerService MailerApi webapp fr.amazing.client ClientMail

    compilation compilation compilation est visible est visible
  55. implementation api implementation mailer-service mailer-api amazing-mail com.lib.mailer.api com.lib.mailer.impl MailerService MailerApi

    webapp fr.amazing.client ClientMail est visible est visible
  56. Repositories.

  57. repositories { }

  58. repositories { mavenCentral() }

  59. repositories { mavenCentral() jcenter() google() }

  60. repositories { mavenCentral() jcenter() google() maven { url = uri("https://oss.sonatype.org/content/repositories/snapshots/")

    } }
  61. repositories { mavenCentral() jcenter() google() maven { url = uri("https://oss.sonatype.org/content/repositories/snapshots/")

    } maven { url = uri("https://internal") content { includeGroupByRegex("com\\.mycompany.*") } } } Selection des dépendances
  62. repositories { mavenCentral() jcenter() google() maven { url = uri("https://oss.sonatype.org/content/repositories/snapshots/")

    } maven { url = uri("https://internal") content { includeGroupByRegex("com\\.mycompany.*") } } ivy { url = uri("https://oss.sonatype.org/content/repositories/releases/") } flatDir { dirs("libs") } }
  63. repositories { mavenCentral() jcenter() google() maven { url = uri("https://oss.sonatype.org/content/repositories/snapshots/")

    } maven { url = uri("https://internal") content { includeGroupByRegex("com\\.mycompany.*") } } ivy { url = uri("https://oss.sonatype.org/content/repositories/releases/") } flatDir { dirs("libs") } mavenLocal() } Devrait être inutile
  64. projectA projectB mavenLocal publishToMavenLocal Dépend de…

  65. Composite Build.

  66. projectA projectB compositeBuild includeBuild(…)

  67. projectA projectB dependencySource gitRepository(https://github.com/…) version = branch/tag

  68. mailer 1.0.0 Master dev/feature superProject otherProject projectZ

  69. mailer 1.0.0 Master dev/feature superProject OK otherProject OK projectZ OK

  70. mailer 1.0.0 master superProject OK OK otherProject OK OK projectZ

    OK KO Dependency sources
  71. mailer 1.0.0 master dev/feature superProject OK OK KO otherProject OK

    OK OK projectZ OK KO OK Dependency sources Dependency sources
  72. Performance.

  73. None
  74. org.gradle.caching=true org.gradle.configureondemand=true org.gradle.jvmargs=-Xmx2048M -Xms2048M org.gradle.parallel=true Réutilisation des résultats de build

    Execution des tâches en parallèle Utilisation d’un maximum de mémoire Configuration uniquement des tâches nécessaires
  75. None
  76. Daemon Gradle 5.1.1 Daemon Gradle 4.10

  77. None
  78. None
  79. Simplicité d’utilisation Performance Fonctionnalités

  80. Développeur Mainteneur de scripts Build master 2

  81. Data Payments Backend Core Created Deposited Withdraw Withdraw Closed WRITE

    Event store Reporting Accounting Regulators Data sciences GDPR Users Transfers Customers Collections Cards KYC Limit controller
  82. Data Payments Backend Reporting Accounting Regulators Data sciences GDPR Users

    Transfers Customers Collections Cards KYC Limit controller
  83. Backend GDPR Users Customers KYC Limit controller kotlin nexus release

    lint Configuration
  84. Plugin interne.

  85. apply(plugin = "com.your.company.commons")

  86. None
  87. Configurer une seule fois, Exécuter partout.

  88. buildSrc.

  89. None
  90. None
  91. None
  92. None
  93. src main buildSrc kotlin myProject

  94. open class MyExtension(var yourName: String = "not defined!")

  95. open class MyExtension(var yourName: String = "not defined!") class MyPlugin

    : Plugin<Project> { override fun apply(project: Project) { } }
  96. open class MyExtension(var yourName: String = "not defined!") class MyPlugin

    : Plugin<Project> { override fun apply(project: Project) { val exts = project.extensions.create("myPlugin", MyExtension::class) } }
  97. open class MyExtension(var yourName: String = "not defined!") class MyPlugin

    : Plugin<Project> { override fun apply(project: Project) { val exts = project.extensions.create("myPlugin", MyExtension::class) project.task("myTask") { doLast { println("hello ${exts.yourName}") } } } }
  98. apply<MyPlugin>() configure<MyExtension> { yourName = "Devoxx France" }

  99. None
  100. DSL.

  101. Groovy DSL.

  102. sourceSets { } Groovy

  103. sourceSets { integrationTest { } } DSL Dynamique Groovy

  104. None
  105. Type safety IDE Support Navigation Refactoring

  106. sourceSets { integrationTest { } } Groovy

  107. sourceSets.create("integrationTest") { … } Kotlin

  108. None
  109. None
  110. None
  111. idea { project { settings { runConfigurations { "Start Application"(Application)

    { // … } } } } } Groovy
  112. idea { project { this as ExtensionAware configure<ProjectSettings> { this

    as ExtensionAware configure<NamedDomainObjectContainer<RunConfiguration>> { // cast to PolymorphicDomainObjectContainer to access the create method used bellow. @Suppress("UnstableApiUsage") this as PolymorphicDomainObjectContainer<RunConfiguration> create("Start Application", Application::class) { // … } } } } } Kotlin
  113. « Un langage pour les gouverner tous. »

  114. Migration vers Kotlin DSL.

  115. object Versions { val assertj = "3.10.0" val junit =

    "4.12" val mockito = "2.19.1" val mockito_kotlin = "1.6.0" val postgres = "42.2.4" val prometheus = "0.6.0" val springboot = "2.1.3.RELEASE" val swagger = "1.5.20" }
  116. object TestDeps { val assertj = "org.assertj:assertj-core:${Versions.assertj}" val junit =

    "junit:junit:${Versions.junit}" val mockito = "org.mockito:mockito-core:${Versions.mockito}" }
  117. dependencies { testImplementation(TestDeps.assertj) testImplementation(TestDeps.junit) testImplementation(TestDeps.mockito) }

  118. 1. Doublez vos quotes.

  119. allprojects { group = 'com.margo.backend' version = '1.0' } Groovy

  120. allprojects { group = 'com.margo.backend' version = '1.0' } Groovy

  121. allprojects { group = "com.margo.backend" version = "1.0" } Kotlin

  122. 2. Explicitez vos assignations.

  123. repositories { maven { url 'https://plugins.gradle.org/m2/' } } Groovy

  124. repositories { maven { url = uri("https://plugins.gradle.org/m2/") } } Kotlin

  125. dependencies { compile project(":service") } Groovy

  126. dependencies { compile(project(":service")) } Kotlin

  127. val commit by extra { Git.commit() } Kotlin

  128. object Git { fun commit() = Runtime.getRuntime() .exec("git rev-parse --short

    HEAD") .inputStream.bufferedReader() .readText() } buildSrc
  129. 3. Fichier par fichier.

  130. web buildSrc src build.gradle settings.gradle build.gradle src build.gradle

  131. build.gradle.kts web buildSrc src settings.gradle build.gradle src build.gradle

  132. settings.gradle.kts build.gradle.kts web buildSrc src build.gradle src build.gradle

  133. build.gradle.kts settings.gradle.kts build.gradle.kts web buildSrc src src build.gradle

  134. web buildSrc src build.gradle.kts settings.gradle.kts build.gradle.kts src build.gradle.kts

  135. Quelques difficultés.

  136. 1. Documentation.

  137. None
  138. 2. Exemples.

  139. None
  140. None
  141. 3. Utilisation avancée.

  142. processResources { filesMatching('**/*.properties') { expand(project.properties) } } Groovy

  143. tasks .withType(ProcessResources::class) .named("processResources") .configure { filesMatching("**/*.properties") { expand(project.properties) } }

    Kotlin
  144. tasks .withType(ProcessResources::class) .named("processResources") .configure { filesMatching("**/*.properties") { expand(project.properties) } }

    Kotlin
  145. tasks .withType(ProcessResources::class) .named("processResources") .configure { filesMatching("**/*.properties") { expand(project.properties) } }

    Kotlin
  146. tasks .withType(ProcessResources::class) .named("processResources") .configure { filesMatching("**/*.properties") { expand(project.properties) } }

    Kotlin
  147. tasks .withType(ProcessResources::class) .named("processResources") .configure { filesMatching("**/*.properties") { expand(project.properties) } }

    Kotlin
  148. tasks .withType(ProcessResources::class) .named("processResources") .configure { filesMatching("**/*.properties") { expand(project.properties) } }

    Kotlin
  149. 4. Migration du plugin interne.

  150. Si c’était à refaire ?

  151. buildSrc Performance Plugin interne IDE Support

  152. Prochaines étapes. Consommation mémoire Build cache

  153. Questions ?