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

[Michael Pustovit] Gradle scripts in Kotlin: is it cool?

[Michael Pustovit] Gradle scripts in Kotlin: is it cool?

Presentation from GDG DevFest Ukraine 2017 - the biggest community-driven Google tech conference in the CEE.

Learn more at: https://devfest.gdg.org.ua

Google Developers Group Lviv

October 14, 2017
Tweet

More Decks by Google Developers Group Lviv

Other Decks in Technology

Transcript

  1. #dfua Plan for next ~35 minutes 1. Groovy Gradle DSL

    magic 2. Kotlin DSL remedy 3. Demo (groovy -> kotlin) 1 2 3
  2. #dfua 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. #dfua Named parameters testCompile group: 'junit', name: 'junit', version: '4.12'

    testCompile([group: 'junit', name: 'junit', version: '4.12'])
  4. #dfua Abstract Syntax Tree (AST) transformation task hello { println

    "Hello world!" } task('hello', { println "Hello world!" })
  5. #dfua 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!" })
  6. #dfua Plugins class GreetingPlugin implements Plugin<Project> { void apply(Project project)

    { project.task('hello') { doLast { println 'Hello from the GreetingPlugin' } } } }
  7. #dfua 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 }} } }
  8. #dfua Plugin extension apply plugin: 'org.example.GreetingPlugin' greeting { message "Hello

    world!" } This method doesn’t exist at “compile” time
  9. #dfua class Foo { def methodMissing(String name, def args) {

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

    of a help from an IDE 3. Late error detection 1 2 3
  11. #dfua 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
  12. #dfua 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
  13. #dfua • Dynamic nature of plugins • “Old” plugins •

    Kotlin-Groovy intercommunication Why is it not so easy?
  14. #dfua Current (“old”) plugin system buildscript { repositories { jcenter()

    } def ver = “1.0.0” dependencies { classpath "jfrog…:$ver" } } apply plugin: "com.jfrog…" Dynamic block
  15. #dfua New plugin system pluginManagement { repositories { gradlePluginPortal() }

    } plugins { id "com.jfrog…" version "4.5.2" } Static block Gradle plugins repo
  16. #dfua "conventions": { "base": "org...BasePluginConvention", "java": "org...JavaPluginConvention", ... }, "configurations":

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

    Project.`android`(configure: AppExtension.() -> Unit): Unit = extensions.configure("android", configure) Generated code
  18. #dfua > gradle kotlinDslAccessorsSnapshot gradle ├── project-schema.json └── wrapper ├──

    gradle-wrapper.jar └── gradle-wrapper.properties Dynamic > Static workaround
  19. #dfua How to use this workaround 1. Apply a plugin

    but not add an extension yet 2. gradle kotlinDslAccessorsSnapshot 3. Add the extension 1 2 3
  20. #dfua Kotlin DSL + Android • Android plugin is not

    in the repo • Android plugin is tricky • Not supported plugins
  21. #dfua Unsupportable plugins android { playAccountConfigs { defaultAccountConfig { serviceAccountEmail

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

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

    Android projects • Should try - it’s a future Summary
  24. #dfua 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