Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Kotlin DSL in Gradle build scripts

Michael
November 11, 2017

Kotlin DSL in Gradle build scripts

Gradle is a default build tool for Android applications. It is experiencing a phase of rapid growth now and tries to adopt new build script language – Kotlin. We will try to discover what benefits and dangers the new language brings, how it makes build script magic more understandable and what pitfalls we should avoid.

Demo project: https://github.com/lampapos/kotand

Michael

November 11, 2017
Tweet

More Decks by Michael

Other Decks in Programming

Transcript

  1. Plan for next ~35 minutes 1. Groovy Gradle DSL magic

    2. Kotlin DSL remedy 3. Demo (groovy -> kotlin) 1 2 3 Domain-Specific Language - a language for a specific problem.
  2. apply plugin: 'java’ version '1.0-SNAPSHOT' sourceCompatibility = 1.8 repositories {

    mavenCentral() } dependencies { testCompile group: 'junit', name: 'junit', version: '4.12' } task hello { println "Hello world!" }
  3. Abstract Syntax Tree (AST) transformation task hello { println "Hello

    world!" } task('hello', { println "Hello world!" })
  4. apply(plugin: 'java') version('1.0-SNAPSHOT') sourceCompatibility = 1.8 repositories({ mavenCentral() }) dependencies({

    testCompile([group: 'junit', name: 'junit', version: '4.12']) }) task('hello', { println "Hello world!" })
  5. Plugins class GreetingPlugin implements Plugin<Project> { void apply(Project project) {

    project.task('hello') { doLast { println 'Hello from the GreetingPlugin' } } } }
  6. Plugins class GreetingPluginExtension { String message } class GreetingPlugin implements

    Plugin<Project> { void apply(Project prj) { def ext = prj.extensions.create('greeting', GreetingPluginExtension) project.task('hello') { doLast { println ext.message }} } }
  7. class Foo { def methodMissing(String name, def args) { return

    '1' } } assert new Foo().someUnknownMethod(42) == '1' “methodMissing” method
  8. Problems 1. Too much Groovy specific magic 2. Lack of

    a help from an IDE 3. Late error detection 1 2 3
  9. apply plugin: 'java’ version '1.0-SNAPSHOT' sourceCompatibility = 1.8 repositories {

    mavenCentral() } dependencies { testCompile group: 'junit', name: 'junit', version: '4.12' } task hello { println "Hello world!" } Groovy DSL
  10. apply { plugin("java") } version = "1.0-SNAPSHOT" java.sourceCompatibility = JavaVersion.VERSION_1_8

    repositories { mavenCentral() } dependencies { testCompile(group = "junit", name = "junit", version = "4.12") } tasks.create("hello", { println("Hello world!") }) Kotlin DSL
  11. Plugins application buildscript { repositories { jcenter() } def ver

    = “1.0.0” dependencies { classpath "jfrog…:$ver" } } apply plugin: "com.jfrog…" Where to look for plugins What plugins do we need
  12. How to use this workaround 1. Apply a plugin but

    not add an extension yet 2. Trigger handlers generator 3. Add the extension & configure plugins 1 2 3
  13. "conventions": { "base": "org...BasePluginConvention", "java": "org...JavaPluginConvention", ... }, "configurations": [

    "compile", "provided", ... ], "extensions": { "ext": "org...ExtraPropertiesExtension", "defaultArtifacts": "org.gradle.api.inter…”, ... } project-schema.json
  14. val Project.`android`: AppExtension get() = extensions.getByName("android") as AppExtension fun Project.`android`(configure:

    AppExtension.() -> Unit): Unit = extensions.configure("android", configure) Generated code
  15. Current (“old”) plugin system buildscript { repositories { jcenter() }

    def ver = “1.0.0” dependencies { classpath "jfrog…:$ver" } } apply plugin: "com.jfrog…" Dynamic block Can be placed anywhere
  16. New plugin system pluginManagement { repositories { gradlePluginPortal() } }

    plugins { id "com.jfrog…" version "4.5.2" } Static block Gradle plugins repo
  17. Kotlin DSL + Android • Android plugin is not in

    the repo • Android plugin is tricky • Not supported plugins
  18. Unsupportable plugins android { playAccountConfigs { defaultAccountConfig { serviceAccountEmail =

    '[email protected]' pk12File = file('key.p12') } } defaultConfig { // ... } } Triple-T/gradle-play-publisher
  19. Kotlin extension configuration hack apply { plugin("com.android.application") } // android

    { configure <com.android.build.gradle.AppExtension> { buildToolsVersion("26.0.2") compileSdkVersion(26) } > gradle kotlinDslAccessorsSnapshot
  20. • Tools are in alpha-beta state ``` • Usable with

    Android projects • Should try - it’s a future ``` Summary
  21. Sources ❖ Kotlin DSL GitHub repo ❖ Using Gradle Script

    Kotlin for Android ❖ Chicken and egg problem with accessors.kt ❖ Gradle and Kotlin, a personal perspective ❖ Compile time metaprogramming in Groovy ❖ Gradle tip #2: understanding syntax