Slide 1

Slide 1 text

Customizing and Refactoring Gradle Builds Marc Philipp, Gradle Inc.

Slide 2

Slide 2 text

Marc Philipp So ware Engineer at Gradle, Inc. JUnit 5 team lead Twi er: Web: @marcphilipp marcphilipp.de

Slide 3

Slide 3 text

What is Gradle?

Slide 4

Slide 4 text

What is Gradle? ⬢ ⬢ ⬢ ⬢ based on the Java Virtual Machine (JVM) implemented in Java focused on flexibility and performance 100% open‑source (Apache 2.0) and free Gradle is an open‑source build automa on tool

Slide 5

Slide 5 text

Versa le ⬢ ⬢ ⬢ ⬢ Java ecosystem: Java, Groovy, Kotlin, Scala, … Official build tool for Android Na ve projects: C, C++, Swi , … And more: Go, Asciidoctor, …

Slide 6

Slide 6 text

Gradle Inc. ⬢ ⬢ ⬢ ⬡ ⬡ ⬢ Vision: Build Happiness Mission: Accelerate Developer Produc vity Products: Gradle Build Tool Gradle Enterprise more than 60 employees including over 40 engineers

Slide 7

Slide 7 text

Agenda ⬢ ⬢ ⬡ ⬡ ⬡ Basic concepts From Quick & Dirty to Safe & Sound dependency management custom tasks custom configura on

Slide 8

Slide 8 text

✋ Show of Hands

Slide 9

Slide 9 text

Basic Concepts

Slide 10

Slide 10 text

Tasks ⬢ ⬢ ⬢ a Gradle build executes tasks tasks can depend on other tasks tasks have inputs and outputs

Slide 11

Slide 11 text

Hello World tasks.register("helloWorld") { // in build.gradle doLast { println("Hello World!") } } $ gradle helloWorld > Task :helloWorld Hello World! BUILD SUCCESSFUL in 0s 1 actionable task: 1 executed

Slide 12

Slide 12 text

Build Scripts A Gradle project is configured in build scripts: ⬢ ⬢ settings.gradle[.kts]: configures the subprojects that comprise the build build.gradle[.kts]: configures the used plugins and tasks

Slide 13

Slide 13 text

se ngs.gradle[.kts] rootProject.name = "new-project" include("subproject-a") include("subproject-b")

Slide 14

Slide 14 text

build.gradle[.kts] plugins { java // to compile Java sources application // to generate startup scripts } repositories { jcenter() // to resolve dependencies } dependencies { implementation("com.google.guava:guava:28.0-jre") testImplementation("org.junit.jupiter:junit-jupiter:5.5.2") } application { // extension of the 'application' plugin mainClassName = "com.example.App" }

Slide 15

Slide 15 text

Groovy vs. Kotlin DSL ⬢ ⬢ ⬡ ⬡ ⬢ build scripts use a Domain Specific Language (DSL) ini ally Gradle only supported Groovy dynamically typed limited IDE support Kotlin DSL is stable since Gradle 5.0 Build scripts should be declara ve – complex logic does not belong here.

Slide 16

Slide 16 text

Gradle Wrapper ./gradlew instead of gradle ⬢ ⬢ ⬢ ⬢ execute builds with prior installa on of Gradle downloads required version caches already downloaded versions locally everyone uses the same version

Slide 17

Slide 17 text

Anatomy of a Gradle project $ gradle init --dsl=kotlin --type=java-application \ --test-framework=junit --package=com.example \ --project-name=new-project BUILD SUCCESSFUL in 0s 2 actionable tasks: 2 executed ├── build.gradle.kts // build script ├── gradle/wrapper // wrapper jar and configuration ├── gradlew // wrapper script for Linux/macOS ├── gradlew.bat // wrapper script for Windows ├── settings.gradle.kts // settings script └── src // Java source tree ├── main │ ├── java │ └── resources └── test ├── java └── resources

Slide 18

Slide 18 text

Incremental Builds ⬢ ⬡ ⬡ ⬡ ⬢ only execute tasks that are affected by changes in between two subsequent builds inputs have changed outputs are present and unchanged task implementa on has changed (e.g. different plugin version) keep outputs of all tasks that are up‑to‑date

Slide 19

Slide 19 text

First Build $ ./gradlew --console=plain build > Task :compileJava > Task :processResources NO-SOURCE > Task :classes > Task :jar [...] > Task :compileTestJava > Task :testClasses > Task :test > Task :check > Task :build BUILD SUCCESSFUL in 5s 7 actionable tasks: 7 executed

Slide 20

Slide 20 text

Subsequent Build $ ./gradlew --console=plain build > Task :compileJava UP-TO-DATE > Task :processResources NO-SOURCE > Task :classes UP-TO-DATE > Task :jar UP-TO-DATE [...] > Task :compileTestJava UP-TO-DATE > Task :testClasses UP-TO-DATE > Task :test UP-TO-DATE > Task :check UP-TO-DATE > Task :build UP-TO-DATE BUILD SUCCESSFUL in 0s 7 actionable tasks: 7 up-to-date

Slide 21

Slide 21 text

Build Scans ⬢ ⬢ ⬢ Accelerate debugging of build problems Private but shareable link Free to use on › scans.gradle.com $ ./gradlew build --scan BUILD SUCCESSFUL in 1s 7 actionable tasks: 5 executed, 2 up-to-date Publishing build scan... https://gradle.com/s/lu7dxy7quyoju h ps:/ /gradle.com/s/lu7dxy7quyoju

Slide 22

Slide 22 text

Build Cache ⬢ ⬢ allows reusing task outputs of any previous build local and remote cache $ git pull [...] 185 files changed, 4320 insertions(+), 1755 deletions(-) $ ./gradlew --build-cache sanityCheck BUILD SUCCESSFUL in 1m 11s 1338 actionable tasks: 238 executed, 1100 from cache

Slide 23

Slide 23 text

Dependency Management

Slide 24

Slide 24 text

Demo

Slide 25

Slide 25 text

Recap ⬢ ⬢ ⬢ ⬢ Don’t duplicate dependency version Prefer api or implementation over compile Use buildSrc to collect dependency versions Use a java-platform plugin to streamline dependency management

Slide 26

Slide 26 text

More on Dependency Management Free webinars: ⬢ ⬢ h ps:/ /gradle.com/blog/dependency‑management‑ fundamentals/ h ps:/ /gradle.com/blog/dependency‑management‑ part‑2‑handling‑conflicts/

Slide 27

Slide 27 text

Custom Tasks

Slide 28

Slide 28 text

Demo

Slide 29

Slide 29 text

Recap ⬢ ⬢ ⬢ Don’t define complex tasks directly in the build script Define them in the buildSrc project Allows for tes ng and reuse in subprojects

Slide 30

Slide 30 text

Custom Configura on

Slide 31

Slide 31 text

Demo

Slide 32

Slide 32 text

Recap ⬢ ⬢ ⬢ Extract custom logic into separate build scripts Even be er: Extract your custom logic into a pre‑ compiled script plugin in buildSrc Next step: Move it to a separate plugin to use it in independent projects

Slide 33

Slide 33 text

Summary

Slide 34

Slide 34 text

Summary ⬢ ⬢ Keep your build scripts declara ve Use buildSrc to share logic

Slide 35

Slide 35 text

Links ⬢ ⬢ Demo code: My talks on Gradle and JUnit: h ps:/ /github.com/marcphilipp/gradle‑refactorings h ps:/ /www.marcphilipp.de/en/talks/

Slide 36

Slide 36 text

Thank you! @marcphilipp