Slide 1

Slide 1 text

Kotlin Script 활용하기 @kciter KotlinConf'24 South Korea

Slide 2

Slide 2 text

Kotlin Script 활용하기 발표자 소개 이선협 (@kciter) CoBALT, CTO https://realizer.ai https://github.com/kciter https://kciter.so

Slide 3

Slide 3 text

What is Kotlin Script?

Slide 4

Slide 4 text

Kotlin Script 활용하기

Slide 5

Slide 5 text

Kotlin Script 활용하기 Kotlin을 스크립트 언어처럼! Kotlin scripting is the technology that enables executing Kotlin code as scripts without prior compilation or packaging into executables.

Slide 6

Slide 6 text

Kotlin Script 활용하기 다른 스크립트 언어처럼 빌드 없이 실행가능! Code 빌드하거나 패키징할 필요가 전혀 없다! Shell // hello.kts fun say() { println("Hello, Kotlin!") } say() $ kotlinc -script hello.kts Hello, Kotlin!

Slide 7

Slide 7 text

Kotlin Script 활용하기 그러나… https://kotlinlang.org/docs/custom-script-deps-tutorial.html 😱

Slide 8

Slide 8 text

Kotlin Script 활용하기 써야할 이유가 있나요? 베타도 아니고 실험 단계 현재 JVM 환경에서만 가능 솔직히 대안이 많다 그럼에도 불구하고 이 발표를 하는 이유? 재밌어 보이니까! 그래도 없어질 것 같지는 않다 이럴 때 아니면 언제 써보겠습니까

Slide 9

Slide 9 text

Kotlin Script 활용하기 일단 어디에 쓸 수 있는지 알아보자! 사용 사례는 총 세 가지 빌드를 위한 스크립트 이미 Gradle Kotlin DSL에서 잘 사용되고 있음 CLI 환경에서 스크립트 실행 Kotlin 프로그램 런타임에서 스크립트 실행

Slide 10

Slide 10 text

Alternative shell-scripting

Slide 11

Slide 11 text

Kotlin Script 활용하기 Shell Script 대체 Shell Script 대신 Kotlin Script를 사용할 수 있다. Kotlin Script가 가지는 이점은? Shell Script 보다는 쉬움 Type 안정성 외부 라이브러리 사용 가능 다른 스크립트 언어로도 가능하지만 Kotlin을 사용하면 더 좋은점? Kotlin 언어만 익숙한 경우에도 사용 가능 JVM 생태계와의 호환성 솔직히 성능은 살짝 애매하다 많은 연산 처리는 빠르겠지만 JVM 워밍업 시간이 필요하므로 워밍업 시간이 0에 가까운 Python이나 Node.js에 비해 느릴 수 있다.

Slide 12

Slide 12 text

Kotlin Script 활용하기 Kotlin을 사용하는 조직에선 쓸만할지도? 조직 내부에서 사용하는 툴을 만들 때 쓰면 어떨까?

Slide 13

Slide 13 text

Kotlin Script 활용하기 사용 방법 SDKMAN으로 kotlin 설치 Kotlin Script 작성 Kotlin Script 실행 # Install sdkman $ curl -s https://get.sdkman.io | bash $ source "$HOME/.sdkman/bin/sdkman-init.sh" # Install kotlin $ sdk install kotlin // hello.kts println("Hello, Kotlin!") # Run script $ kotlinc -script hello.kts Hello, Kotlin!

Slide 14

Slide 14 text

Kotlin Script 활용하기 shebang 사용 Code Shell !/usr/bin/env kotlinc -script println("Hello, Kotlin!") $ chmod +x hello.kts $ ./hello.kts Hello, Kotlin!

Slide 15

Slide 15 text

Kotlin Script 활용하기 KScript https://github.com/kscripting/kscript kotlinc 는 기본 기능만 있기 때문에 다른 언어를 대체하기는 역부족 kscript 는 kotlinc 에 비해 다양한 기능을 추가로 제공 스크립트 캐싱 의존성 관리 바이너리 패키징 설치 # Install kscript using sdkman $ sdk install kscript

Slide 16

Slide 16 text

Kotlin Script 활용하기 외부 라이브러리 사용하기 Code Shell @file:DependsOn("com.github.kittinunf.fuel:fuel:2.3.1") import com.github.kittinunf.fuel.httpGet // main.kts val (request, response, result) = "https://httpbin.org/get" .httpGet() .responseString() println(result.get()) [kscript] Resolving com.github.kittinunf.fuel:fuel:2.3.1... $ kscript main.kts { "args": {}, "headers": { "Accept": "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2", "Host": "httpbin.org", ...

