Kotlin 커스텀 스크립팅 시작하기 – 튜토리얼
DANGER
Kotlin 커스텀 스크립팅은 실험적 기능입니다. 언제든지 삭제되거나 변경될 수 있습니다.
평가 목적으로만 사용하십시오. YouTrack에 대한 피드백을 주시면 감사하겠습니다.
_Kotlin 스크립팅_은 Kotlin 코드를 사전 컴파일하거나 실행 파일로 패키징할 필요 없이 스크립트로 실행할 수 있게 해주는 기술입니다.
Kotlin 스크립팅에 대한 개요와 예시를 보려면 KotlinConf'19에서 Rodrigo Oliveira의 강연인 Implementing the Gradle Kotlin DSL을 확인하십시오.
이 튜토리얼에서는 Maven 종속성(dependencies)을 사용하여 임의의 Kotlin 코드를 실행하는 Kotlin 스크립팅 프로젝트를 생성합니다. 다음과 같은 스크립트를 실행할 수 있습니다:
@file:Repository("https://maven.pkg.jetbrains.space/public/p/kotlinx-html/maven")
@file:DependsOn("org.jetbrains.kotlinx:kotlinx-html-jvm:0.7.3")
import kotlinx.html.*
import kotlinx.html.stream.*
import kotlinx.html.attributes.*
val addressee = "World"
print(
createHTML().html {
body {
h1 { +"Hello, $addressee!" }
}
}
)
지정된 Maven 종속성(이 예시에서는 kotlinx-html-jvm
)은 실행 중에 지정된 Maven 저장소 또는 로컬 캐시에서 해결(resolve)되고 스크립트의 나머지 부분에 사용됩니다.
프로젝트 구조
최소한의 Kotlin 커스텀 스크립팅 프로젝트는 다음 두 부분으로 구성됩니다:
- 스크립트 정의 – 이 스크립트 유형이 인식되고, 처리되고, 컴파일되고, 실행되는 방식을 정의하는 매개변수 및 구성 세트입니다.
- 스크립팅 호스트 – 스크립트 컴파일 및 실행을 처리하는 애플리케이션 또는 구성 요소로, 실제로 이 유형의 스크립트를 실행합니다.
이 모든 점을 고려할 때, 프로젝트를 두 개의 모듈로 분할하는 것이 가장 좋습니다.
시작하기 전에
최신 버전의 IntelliJ IDEA를 다운로드하여 설치하십시오.
프로젝트 생성
IntelliJ IDEA에서 File | New | Project를 선택하십시오.
왼쪽 패널에서 New Project를 선택하십시오.
새 프로젝트의 이름을 지정하고 필요한 경우 위치를 변경하십시오.
TIP
Git 저장소 생성 확인란을 선택하여 새 프로젝트를 버전 관리 하에 둘 수 있습니다. 이 작업은 나중에 언제든지 수행할 수 있습니다.
Language 목록에서 Kotlin을 선택하십시오.
Gradle 빌드 시스템을 선택하십시오.
JDK 목록에서 프로젝트에 사용할 JDK를 선택하십시오.
- JDK가 컴퓨터에 설치되어 있지만 IDE에 정의되어 있지 않은 경우, Add JDK를 선택하고 JDK 홈 디렉토리의 경로를 지정하십시오.
- 컴퓨터에 필요한 JDK가 없는 경우, Download JDK를 선택하십시오.
Gradle DSL에 사용할 Kotlin 또는 Gradle 언어를 선택하십시오.
Create를 클릭하십시오.
스크립팅 모듈 추가
이제 빈 Kotlin/JVM Gradle 프로젝트가 있습니다. 필요한 모듈인 스크립트 정의와 스크립팅 호스트를 추가하십시오:
IntelliJ IDEA에서 File | New | Module을 선택하십시오.
왼쪽 패널에서 New Module을 선택하십시오. 이 모듈은 스크립트 정의가 됩니다.
새 모듈의 이름을 지정하고 필요한 경우 위치를 변경하십시오.
Language 목록에서 Java를 선택하십시오.
빌드 스크립트를 Kotlin으로 작성하려면 Gradle 빌드 시스템과 Gradle DSL에 Kotlin을 선택하십시오.
모듈의 상위(parent)로 루트 모듈을 선택하십시오.
Create를 클릭하십시오.
모듈의
build.gradle(.kts)
파일에서 Kotlin Gradle 플러그인의version
을 제거하십시오. 이는 이미 루트 프로젝트의 빌드 스크립트에 있습니다.스크립팅 호스트를 위한 모듈을 생성하려면 이전 단계를 한 번 더 반복하십시오.
프로젝트는 다음 구조를 가져야 합니다:
이러한 프로젝트의 예시와 더 많은 Kotlin 스크립팅 예시는 kotlin-script-examples GitHub 저장소에서 찾을 수 있습니다.
스크립트 정의 생성
먼저 스크립트 유형을 정의하십시오: 이 유형의 스크립트에 개발자가 무엇을 작성할 수 있고, 어떻게 처리될지를 정의합니다. 이 튜토리얼에서는 스크립트에서 @Repository
및 @DependsOn
애노테이션(annotations)에 대한 지원이 포함됩니다.
스크립트 정의 모듈의
build.gradle(.kts)
파일의dependencies
블록에 Kotlin 스크립팅 구성 요소에 대한 종속성을 추가하십시오. 이 종속성들은 스크립트 정의에 필요한 API를 제공합니다:
dependencies {
implementation("org.jetbrains.kotlin:kotlin-scripting-common")
implementation("org.jetbrains.kotlin:kotlin-scripting-jvm")
implementation("org.jetbrains.kotlin:kotlin-scripting-dependencies")
implementation("org.jetbrains.kotlin:kotlin-scripting-dependencies-maven")
// 이 특정 정의에는 코루틴 종속성이 필요합니다.
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.2")
}
dependencies {
implementation 'org.jetbrains.kotlin:kotlin-scripting-common'
implementation 'org.jetbrains.kotlin:kotlin-scripting-jvm'
implementation 'org.jetbrains.kotlin:kotlin-scripting-dependencies'
implementation 'org.jetbrains.kotlin:kotlin-scripting-dependencies-maven'
// 이 특정 정의에는 코루틴 종속성이 필요합니다.
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.2'
}
:::
모듈에
src/main/kotlin/
디렉터리를 생성하고, 예를 들어scriptDef.kt
와 같은 Kotlin 소스 파일을 추가하십시오.scriptDef.kt
파일에 클래스를 생성하십시오. 이 클래스는 이 유형의 스크립트에 대한 상위 클래스(superclass)가 되므로,abstract
또는open
으로 선언하십시오.kotlin// 이 유형의 스크립트를 위한 abstract (또는 open) 상위 클래스 abstract class ScriptWithMavenDeps
이 클래스는 나중에 스크립트 정의에 대한 참조 역할을 합니다.
이 클래스를 스크립트 정의로 만들려면
@KotlinScript
애노테이션으로 표시하십시오. 이 애노테이션에 다음 두 가지 매개변수를 전달하십시오:fileExtension
– 이 스크립트 유형의 파일 확장자를 정의하는.kts
로 끝나는 문자열입니다.compilationConfiguration
–ScriptCompilationConfiguration
을 확장하고 이 스크립트 정의에 대한 컴파일 세부 정보를 정의하는 Kotlin 클래스입니다. 다음 단계에서 생성합니다.
kotlin// @KotlinScript 애노테이션은 스크립트 정의 클래스를 표시합니다. @KotlinScript( // 스크립트 유형의 파일 확장자 fileExtension = "scriptwithdeps.kts", // 스크립트 유형의 컴파일 구성 compilationConfiguration = ScriptWithMavenDepsConfiguration::class ) abstract class ScriptWithMavenDeps object ScriptWithMavenDepsConfiguration: ScriptCompilationConfiguration()
아래에 표시된 대로 스크립트 컴파일 구성을 정의하십시오.
kotlinobject ScriptWithMavenDepsConfiguration : ScriptCompilationConfiguration( { // 이 유형의 모든 스크립트에 대한 암시적 임포트 defaultImports(DependsOn::class, Repository::class) jvm { // 컨텍스트 클래스 로더에서 전체 클래스패스를 추출하여 종속성으로 사용 dependenciesFromCurrentContext(wholeClasspath = true) } // 콜백 refineConfiguration { // 제공된 핸들러로 지정된 애노테이션 처리 onAnnotations(DependsOn::class, Repository::class, handler = ::configureMavenDepsOnAnnotations) } } )
configureMavenDepsOnAnnotations
함수는 다음과 같습니다:kotlin// 컴파일을 즉석에서 재구성하는 핸들러 fun configureMavenDepsOnAnnotations(context: ScriptConfigurationRefinementContext): ResultWithDiagnostics<ScriptCompilationConfiguration> { val annotations = context.collectedData?.get(ScriptCollectedData.collectedAnnotations)?.takeIf { it.isNotEmpty() } ?: return context.compilationConfiguration.asSuccess() return runBlocking { resolver.resolveFromScriptSourceAnnotations(annotations) }.onSuccess { context.compilationConfiguration.with { dependencies.append(JvmDependency(it)) }.asSuccess() } } private val resolver = CompoundDependenciesResolver(FileSystemDependenciesResolver(), MavenDependenciesResolver())
전체 코드는 여기에서 찾을 수 있습니다.
스크립팅 호스트 생성
다음 단계는 스크립팅 호스트, 즉 스크립트 실행을 처리하는 구성 요소를 생성하는 것입니다.
스크립팅 호스트 모듈의
build.gradle(.kts)
파일의dependencies
블록에 다음 종속성을 추가하십시오:- 스크립팅 호스트에 필요한 API를 제공하는 Kotlin 스크립팅 구성 요소
- 이전에 생성한 스크립트 정의 모듈
dependencies {
implementation("org.jetbrains.kotlin:kotlin-scripting-common")
implementation("org.jetbrains.kotlin:kotlin-scripting-jvm")
implementation("org.jetbrains.kotlin:kotlin-scripting-jvm-host")
implementation(project(":script-definition")) // 스크립트 정의 모듈
}
dependencies {
implementation 'org.jetbrains.kotlin:kotlin-scripting-common'
implementation 'org.jetbrains.kotlin:kotlin-scripting-jvm'
implementation 'org.jetbrains.kotlin:kotlin-scripting-jvm-host'
implementation project(':script-definition') // 스크립트 정의 모듈
}
:::
모듈에
src/main/kotlin/
디렉터리를 생성하고, 예를 들어host.kt
와 같은 Kotlin 소스 파일을 추가하십시오.애플리케이션의
main
함수를 정의하십시오. 본문에서 스크립트 파일의 경로인 하나의 인수가 있는지 확인하고 스크립트를 실행하십시오. 다음 단계에서 별도의 함수evalFile
에서 스크립트 실행을 정의할 것입니다. 지금은 비어 있는 함수로 선언하십시오.main
함수는 다음과 같습니다:kotlinfun main(vararg args: String) { if (args.size != 1) { println("usage: <app> <script file>") } else { val scriptFile = File(args[0]) println("Executing script $scriptFile") evalFile(scriptFile) } }
스크립트 평가 함수를 정의하십시오. 여기에서 스크립트 정의를 사용할 것입니다. 스크립트 정의 클래스를 타입 매개변수로 사용하여
createJvmCompilationConfigurationFromTemplate
를 호출하여 스크립트 정의를 얻으십시오. 그런 다음 스크립트 코드와 컴파일 구성을 전달하여BasicJvmScriptingHost().eval
을 호출하십시오.eval
은ResultWithDiagnostics
의 인스턴스를 반환하므로, 이를 함수의 반환 타입으로 설정하십시오.kotlinfun evalFile(scriptFile: File): ResultWithDiagnostics<EvaluationResult> { val compilationConfiguration = createJvmCompilationConfigurationFromTemplate<ScriptWithMavenDeps>() return BasicJvmScriptingHost().eval(scriptFile.toScriptSource(), compilationConfiguration, null) }
스크립트 실행에 대한 정보를 출력하도록
main
함수를 조정하십시오:kotlinfun main(vararg args: String) { if (args.size != 1) { println("usage: <app> <script file>") } else { val scriptFile = File(args[0]) println("Executing script $scriptFile") val res = evalFile(scriptFile) res.reports.forEach { if (it.severity > ScriptDiagnostic.Severity.DEBUG) { println(" : ${it.message}" + if (it.exception == null) "" else ": ${it.exception}") } } } }
전체 코드는 여기에서 찾을 수 있습니다.
스크립트 실행
스크립팅 호스트가 어떻게 작동하는지 확인하려면 실행할 스크립트와 실행 구성을 준비하십시오.
프로젝트 루트 디렉터리에 다음 내용을 포함하는
html.scriptwithdeps.kts
파일을 생성하십시오:kotlin@file:Repository("https://maven.pkg.jetbrains.space/public/p/kotlinx-html/maven") @file:DependsOn("org.jetbrains.kotlinx:kotlinx-html-jvm:0.7.3") import kotlinx.html.*; import kotlinx.html.stream.*; import kotlinx.html.attributes.* val addressee = "World" print( createHTML().html { body { h1 { +"Hello, $addressee!" } } } )
이는
@DependsOn
애노테이션(annotation) 인수에 참조된kotlinx-html-jvm
라이브러리의 함수를 사용합니다.스크립팅 호스트를 시작하고 이 파일을 실행하는 실행 구성을 생성하십시오:
host.kt
를 열고main
함수로 이동하십시오. 왼쪽에는 Run 거터 아이콘이 있습니다.거터 아이콘을 마우스 오른쪽 버튼으로 클릭하고 Modify Run Configuration을 선택하십시오.
Create Run Configuration 대화 상자에서 Program arguments에 스크립트 파일 이름을 추가하고 OK를 클릭하십시오.
생성된 구성을 실행하십시오.
스크립트가 실행되고, 지정된 저장소에서 kotlinx-html-jvm
종속성이 해결되며, 해당 함수 호출 결과가 출력되는 것을 볼 수 있습니다:
<html>
<body>
<h1>Hello, World!</h1>
</body>
</html>
종속성을 해결하는 데 첫 실행 시 시간이 다소 소요될 수 있습니다. 이후 실행은 로컬 Maven 저장소에서 다운로드된 종속성을 사용하므로 훨씬 빠르게 완료됩니다.
다음 단계는?
간단한 Kotlin 스크립팅 프로젝트를 생성했다면, 이 주제에 대한 더 많은 정보를 찾아보십시오:
- Kotlin 스크립팅 KEEP을 읽어보십시오.
- 더 많은 Kotlin 스크립팅 예시를 찾아보십시오.
- Rodrigo Oliveira의 강연 Implementing the Gradle Kotlin DSL을 시청하십시오.