Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Gradle: the good parts

216 views

Published on

Gradle has evolved quite a lot since its inception. It is a well-recognized build tool in the JVM ecosystem. Many worship its power, but also many complain about its design, excessive flexibility and integration options. Let us see the good parts of Gradle (and also mention some of the not so good ones). Gradle provides great power, which should be used responsibly.

Published in: Technology
  • Be the first to comment

  • Be the first to like this

Gradle: the good parts

  1. 1. 01
  2. 2. 02
  3. 3. This talk... 03
  4. 4. ...is partially inspired by: 04
  5. 5. The path... 05
  6. 6. ...through... 06
  7. 7. ...monoliths 07
  8. 8. ...and SOA 08
  9. 9. Actually, huge monoliths 09
  10. 10. Actually, huge monoliths >300K  LOC of source code (reaching  2M  LOC) >2K  LOC of supporting code dozens of components and extra deployment configuration • • • 10
  11. 11. Before Gradle Using Maven 2 since 2005 Writing Maven plugins Advocating Maven (before 2008) • • • 11
  12. 12. The path to Gradle Active Gradle user since 2008 A slight Maven basher from 2008 till 2016 After 2016, peace maker, right­tool­for­the­job kinda guy • • • 12
  13. 13. Not just for... compiling running tests creating a JAR/WAR/EAR • • • 13
  14. 14. ... but also pubishing artifacts signing artifacts running integration tests running performance tests managing database generating non­standard artifacts • • • • • • 14
  15. 15. Non­standard artifacts Configuration data and secrets LDAP role tree based on the structure of deployed components ESB configurations generated from the service structure Monitoring dashboards generated from annotations Puppet manifests to provision environments • • • • • 15
  16. 16. The fight 16
  17. 17. Maven vs. Gradle 17
  18. 18. Maven vs. Gradle 18
  19. 19. Maven vs. Gradle 19
  20. 20. Maven vs. Gradle 20
  21. 21. Maven vs. Gradle 21
  22. 22. Maven vs. Gradle 22
  23. 23. Maven vs. Gradle 23
  24. 24. Maven vs. Gradle 24
  25. 25. Maven vs. Gradle 25
  26. 26. Maven vs. Gradle 26
  27. 27. Let's stop fighting! 27
  28. 28. Otherwise, Buck will take over... 28
  29. 29. What's in it for me? 29
  30. 30. The good 30
  31. 31. The conventions Source directory structure (was defined by Maven) Repository/dependency structure (was defined by Maven) Yes, most of them are from Maven • • • 31
  32. 32. The DSL 32
  33. 33. The API 33
  34. 34. The API Project Task Dependency Artifact SourceSet ... • • • • • • 34
  35. 35. The dependency notation group:name:version:classifier@packaging org.gradle.test.classifiers:service:1.0:jdk15@jar org.springframework:spring‐core:2.5 com.mycompany:puppet‐manifests:1.5@zip • • • • 35
  36. 36. The power of copy 36
  37. 37. The power of copy copy {   into 'build/webroot'   exclude '**/.svn/**'   from('src/main/webapp') {     include '**/*.jsp'     filter(ReplaceTokens,             tokens:[copyright:'2009', version:'2.3.1'])   } } 01. 02. 03. 04. 05. 06. 07. 08. 09. 37
  38. 38. The power of copy task copyRuntimeLibs(type: Copy) {   into "lib"   from configurations.testRuntime } 01. 02. 03. 04. 38
  39. 39. The power of copy task unzip(type: Copy) {   from zipTree(zipFile)   into "unzipped"   include "dir/to/unzip/**" } 01. 02. 03. 04. 05. 39
  40. 40. The power of copy task unzip(type: Copy) {   from zipTree(zipFile)   into "unzipped"    eachFile { FileCopyDetails fcp ‐>     ...   } } 01. 02. 03. 04. 05. 06. 07. 40
  41. 41. The power of copy https://docs.gradle.org/3.5/javadoc/ org/gradle/api/file/CopySpec.html org/gradle/api/Project.html#files(java.lang.Object...) • • 41
  42. 42. The wrapper 42
  43. 43. The wrapper gradle/wrapper/gradle‐wrapper.jar gradle/wrapper/gradle‐wrapper.properties gradlew gradlew.bat • • • • 43
  44. 44. ./gradlew and ./gradlew.bat Checks if Gradle distribution exists in user's home Downloads it if it is not there already Runs Gradle from the distrubution • • • 44
  45. 45. gradle­wrapper.properties #Sat Oct 31 22:09:32 EET 2015 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists distributionUrl=https://.../gradle‐2.7‐bin.zip 01. 02. 03. 04. 05. 06. 45
  46. 46. gdub 46
  47. 47. gdub gdub  ( gw  on the command line) is a  gradle  /  gradlew  wrapper. Not to be confused with the Gradle Wrapper,  gw  invokes  ./gradlew on projects where one is configured, and falls back to use the  gradle from the  $PATH  if a wrapper is not available. Also, gw is 66% shorter to type than  gradle  and 78% shorter to type than  ./gradlew. “ 47
  48. 48. Maven Wrapper 48
  49. 49. The continuous build49
  50. 50. The continuous build gradlew ‐t <task>01. 50
  51. 51. Demo 51
  52. 52. The incremental build52
  53. 53. Task inputs/outputs task(one) {   inputs.dir 'src'    inputs.file 'config.xml' } 01. 02. 03. 04. 53
  54. 54. Task inputs/outputs task(one) {   outputs.file 'package.par' } 01. 02. 03. 54
  55. 55. Task inputs/outputs task(one) {   outputs.upToDateWhen {     // custom code   } } 01. 02. 03. 04. 05. 55
  56. 56. Incremental Java compiler Introduced since Gradle 3.4 General moto: compilation avoidance Mechanism for up­to­date checking of Java compilation that is sensitive to public API changes only This means that if you change a comment or even a private API in a downstream project, Java compilation for upstream projects will be UP­TO­DATE • • • • 56
  57. 57. The cache Information about tasks inputs/outputs is stored inside project's .gradle  directory. Gradle distributions, downloaded libraries, compiled scripts are stored in  $USER_HOME/.gradle . • • 57
  58. 58. Using local maven cache repositories {   mavenLocal()  } 01. 02. 03. 58
  59. 59. The daemon 59
  60. 60. The daemon Can be disabled:  org.gradle.daemon=false Daemon status:  gradlew ‐‐status Different Gradle and/or Java version will trigger a new daemon • • • 60
  61. 61. The daemon 61
  62. 62. The build scan plugins {   id "com.gradle.build‐scan" version "1.7.1" } buildScan {   licenseAgreementUrl = 'https://...'   licenseAgree = 'yes' } 01. 02. 03. 04. 05. 06. 07. 62
  63. 63. The build scan gradle build ‐‐scan01. 63
  64. 64. The build scan 64
  65. 65. The composite builds gradle test ‐‐include‐build ../number‐utils01. 65
  66. 66. The built­in tasks gradle init ‐‐type java‐library gradle wrapper ‐‐gradle‐version 3.5 gradle tasks gradle dependencies gradle ‐‐status gradle ‐‐gui • • • • • • 66
  67. 67. Gradle GUI 67
  68. 68. IDE support 68
  69. 69. Sad face here :( 69
  70. 70. IDE People who prefer Maven expect their IDE to work with Maven out­of­ the­box. That's totally valid expectation. Gradle can work in that way as well now (more or less), but it wasn't the case for some time. • • 70
  71. 71. IDE POM editor usually works perfectly and it is easy to implement. Gradle editor is hard to implement and none of the IDEs actually did it well. • • 71
  72. 72. Honestly, I don't care! plugins {   id "idea"   id "eclipse" } 01. 02. 03. 04. 72
  73. 73. Honestly, I don't care! gradlew cleanIdea idea gradlew cleanEclipse eclipse • • 73
  74. 74. Intellij IDEA 74
  75. 75. Intellij IDEA 75
  76. 76. Eclipse BuildShip 76
  77. 77. Structuring the build 77
  78. 78. gradle.properties Project's local gradle.properties Override through  $USER_HOME/.gradle/gradle.properties Override through  ‐Pprop=somevalue Override through environment variables ORG_GRADLE_PROJECT_prop=somevalue • • • • 78
  79. 79. gradle.properties Custom user settings Isolating secrets from the build code CI­friendly • • • 79
  80. 80. apply from: other.gradle 80
  81. 81. Facets ./gradle/ java.gradle ide.gradle ... • • • 81
  82. 82. Writing your own plugin apply plugin: GreetingPlugin class GreetingPlugin implements Plugin<Project> {   void apply(Project project) {     project.task('hello') << {         println "Hello from the GreetingPlugin"     }   } } 01. 02. 03. 04. 05. 06. 07. 08. 82
  83. 83. buildSrc buildSrc/build.gradle buildSrc/src/main/java • • 83
  84. 84. Testing plugins 84
  85. 85. TestKit dependencies {   testCompile gradleTestKit() } 01. 02. 03. 85
  86. 86. TestKit public class BuildLogicFunctionalTest { @Test public void testHelloWorldTask() throws IOException {     String buildFileContent =           "task helloWorld {" +          "    doLast {" +          "        println 'Hello world!'" +          "    }" +          "}"; 01. 02. 03. 04. 05. 06. 07. 08. 09. 86
  87. 87. TestKit BuildResult result = GradleRunner.create()         .withProjectDir(testProjectDir.getRoot())         .withArguments("helloWorld")         .build(); 01. 02. 03. 04. 87
  88. 88. TestKit GradleRunner.withGradleVersion(java.lang.String) GradleRunner.withGradleInstallation(java.io.File) GradleRunner.withGradleDistribution(java.net.URI) 01. 02. 03. 88
  89. 89. TestKit assertTrue  (result                .getOutput()                .contains("Hello world!")); assertEquals(result                .task(":helloWorld")                .getOutcome(), SUCCESS); 01. 02. 03. 04. 05. 06. 89
  90. 90. GradleTest 90
  91. 91. GradleTest buildscript {   dependencies {     classpath "org.ysb33r.gradle:gradletest:0.5.4"   } } apply plugin : 'org.ysb33r.gradletest' 01. 02. 03. 04. 05. 06. 91
  92. 92. GradleTest gradleTest {   versions '2.0', '2.2', '2.4', '2.5', '2.9' } 01. 02. 03. 92
  93. 93. Plugins 93
  94. 94. Useful plugins license versions shadow izpack stats release bintray • • • • • • • 94
  95. 95. Useful plugins coveralls asciidoctor markdown livereload gretty nexus watch pitest • • • • • • • • 95
  96. 96. Useful plugins clirr flyway jmh osspackage sshoogr • • • • • 96
  97. 97. Kotlin support 97
  98. 98. Take aways Gradle is not ideal (but what is?) Gradle's value is in its API, DSL, plug­ins and community Gradle is constanly evolving • • • 98
  99. 99. Links https://zeroturnaround.com/rebellabs/making­gradle­builds­faster/ https://github.com/ksoichiro/awesome­gradle https://github.com/gradle­guides/performance https://github.com/shekhargulati/gradle­tips • • • • 99
  100. 100. That's all! 100
  101. 101. Thank you! 101
  102. 102. 102

×