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

Kotlinとずっと一緒にいたい話 with Kotlin Scripting

umakoz
September 14, 2019

Kotlinとずっと一緒にいたい話 with Kotlin Scripting

umakoz

September 14, 2019
Tweet

More Decks by umakoz

Other Decks in Programming

Transcript

  1. Kotlin ͱ
    ͣͬͱҰॹʹ͍͍ͨ࿩
    with Kotlin Scripting
    LINE Fukuoka
    അݟ ੣ @umakoz
    Coroutine ϋϯζΦϯ by DroidKaigi @ LINE Fukuoka

    View Slide

  2. About me
    • LINE Fukuoka
    • അݟɹ੣ʢumami makotoʣ
    • @umakoz

    !
    3°02'03"
    • LINE Creators Studio

    View Slide

  3. KotlinͰ
    Android AppΛ
    ։ൃͯ͠·͔͢ʁ

    View Slide

  4. Kotlinͱ
    ͣͬͱ
    ཭Εͨ͘ͳ͍Ͱ͢ΑͶʂ

    View Slide

  5. ͔͠͠ɺಥવͷKotlin࢖͍ʹ͍͘Ҋ݅
    Excel fileΛಡΈࠐΜͰɺ
    Kotlin code fileΛग़ྗ͢Δɻ
    ੜ੒ͨ͠fileΛAndroid appͰ࢖͏ɻ

    View Slide

  6. Command-line Tool΋
    KotlinͰॻ͖͍͕ͨɻɻɻ
    • Compile͢ΔͷΊΜͲ͍
    • Gradle commandʹ͢Δͷ΋ΊΜͲ͍

    View Slide

  7. Kotlin Scripting support
    • KotlinΛScriptݴޠͱͯ͠࢖͑ΔΑ͏ʹ͢Δ
    • command-line toolͱ͸REPLͳͲͷ༻్Λ૝ఆ͍ͯ͠Δ
    • https://github.com/Kotlin/KEEP/blob/master/proposals/
    scripting-support.md

    View Slide

  8. Preparation
    • Kotlin CLIΛinstall͢Δ
    • Kotlin 1.3.50લఏ
    $ brew install kotlin

    View Slide

  9. generate.main.kts overview
    Command-line͔Β࣮ߦ͢Δscript
    @file:Repository("https://jcenter.bintray.com")
    @file:DependsOn("org.apache.poi:poi-ooxml:4.1.0")
    @file:DependsOn("org.freemarker:freemarker:2.3.29")
    @file:Import("EventXlsxParser.kt")
    import freemarker.template.Configuration
    import ...
    val filePath = args[0]
    val events = EventXlsxParser().parse("${filePath}${File.separator}Events.xlsx")
    val configuration = Configuration(Configuration.getVersion()).apply {
    setDirectoryForTemplateLoading(File("./templates"))
    }
    val template = configuration.getTemplate("ActionEvent.ftl")
    val writer = FileWriter("${filePath}${File.separator}ActionEvent.kt")
    val data = hashMapOf("events" to events)
    template.process(data, writer)

    View Slide

  10. generate.main.kts note 1
    • ֦ுࢠΛ ".main.kts" ʹ͢Δ
    ".main"Λ͚ͭΔͱ file-level annotation ͕༗ޮʹͳΔ

    View Slide

  11. generate.main.kts note 2
    • file-level annotaionʹΑΓscriptػೳ֦ு͢Δ
    @file:ImportͰඞཁͳґଘ΋@file:DependsOnͰࢦఆ͢Δ
    // maven repository
    @file:Repository("https://jcenter.bintray.com")
    // 3rd-party library
    @file:DependsOn("org.apache.poi:poi-ooxml:4.1.0")
    @file:DependsOn("org.freemarker:freemarker:2.3.29")
    // import another Kotlin code
    @file:Import("EventXlsxParser.kt")

    View Slide

  12. generate.main.kts note 3
    • @file:ImportͰ͸Kotlin script΋source΋ಡΈࠐΊΔ
    scriptʹ͢Δͱɺmain͔Βimport fileͷclass͕ࢀরͰ͖ͳ͍
    // script
    @file:Import("EventXlsxParser.main.kts")
    // source
    @file:Import("EventXlsxParser.kt")

    View Slide

  13. EventXlsxParser.kt
    import java.nio.file.Paths
    import org.apache.poi.ss.usermodel.WorkbookFactory
    class EventXlsxParser {
    fun parseXlsx(filePath: String): List> {
    val file = Paths.get(filePath).toFile()
    val workbook = WorkbookFactory.create(file)
    val sheet = workbook.getSheet("Action")
    val keys = sheet.first().map { cell -> cell.stringCellValue }
    return sheet.rowIterator().asSequence().drop(1)
    .map { row ->
    keys.mapIndexed { index, key ->
    key to row.getCell(index).stringCellValue
    }.toMap()
    }
    .toList()
    }
    }

    View Slide

  14. generate.main.kts note 4
    • @file:paramͰscript parameterΛड͚औΕΔ͸͕ͣͩɺ
    ্ख͘ಈ࡞͠ͳ͔ͬͨʢݪҼ஌ͬͯͨΒڭ͍͑ͯͩ͘͞ ʣ
    // NG
    //@file:param("filePath", "String?")
    // OK
    val filePath = args[0]

    View Slide

  15. generate.main.kts note 5
    • ͋ͱ͸ී௨ͷcodeΛॻ͘
    val events = EventXlsxParser().parse("${filePath}${File.separator}Events.xlsx")
    val configuration = Configuration(Configuration.getVersion()).apply {
    setDirectoryForTemplateLoading(File("./"))
    }
    val template = configuration.getTemplate("ActionEvent.ftl")
    val writer = FileWriter("${filePath}${File.separator}ActionEvent.kt")
    val data = hashMapOf("events" to events)
    template.process(data, writer)

    View Slide

  16. ActionEvent.ftl
    sealed class ActionEvent(
    val type: String,
    val value: String
    ) {
    <#assign currentType = "">
    <#list events as event>
    <#if currentType != event.type>
    <#assign currentType = event.type>
    <#assign typeValues = events?filter(v -> v.type == currentType)>
    class ${currentType?cap_first} {
    <#typeValues as typeValue>
    object ${typeValue.value?cap_first} : ActionEvent("${typeValue.type}", "${typeValue.value}")
    #list>
    }
    #if>
    #list>
    }

    View Slide

  17. Execute
    • kotlin-main-kts-1.3.50.jarΛdownloadͯ͠
    scriptͱಉ͡folderʹஔ͘
    $ kotlinc \
    -cp ./kotlin-main-kts-1.3.50.jar \
    -script ./generate.main.kts \
    /path/to/file

    View Slide

  18. ActionEvent.kt
    sealed class ActionEvent(
    val type: String,
    val value: String
    ) {
    class Foo {
    object On : ActionEvent("bar", "on")
    object Off : ActionEvent("bar", "off")
    }
    }

    View Slide

  19. Kotlin script Pros
    1. Kotlin code͕scriptͱͯ͠ॻ͚Δ
    2. ໰୊ͳ࣮͘༻Ͱ͖ΔϨϕϧ
    3. Dependencies͸ॳճىಈʗߏ੒มߋ࣌ʹղܾ͠
    Caching͞ΕΔͷͰ଴ͨ͞Εͳ͍

    View Slide

  20. Kotlin script Cons
    1. ⾠ Experimental
    2. IDEʹΑΔsupport͕ऑ͍
    • Import
    • Suggestion

    View Slide

  21. ๻ͱKotlin͸ͣͬͱҰॹ

    View Slide

  22. LINE Fukuoka͸
    Android EngineerΛ
    ืू͍ͯ͠·͢!!!!!

    View Slide