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. About me • Kentaro Takiguchi @ Cookpad • Visited Asian

    countries, US, Middle East, Europe, … => Settle down to a new life in UK
  2. 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
  3. 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
  4. 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
  5. Task manegement was chaos • Make, Rake, … Gradle? •

    How it’s managed depends on the project • How about your project?
  6. 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…
  7. It changed my mind • We have to choose from

    Java or Groovy • => Now Kotlin is a realistic option • There are few plugins/libraries • => Opportunity
  8. 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
  9. 1. Build script (Groovy) 2. buildSrc (JVM languages) 3. Standalone

    project (JVM languages) How to define Gradle tasks
  10. 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
  11. Method 1-1 // app/build.gradle
 task hello {
 doLast { println

    “Hello”
 }
 } ./gradlew hello => “Hello”
  12. Method 1-4 // app/build.gradle
 task hello(type: HelloTask) 
 class HelloTask

    extends DefaultTask {
 @TaskAction
 def hello() {
 println “Hello”
 }
 }
  13. 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
  14. 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
  15. buildSrc project 1. Create buildSrc directory 2. Add `build.gradle` 3.

    Create `src/main/groovy/your/package/ HelloTask.groovy`
  16. 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”)
 }
 }
  17. 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”)
 }
 }
  18. 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”)
 }
 }
  19. Write tests for buildSrc class HelloTaskTest {
 @Test
 fun hello()

    {
 val project = ProjectBuilder.builder().build()
 val task = project.task("hello")
 assertTrue(task is HelloTask)
 }
 }
  20. Isn’t it better than 1. Build script? • We can

    write Kotlin • We can test • It’s still unavailable outside the project
  21. 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
  22. 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
  23. 4. Define Plugin // plugin/src/main/kotlin/your/package/HelloPlugin.kt class YourPlugin : Plugin<Project> {


    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)
 }
 }
 }
  24. Create extension (if needed) // plugin/src/main/kotlin/your/package/HelloPlugin.kt class YourPlugin : Plugin<Project>

    {
 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)
 }
 }
 }
  25. Extension open class OneskyExtension {
 var apiKey: String = ""


    var apiSecret: String = ""
 var projectId: Int = 0
 var locales: Set<String> = setOf()
 
 fun locales(locales: Array<String>) {
 this.locales = locales.toSet()
 }
 } // app/build.gradle onesky {
 apiKey oneskyApiKey
 apiSecret oneskyApiSecret
 projectId oneskyProjectId locales “es”, “ar”, …
 }
  26. 5. Add tasks // plugin/src/main/kotlin/your/package/HelloPlugin.kt class YourPlugin : Plugin<Project> {


    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)
 }
 }
 }
  27. 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”) }
 }
  28. 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)
 }
 }
  29. 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
  30. 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
  31. 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`
  32. 1. Build script (Kotlin) 2. buildSrc (Kotlin) 3. Standalone project

    (Kotlin) Everything is Kotlin app (Kotlin)
  33. 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