Slide 17

Slide 17 text

Kotlin Script 활용하기 바이너리 패키징 Gradle이 필요하며 바이너리는 Java가 설치된 환경에서만 실행 가능 Shell $ kscript --package main.kts # Need Gradle [kscript] Packaging script 'main' into standalone executable... [kscript] Packaged script 'main' available at path: [kscript] /Users/kciter/Library/Caches/kscript/package_07f1f85044b41284dee18d4f8c159650/build/libs/main $ /Users/kciter/Library/Caches/kscript/package_07f1f85044b41284dee18d4f8c159650/build/libs $ ./main # Need Java { "args": {}, "headers": { "Accept": "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2", "Host": "httpbin.org", "User-Agent": "Java/17.0.3", "X-Amzn-Trace-Id": "Root=1-6676a491-5935eb22586d7aa550e76b8d" }, "origin": "1.225.3.207", "url": "https://httpbin.org/get" }

Slide 18

Slide 18 text

Kotlin Script 활용하기 IntelliJ와 함께 사용하기 kscript --idea 를 사용하면 자동으로 IntelliJ에서 편집할 수 있게 구성해준다.

Slide 19

Slide 19 text

Kotlin Script 활용하기 args 사용 kscript를 이용하면 자동으로 args를 받아올 수 있다 Code Shell println(args.joinToString(", ")) $ kotlinc --script args.kts hi hello bye $ kscript args.kts hi hello bye hi, hello, bye

Slide 20

Slide 20 text

Kotlin Script 활용하기 여러 라이브러리와 함께 사용해보자 Clikt : https://github.com/ajalt/clikt Mordant : https://github.com/ajalt/mordant

Slide 21

Slide 21 text

Kotlin Script 활용하기 Clikt CLI 입력을 쉽게 처리할 수 있다 // ... class Hello : CliktCommand() { val count: Int by option(help="Number of greetings").int().default(1) val name: String by option(help="The person to greet").prompt("Your name") override fun run() { repeat(count) { echo("Hello $name!") } } } Hello().main(args) $ kscript clikt.kts --count 3 Your name: kciter Hello kciter! Hello kciter! Hello kciter!

Slide 22

Slide 22 text

