Kotlinカスタムスクリプトの始め方 – チュートリアル
Kotlinカスタムスクリプトは実験的です。これは予告なく廃止または変更される可能性があります。 評価目的のみにご使用ください。YouTrackでフィードバックをお待ちしております。
_Kotlinスクリプト_は、Kotlinコードを事前コンパイルや実行可能ファイルへのパッケージングなしにスクリプトとして実行可能にする技術です。
Kotlinスクリプトの概要と例については、KotlinConf'19でのRodrigo Oliveira氏によるトークImplementing the Gradle Kotlin DSLをご覧ください。
このチュートリアルでは、Maven依存関係を持つ任意の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リポジトリまたはローカルキャッシュから解決され、スクリプトの残りの部分で使用されます。
プロジェクト構造
最小限のKotlinカスタムスクリプトプロジェクトは、2つの部分で構成されます。
- スクリプト定義 – このスクリプトタイプがどのように認識され、処理され、コンパイルされ、実行されるかを定義する、パラメーターと構成のセット。
- スクリプトホスト – スクリプトのコンパイルと実行を処理するアプリケーションまたはコンポーネント。実際にこのタイプのスクリプトを実行します。
これらすべてを考慮すると、プロジェクトを2つのモジュールに分割するのが最善です。
始める前に
IntelliJ IDEAの最新バージョンをダウンロードしてインストールしてください。
プロジェクトを作成する
IntelliJ IDEAで、File | New | Projectを選択します。
左側のパネルで、New Projectを選択します。
新しいプロジェクトに名前を付け、必要に応じてその場所を変更します。
Create Git repositoryチェックボックスを選択して、新しいプロジェクトをバージョン管理下に置きます。後からいつでも行うことができます。
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を選択します。
- モジュールの親として、ルートモジュールを選択します。
- Createをクリックします。
モジュールの
build.gradle(.kts)
ファイルで、Kotlin Gradleプラグインのversion
を削除します。これはすでにルートプロジェクトのビルドスクリプトに含まれています。前のステップをもう一度繰り返して、スクリプトホスト用のモジュールを作成します。
プロジェクトは次の構造になっているはずです。
このようなプロジェクトの例やその他のKotlinスクリプトの例は、kotlin-script-examples GitHubリポジトリで見つけることができます。
スクリプト定義を作成する
まず、スクリプトタイプを定義します。開発者がこのタイプのスクリプトで何を書けるか、そしてそれがどのように処理されるかです。 このチュートリアルでは、スクリプト内の@Repository
および@DependsOn
アノテーションのサポートが含まれます。
スクリプト定義モジュールで、
build.gradle(.kts)
のdependencies
ブロックにKotlinスクリプトコンポーネントへの依存関係を追加します。これらの依存関係は、スクリプト定義に必要なAPIを提供します。kotlindependencies { 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") // coroutines dependency is required for this particular definition implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.2") }
groovydependencies { 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' // coroutines dependency is required for this particular definition implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.2' }
モジュール内に
src/main/kotlin/
ディレクトリを作成し、例えばscriptDef.kt
のようなKotlinソースファイルを追加します。scriptDef.kt
でクラスを作成します。これは、このタイプのスクリプトのスーパークラスになるため、abstract
またはopen
として宣言します。kotlin// abstract (or open) superclass for scripts of this type abstract class ScriptWithMavenDeps
このクラスは、後でスクリプト定義への参照としても機能します。
クラスをスクリプト定義にするには、
@KotlinScript
アノテーションでマークします。アノテーションに2つのパラメーターを渡します。fileExtension
– このスクリプトタイプのファイル拡張子を定義する、.kts
で終わる文字列です。compilationConfiguration
–ScriptCompilationConfiguration
を拡張し、このスクリプト定義のコンパイルの詳細を定義するKotlinクラスです。これは次のステップで作成します。
kotlin// @KotlinScript annotation marks a script definition class @KotlinScript( // File extension for the script type fileExtension = "scriptwithdeps.kts", // Compilation configuration for the script type compilationConfiguration = ScriptWithMavenDepsConfiguration::class ) abstract class ScriptWithMavenDeps object ScriptWithMavenDepsConfiguration: ScriptCompilationConfiguration()
このチュートリアルでは、KotlinスクリプトAPIの説明なしに、動作するコードのみを提供します。 詳細な説明付きの同じコードはGitHubで見つけることができます。
以下に示すように、スクリプトコンパイル構成を定義します。
kotlinobject ScriptWithMavenDepsConfiguration : ScriptCompilationConfiguration( { // Implicit imports for all scripts of this type defaultImports(DependsOn::class, Repository::class) jvm { // Extract the whole classpath from context classloader and use it as dependencies dependenciesFromCurrentContext(wholeClasspath = true) } // Callbacks refineConfiguration { // Process specified annotations with the provided handler onAnnotations(DependsOn::class, Repository::class, handler = ::configureMavenDepsOnAnnotations) } } )
configureMavenDepsOnAnnotations
関数は次のとおりです。kotlin// Handler that reconfigures the compilation on the fly 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スクリプトコンポーネント
- 以前に作成したスクリプト定義モジュール
kotlindependencies { 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")) // the script definition module }
groovydependencies { 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') // the script definition module }
モジュール内に
src/main/kotlin/
ディレクトリを作成し、例えばhost.kt
のようなKotlinソースファイルを追加します。アプリケーションの
main
関数を定義します。その本体では、スクリプトファイルへのパスという1つの引数があることを確認し、スクリプトを実行します。次のステップで、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!" } } } )
これは
kotlinx-html-jvm
ライブラリの関数を使用しており、これは@DependsOn
アノテーションの引数で参照されています。スクリプトホストを起動し、このファイルを実行する実行構成を作成します。
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を視聴する