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

Managing tasks to Kotlin

Managing tasks to Kotlin

rejasupotaro

June 21, 2017
Tweet

More Decks by rejasupotaro

Other Decks in Technology

Transcript

  1. Managing tasks
    to Kotlin
    Kentaro Takiguchi
    @rejasupotaro

    View Slide

  2. About me
    • Kentaro Takiguchi @ Cookpad
    • Visited Asian countries, US, Middle East, Europe,
    … => Settle down to a new life in UK

    View Slide

  3. View Slide

  4. My motivation of
    automation
    • This project is unique and challenging (= fun)
    • Product: Cultural difference, linguistic
    difference, …
    • Development: Remote team, different opinions
    and backgrounds, …
    • Many problems I want to solve => I want to make
    myself more productive

    View Slide

  5. A day of mine
    • Have coffee
    • Code review
    • Talk about technical issues
    • Talk about hiring
    • Lunch
    • Write code
    • Work on translation
    • Release
    • Monitor errors
    • Analyze logs
    • Create slides
    • Go to gym
    • Write a blog post

    View Slide

  6. How much time can you
    take only for coding?

    View Slide

  7. Make machines work
    instead of humans
    • Report lint warnings instead members review
    code carefully and leave comments on GitHub
    • Display test coverage on each PR to encourage
    members to write tests instead of saying “please
    add tests”
    • Download/Upload translation instead members
    open a translation tool and click some buttons

    View Slide

  8. Task manegement was
    chaos
    • Make, Rake, … Gradle?
    • How it’s managed depends on the project
    • How about your project?

    View Slide

  9. How to manage tasks
    • Rake > Gradle?
    • There are many gems such as Fastlane, GitHub,
    DeployGate, OneSky, Slack…
    • Gradle
    • We can (have to) choose from Java or Groovy
    • There are few plugins/libraries
    • But…

    View Slide

  10. View Slide

  11. It changed my mind
    • We have to choose from Java or Groovy
    • => Now Kotlin is a realistic option
    • There are few plugins/libraries
    • => Opportunity

    View Slide

  12. It’s a good time to
    learn Gradle tasks

    View Slide

  13. Gradle
    • Build automation system
    • Gradle uses a directed a cyclic graph (DAG) to
    determine the order of tasks
    • Stable release: 4.0
    • Gradle’s Build Cache is now production-ready
    which makes Gradle builds up to 100x faster
    than Maven

    View Slide

  14. 1. Build script (Groovy)
    2. buildSrc (JVM languages)
    3. Standalone project (JVM languages)
    How to define Gradle
    tasks

    View Slide

  15. Build script
    • Define tasks directly in the build.gradle
    • The task class is automatically compiled and
    included in the class path of the build script
    • The task class is not visible outside the build
    script

    View Slide

  16. Method 1-1
    // app/build.gradle

    task yourTaskName {

    doLast {
    // What you want to do

    }

    }

    View Slide

  17. Method 1-1
    // app/build.gradle

    task hello {

    doLast {
    println “Hello”

    }

    }
    ./gradlew hello => “Hello”

    View Slide

  18. Method 1-2
    // app/build.gradle
    task("hello") {

    doLast {

    println "Hello"

    }

    }

    View Slide

  19. Method 1-3
    // app/build.gradle
    tasks.create(name: “hello”) {

    doLast {

    println "hello"

    }

    }

    View Slide

  20. Method 1-4
    // app/build.gradle

    task hello(type: HelloTask)

    class HelloTask extends DefaultTask {

    @TaskAction

    def hello() {

    println “Hello”

    }

    }

    View Slide

  21. View Slide

  22. Many ways…
    • No need to remember everything but should
    unify how to define tasks in the same project
    • We have to write tasks in Groovy when we go
    with 1. Build script

    View Slide

  23. buildSrc project
    • Define the task class in `rootProject/buildSrc`
    • Gradle will take care of compiling and testing the
    task class and making it available on the class
    path of the build script

    View Slide

  24. buildSrc project
    1. Create buildSrc directory
    2. Add `build.gradle`
    3. Create `src/main/groovy/your/package/
    HelloTask.groovy`

    View Slide

  25. Method 2 (Groovy)
    // app/build.gradle
    task hello(type: HelloTask)
    // buildSrc/src/main/groovy/your/package/HelloTask.groovy

    class HelloTask extends DefaultTask {

    @TaskAction

    def hello() {

    println(“Hello”)

    }

    }

    View Slide

  26. Method 2 (Java)
    // app/build.gradle
    task hello(type: HelloTask)
    // buildSrc/src/main/java/your/package/HelloTask.java
    public class HelloTask extends DefaultTask {

    @TaskAction

    def hello() {

    System.out.println(“Hello”)

    }

    }

    View Slide

  27. Method 2 (Kotlin)
    // app/build.gradle
    task hello(type: HelloTask)
    // buildSrc/src/main/kotlin/your/package/HelloTask.kt
    open class HelloTask : DefaultTask() {

    @TaskAction

    fun hello() {

    println(“Hello”)

    }

    }

    View Slide

  28. Write tests for buildSrc
    class HelloTaskTest {

    @Test

    fun hello() {

    val project = ProjectBuilder.builder().build()

    val task = project.task("hello")

    assertTrue(task is HelloTask)

    }

    }

    View Slide

  29. Isn’t it better than 1. Build
    script?
    • We can write Kotlin
    • We can test
    • It’s still unavailable outside the project

    View Slide

  30. Standalone project
    = Gradle Plugin
    • This project produces and publishes a JAR
    which you can use in multiple builds and share
    with others
    • The JAR might bundle several related task
    classes into a single library

    View Slide

  31. How to write Gradle Plugin
    in Kotlin
    1. Create Java library project
    2. Apply “Convert Java File to Kotlin File”
    3. Add properties file
    4. Define Plugin
    5. Add tasks (We already known!)
    6. Add tests (We already known!)
    7. Publish

    View Slide

  32. 3. Add properties file

    View Slide

  33. 4. Define Plugin
    // plugin/src/main/kotlin/your/package/HelloPlugin.kt
    class YourPlugin : Plugin {

    override fun apply(project: Project) {

    with(project) {

    extensions.create(“yourExtension", YourExtension::class.java)

    tasks.create("yourTask1", YourTask1::class.java)

    tasks.create("yourTask2", YourTask2::class.java)

    tasks.create("yourTask3", YourTask3::class.java)

    }

    }

    }

    View Slide

  34. Create extension
    (if needed)
    // plugin/src/main/kotlin/your/package/HelloPlugin.kt
    class YourPlugin : Plugin {

    override fun apply(project: Project) {

    with(project) {

    extensions.create(“yourExtension", YourExtension::class.java)

    tasks.create("yourTask1", YourTask1::class.java)

    tasks.create("yourTask2", YourTask2::class.java)

    tasks.create("yourTask3", YourTask3::class.java)

    }

    }

    }

    View Slide

  35. Extension
    open class OneskyExtension {

    var apiKey: String = ""

    var apiSecret: String = ""

    var projectId: Int = 0

    var locales: Set = setOf()


    fun locales(locales: Array) {

    this.locales = locales.toSet()

    }

    }
    // app/build.gradle
    onesky {

    apiKey oneskyApiKey

    apiSecret oneskyApiSecret

    projectId oneskyProjectId
    locales “es”, “ar”, …

    }

    View Slide

  36. 5. Add tasks
    // plugin/src/main/kotlin/your/package/HelloPlugin.kt
    class YourPlugin : Plugin {

    override fun apply(project: Project) {

    with(project) {

    extensions.create(“yourExtension", YourExtension::class.java)

    tasks.create("yourTask1", YourTask1::class.java)

    tasks.create("yourTask2", YourTask2::class.java)

    tasks.create("yourTask3", YourTask3::class.java)

    }

    }

    }

    View Slide

  37. 5. Add tasks
    We can reuse
    // app/build.gradle
    apply plugin: ”your.plugin”
    // plugin/src/main/kotlin/your/package/HelloTask.kt
    open class HelloTask : DefaultTask() {

    @TaskAction

    fun hello() {

    println(“Hello”)
    }

    }

    View Slide

  38. 6. Add tests
    We can reuse
    class HelloTaskTest {

    @Test

    fun hello() {

    val project = ProjectBuilder.builder().build()

    val task = project.task("hello")

    assertTrue(task is HelloTask)

    }

    }

    View Slide

  39. 1. Create Java library project
    2. Convert to Kotlin
    3. Add properties file
    4. Define Plugin
    5. Add tasks
    6. Add tests
    7. Publish
    1. Build script 2. buildSrc 3. Standalone project
    1. Create buildSrc
    directory
    2. Add `build.gradle`
    3. Add tasks
    4. (Add tests)
    1. Add tasks

    View Slide

  40. It depends on your
    requirement
    • 1. Build script: I would recommend this only for
    small tasks
    • 2. buildSrc project: Suitable for project specific
    tasks
    • 3. Standalone project: You can use in multiple
    builds and share with other projects

    View Slide

  41. Gradle Script Kotlin
    Could be an option?
    • Could be when it becomes stable
    • We would be able to write tasks in Kotlin in
    `build.gradle.kts`

    View Slide

  42. 1. Build script (Kotlin)
    2. buildSrc (Kotlin)
    3. Standalone project (Kotlin)
    Everything is Kotlin
    app (Kotlin)

    View Slide

  43. Everything is Kotlin

    View Slide

  44. Off topic: Kotin migration
    of Cookpad
    Started migrating Java to Kotlin
    2016/11 2017/5
    40% done
    Migrated from Rake to Gradle
    2017/6
    Migrated tests
    2016/12

    View Slide

  45. Kentaro Takiguchi
    @rejasupotaro
    Let’s automate
    Thank you for listening!

    View Slide