Kotlin Script 활용하기 Mordant Terminal UI를 그릴 수 있게 도와준다 val table = table { tableBorders = NONE borderType = SQUARE_DOUBLE_SECTION_SEPARATOR align = RIGHT column(0) { align = LEFT style = magenta } column(3) { style = magenta } header { style = magenta row("", "Projected Cost", "Actual Cost", "Difference") } . $ kscript ./table.kts │ Projected Cost │ Actual Cost │ Difference ══════════╪════════════════╧═════════════╪════════════ Food │ $400 $200 │ $200 ──────────┼──────────────────────────────┼──────────── Data │ $100 $150 │ $-50 ──────────┼──────────────────────────────┼──────────── Rent │ $800 $800 │ $0 ──────────┼──────────────────────────────┼──────────── Candles │ $0 $3,600 │ $-3,600 ──────────┼──────────────────────────────┼──────────── Utility │ $154 $150 │ $-5 ══════════╪══════════════════════════════╧════════════ Subtotal │ $-3,455

Slide 23

Slide 23 text

Kotlin Script 활용하기 해볼 수 있는건 많다! 배포 자동화 온보딩 툴 데이터 전처리 시드 데이터 추가 … 더 많은 예제는 https://github.com/kciter/kotlin-script-examples

Slide 24

Slide 24 text

Embedded Scripting

Slide 25

Slide 25 text

Kotlin Script 활용하기 Runtime에 Kotlin Script를 실행하는 두 가지 방법 Java Scripting API (JSR-223) Embeddable Host

Slide 26

Slide 26 text

Kotlin Script 활용하기 실험 단계라 그런지 문서가 빈약… Example 저장소가 그나마 유용하다 https://kotlinlang.org/docs/custom-script-deps-tutorial.html https://github.com/Kotlin/kotlin-script-examples

Slide 27

Slide 27 text

Kotlin Script 활용하기 Java Scripting API (JSR-223) 스크립트 코드를 JVM 위에 동작하는 프로그램에서 실행할 수 있게 해준다 JavaScript나 Groovy를 실행 할 수 있다. 물론 Kotlin Script도 실행 가능!

Slide 28

Slide 28 text

Kotlin Script 활용하기 Java Scripting API (JSR-223) org.jetbrains.kotlin:kotlin-scripting-jsr223 의존성 필수 라이브러리 이용이나 다른 스크립트 불러오기는 직접 구현해야함 kotlin-main-kts 를 사용하는 경우 extension을 main.kts 로 지정하면 알아서 다 해준다 org.jetbrains.kotlin:kotlin-main-kts 추가 필요 의존성 관리, 다른 스크립트 불러오기 등 필요한 것들을 미리 다 구현해둠 import javax.script.ScriptEngineManager fun main() { val engine = ScriptEngineManager().getEngineByExtension("main.kts")!! engine.eval( """ val a = 2 val b = 3 println("a + b = ${'$'}{a + b}") """.trimIndent() // Output: a + b = 5 ) }

Slide 29

Slide 29 text

Kotlin Script 활용하기 Java Scripting API (JSR-223) 스크립트 시작 전 미리 값을 넣어두는 것도 가능하다. engine.put("a", 2) engine.put("b", 3) println("a + b = ${'$'}{a + b}") import javax.script.ScriptEngineManager fun main() { val engine = ScriptEngineManager().getEngineByExtension("main.kts")!! engine.eval( """ """.trimIndent() ) }

Slide 30

Slide 30 text

Kotlin Script 활용하기 Embeddable Host 내장형 컴파일러를 사용하는 방식 kotlin-scripting-jsr223 도 내부적으로 사용하고 있다. 분리한 이유는 훗날 멀티플랫폼에서 사용하기 위함이 아닐까 추측 중 (자료가 너무 없다…) Script Definition과 Scripting Host를 만들어야 한다 공식 홈페이지는 이 방식만 설명하고 있다 https://kotlinlang.org/docs/custom-script-deps-tutorial.html 코드가 너무 길어지므로 여기선 생략

Slide 31

Slide 31 text

Kotlin Script 활용하기 뭘 할 수 있을까? 실험 단계기 때문에 실제 제품에 반영하는건 절대 안됨 어떤 문제가 있을지 알 수 없다 그래도 뭔가 해볼 수 없을까? 🤔

Slide 32

Slide 32 text

Kotlin Script 활용하기 HTML Template kotlinx.html 을 이용하여 HTML을 Kotlin DSL로 작성 가능 스크립트 파일을 외부로 뺀다면 컴파일 타임 없이 템플릿 작성 가능

Hello, Kotlin!

import javax.script.ScriptEngineManager data class Params(val name: String) fun main() { val engine = ScriptEngineManager().getEngineByExtension("main.kts")!! engine.put("params", Params("Kotlin")) engine.eval(""" @file:DependsOn("org.jetbrains.kotlinx:kotlinx-html-jvm:0.8.0") import kotlinx.html.*; import kotlinx.html.stream.*; import kotlinx.html.attributes.* print(createHTML().html { body { h1 { +"Hello, ${"$"}{params.name}!" } } })""".trimIndent() ) }

Slide 33

Slide 33 text

Kotlin Script 활용하기 코딩 테스트 사용자가 작성한 코드를 실행, 채점 import javax.script.ScriptEngineManager fun main() { val engine = ScriptEngineManager().getEngineByExtension("main.kts")!! val solutionCode = "fun solution(a: Int, b: Int) = a + b" engine.put("args", arrayOf(1, 5)) engine.put("answer", 6) engine.eval(""" $solutionCode println(solution(args[0] as Int, args[1] as Int) == answer) """.trimIndent() ) }

Slide 34

Slide 34 text

Kotlin Script 활용하기 Toy Project: Ruby Warrior Ruby를 이용하여 퍼즐을 푸는 게임 적절한 스크립트를 작성하여 문제를 해결할 수 있다. WarriorJS, Python Warrior 등 파생 프로젝트로 존재 사용자가 입력한 코드를 실행할 수 있어야함

Slide 35

Slide 35 text

Conclusion

Slide 36

Slide 36 text

Kotlin Script 활용하기 실험 단계지만 쓰려면 잘 쓸 수 있을 것 같다! 다른 스크립트 언어를 대체할 수 있는가? 아직 많이 부족하다 팀 내부에서 협의하고 쓰는건 괜찮을지도? 팀이 코틀린을 주력으로 사용한다면… ex) Spring 서버팀, Android 팀 등 그렇지만 Embedded Scripting은 아직 쓰기엔 많이 애매하다 Stable 단계가 아니라는 점이 가장 크다 Usecase가 애매하다 빌드 타임을 줄이는 용도로 UI나 설정 등에는 쓸 수 있을지도? 게임 개발에서 Lua 같은 사례

Slide 37

Slide 37 text

No content