Reveal.js-Asciidoc-Gradle

gradle elephant

Gradle is awesome!

Marvin Strangfeld
Strangfeld.io

Why Gradle?

Highly customizable

  • rich plugin eco-system

  • build scripts using Groovy or Kotlin

Fast

  • parallel execution of tasks

  • lazy configuration

  • task configuration avoidance

  • incremental builds

Powerful

  • support for many languages

  • use common build logic across different projects

  • fast development

gradle effective meme

How to get Gradle?

Use SDKMAN!

$ curl -s "https://get.sdkman.io" | bash
$ sdk install gradle
$ gradle build

Use the Gradle Wrapper

$ ./gradlew build

Build files

build.gradle.kts
plugins {
    id("com.openexchange.build.packaging") version "1.4.3"
}

repositories {
    jcenter()
}

dependencies {
    implementation("com.sample:myLib:1.0.0")
    testImplementation("com.sample:testLib:2.2.+")
}

val helloWorldTask by tasks.registering {
    doLast {
        println("Hello World!")
    }
}
build.gradle
plugins {
    id 'com.openexchange.build.packaging' version '1.4.3'
}

repositories {
    jcenter()
}

dependencies {
    implementation 'com.sample:myLib:1.0.0'
    testImplementation 'com.sample:testLib:2.2.+'
}

task helloWorldTask {
    doLast {
        println "Hello World!"
    }
}

Convention over configuration

.
├── build.gradle.kts
├── gradle
│   └── wrapper
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── settings.gradle.kts
└── src
    ├── main
    │   ├── java
    │   │   └── package
    │   │       └── App.java
    │   └── resources
    └── test
        ├── java
        │   └── package
        │       └── AppTest.java
        └── resources

Gradle lifecycle

Failed to generate image: Could not find the 'dot' executable in PATH; add it to the PATH or specify its location using the 'graphvizdot' document attribute
digraph lifecycle {
    bgcolor="transparent"
    Initialization[shape=box][label=<
    <table border="0" cellborder="0" cellspacing="1">
        <tr><td align="left"><b>Initialization</b></td></tr>
        <tr><td align="left">evaluate settings.gradle</td></tr>
        <tr><td align="left">scan projects</td></tr>
        <tr><td align="left">create Project instance</td></tr>
    </table>>][color=white, fontcolor=white, fontname="Open Sans"]
    Configuration[shape=box][label=<
    <table border="0" cellborder="0" cellspacing="1">
        <tr><td align="left"><b>Configuration</b></td></tr>
        <tr><td align="left">evaluate build.gradle</td></tr>
        <tr><td align="left">calculate dependencies</td></tr>
        <tr><td align="left">create task execution graph</td></tr>
    </table>>][color=white, fontcolor=white, fontname="Open Sans"]
    Execution[shape=box][label=<
    <table border="0" cellborder="0" cellspacing="1">
        <tr><td align="left"><b>Execution</b></td></tr>
        <tr><td align="left">execute specified tasks</td></tr>
    </table>>][color=white, fontcolor=white, fontname="Open Sans"]
    Initialization -> Configuration [type=s][color=white];
    Configuration -> Execution [type=s][color=white];
}

Let’s build something amazing!

Coffee App

package io.strangfeld.coffee

sealed class Coffee(val name: String) {
    class BlackCoffee: Coffee("black coffee")
    class Espresso: Coffee("espresso")
    class Cappuccino: Coffee("cappuccino")
}

interface CoffeeProvider {
    fun makeCoffee(coffee: KClass<out Coffee>): Coffee
}

class CoffeeMachine: CoffeeProvider {
    override fun makeCoffee(coffee: KClass<out Coffee>): Coffee {
        println("Making coffee...")
        val coffee = when(coffee) {
            Coffee.BlackCoffee::class -> Coffee.BlackCoffee()
            Coffee.Espresso::class -> Coffee.Espresso()
            else -> throw Exception("Couldn't make coffee of type $coffee")
        }
        println("Coffee is ready!")
        return coffee
    }
}

fun main(args: Array<String>) {
    println("""
        Select a coffee:
        1. Black coffee
        2. Espresso
        3. Cappuccino
    """.trimIndent())
    val selection = readLine()?.toInt()
    val coffeeProvider = CoffeeMachine()
    val coffee = when(selection) {
        1 -> coffeeProvider.makeCoffee(Coffee.BlackCoffee::class)
        2 -> coffeeProvider.makeCoffee(Coffee.Espresso::class)
        3 -> coffeeProvider.makeCoffee(Coffee.Cappuccino::class)
        else -> throw Exception("Don't know this coffee...")
    }
    println("Here is your ${coffee.name}")
}

Resources

Thank you for your attention!

This presentation has been build with Asciidoctor and Gradle