(Kotlin/코틀린) Kotlin Script (.kts) 활용


1. Kotlin Script란?

.kts 확장자를 사용하는 스크립트 파일로, 클래스 선언 없이 최상위 레벨에서 바로 코드를 실행할 수 있습니다.

// hello.kts
val name = "Kotlin"
println("Hello, $name!")

for (i in 1..5) {
    println("카운트: $i")
}
# 실행
kotlinc -script hello.kts

2. .kt vs .kts 차이

구분 .kt .kts
실행 방식 컴파일 후 실행 인터프리터식 직접 실행
최상위 코드 main() 함수 필요 바로 작성 가능
주요 용도 앱/라이브러리 개발 빌드 스크립트, 자동화
대표 파일 Main.kt build.gradle.kts

3. 기본 문법 — 최상위 레벨 실행

// script.kts

// 변수와 출력
val message = "스크립트 실행 중"
println(message)

// 함수 정의
fun greet(name: String) = "안녕하세요, $name!"
println(greet("Kotlin"))

// 클래스 사용
data class Point(val x: Int, val y: Int)
val p = Point(3, 4)
println("거리: ${Math.sqrt((p.x * p.x + p.y * p.y).toDouble())}")

// 컬렉션 처리
val numbers = (1..10).toList()
val evens = numbers.filter { it % 2 == 0 }
println("짝수: $evens")

4. 커맨드라인 인수 처리

// args.kts
if (args.isEmpty()) {
    println("사용법: kotlinc -script args.kts <이름>")
} else {
    val name = args[0]
    println("안녕하세요, $name!")
}
kotlinc -script args.kts Alice
# 안녕하세요, Alice!

5. 파일 처리 자동화 스크립트

// rename_files.kts
import java.io.File

val targetDir = File(args.getOrElse(0) { "." })
val extension = args.getOrElse(1) { "txt" }

targetDir.listFiles { file ->
    file.extension == extension
}?.forEach { file ->
    val newName = file.nameWithoutExtension.lowercase().replace(" ", "_") + ".${extension}"
    val newFile = File(file.parent, newName)
    if (file.name != newName) {
        file.renameTo(newFile)
        println("${file.name} → $newName")
    }
}
kotlinc -script rename_files.kts ./documents txt

6. Gradle Kotlin DSL — build.gradle.kts

가장 널리 쓰이는 .kts 활용 사례입니다.

// build.gradle.kts
plugins {
    kotlin("android") version "1.9.0"
    id("com.android.application")
}

android {
    compileSdk = 34
    defaultConfig {
        applicationId = "com.example.app"
        minSdk = 24
        targetSdk = 34
        versionCode = 1
        versionName = "1.0"
    }
    buildTypes {
        release {
            isMinifyEnabled = true
            proguardFiles(
                getDefaultProguardFile("proguard-android-optimize.txt"),
                "proguard-rules.pro"
            )
        }
    }
    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_17
        targetCompatibility = JavaVersion.VERSION_17
    }
}

dependencies {
    implementation("androidx.core:core-ktx:1.12.0")
    implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.7.0")
}

Groovy DSL(build.gradle) 대비 장점: 타입 안전, IDE 자동완성, 리팩토링 지원


7. 버전 카탈로그와 함께 사용

// libs.versions.toml
[versions]
kotlin = "1.9.0"
compose = "1.5.0"

[libraries]
compose-ui = { group = "androidx.compose.ui", name = "ui", version.ref = "compose" }

// build.gradle.kts에서 참조
dependencies {
    implementation(libs.compose.ui)  // 타입 안전하게 접근
}

8. buildSrc — 공유 빌드 로직

멀티 모듈 프로젝트에서 빌드 설정을 공유할 때 사용합니다.

project/
├── buildSrc/
│   ├── build.gradle.kts
│   └── src/main/kotlin/
│       └── AppConfig.kt       ← 공유 상수
├── app/
│   └── build.gradle.kts
└── core/
    └── build.gradle.kts
// buildSrc/src/main/kotlin/AppConfig.kt
object AppConfig {
    const val minSdk = 24
    const val targetSdk = 34
    const val compileSdk = 34
    const val versionCode = 1
    const val versionName = "1.0.0"
}

object Versions {
    const val kotlin = "1.9.0"
    const val hilt = "2.48"
}
// app/build.gradle.kts
android {
    compileSdk = AppConfig.compileSdk
    defaultConfig {
        minSdk = AppConfig.minSdk
        targetSdk = AppConfig.targetSdk
    }
}

9. kscript — 의존성 추가 스크립트

kscript를 사용하면 외부 라이브러리를 스크립트에서 직접 사용할 수 있습니다.

#!/usr/bin/env kscript

// 의존성 선언
@file:DependsOn("com.squareup.okhttp3:okhttp:4.12.0")

import okhttp3.OkHttpClient
import okhttp3.Request

val client = OkHttpClient()
val request = Request.Builder()
    .url("https://api.github.com/repos/JetBrains/kotlin")
    .build()

val response = client.newCall(request).execute()
println(response.body?.string()?.take(200))
# 설치
brew install kscript

# 실행
kscript fetch_repo.kts

10. 정리



Related Posts