build.gradle.ktsに移行する! Tips編
以前記事にしたプロジェクトをbuild.gradleからkotlin-dslに移行します。
build.gradle.ktsにすることでスクリプト内でKotlinを使えるようになるし、IntelliJの補完が賢くなるし、groovyの文法をいちいちググらなくてよくなります。Spring Initializrでのデフォルトもktsになっていますし、やるしかねえぞこれ
で、気合で一気にやりました。変換結果はこちら
以下、自分用のメモとしてTipsを記載しておきます。
変換TIPS
kotlin plugins
// groovy // plugins { // id 'org.jetbrains.kotlin.jvm' version '1.3.50' // id 'org.jetbrains.kotlin.plugin.spring' version '1.3.50' // id 'org.jetbrains.kotlin.plugin.jpa' version '1.3.50' // } // kotlin plugins { kotlin("jvm") version "1.3.50" kotlin("plugin.spring") version "1.3.50" kotlin("plugin.jpa") version "1.3.50" }
implementation
カッコで括ってあげる。StringはKotlinなのでダブルクォーテーション
testImplementationとかtestRuntimeOnlyとかも同じ感じ
//groovy // implementation project(':domain') // implementation 'com.fasterxml.jackson.module:jackson-module-kotlin:2.9.9' // kotlin implementation(project(":domain")) implementation("com.fasterxml.jackson.module:jackson-module-kotlin:2.9.9")
apply
// groovy // apply plugin: 'kotlin' // apply from: 'test.gradle' // kotlin apply(plugin = "kotlin") apply(from = "test.gradle.kts")
拡張プロパティ
拡張プロパティに値を設定する場合、以下のようにする。by extraでdelegationを使うのがkotlinっぽくてかっこいい
// groovy // ext.versions = [ // 'springBoot': '2.2.0.M6' // ] // kotlin extra["versions"] = mapOf( "springBoot" to "2.2.0.M6" ) // または val versions by extra { mapOf( "springBoot" to "2.2.0.M6" ) }
これで、.gradleのときと同様に、拡張プロパティとproject propertyに値がセットされる。
// 呼び出す val versions: Map<String, String> by extra // 拡張プロパティのscopeから外れた場合、projectからも取得可能 // val versions: Map<String, String> by project implementation("org.springframework.boot:spring-boot-starter-webflux:${versions["springBoot"]}")
他ファイル定義の関数を起動する
kotlinの関数参照を利用します
// test.gradle.kts fun test() = "my test method" // 関数参照 val test: () -> String = ::test // 関数参照を拡張プロパティにセット val testFunc by extra { test } // build.gradle.kts tasks.register("myTask") { // 他ファイルを読み込む apply(from = "test.gradle.kts") doFirst { val testFunc: () -> String by project println(testFunc()) // "my test method" } }
taskを定義する
いろんな書き方ができて面白い
// tasks.registerを使う tasks.register("myTask") { doFirst { println("myTask") } } // typeを指定する tasks { withType<KotlinCompile> { kotlinOptions { freeCompilerArgs = listOf("-Xjsr305=strict") jvmTarget = "1.8" } } }
// 個別定義もできる tasks.withType<KotlinCompile> { kotlinOptions { freeCompilerArgs = listOf("-Xjsr305=strict") jvmTarget = "1.8" } }
// delegationも使える val compileKotlin: KotlinCompile by tasks compileKotlin.kotlinOptions { freeCompilerArgs = listOf("-Xjsr305=strict") jvmTarget = "1.8" } val compileTestKotlin: KotlinCompile by tasks compileTestKotlin.kotlinOptions { freeCompilerArgs = listOf("-Xjsr305=strict") jvmTarget = "1.8" }
// こんな書き方もOK. classpathはconfigurationsで定義したktlintを指定してもok (下のTips参照) task("ktlint", JavaExec::class) { group = "verification" description = "Check Kotlin code style." classpath = configurations.getByName("ktlint") main = "com.pinterest.ktlint.Main" args = listOf("adapters/**/*.kt", "application/**/*.kt", "configuration/**/*.kt", "domain/**/*.kt") }
// tasks.registerでtypeも指定できる tasks.register<JavaExec>("ktlint") { group = "verification" description = "Check Kotlin code style." classpath = configurations.getByName("ktlint") main = "com.pinterest.ktlint.Main" args = listOf("adapters/**/*.kt", "application/**/*.kt", "configuration/**/*.kt", "domain/**/*.kt") }
taskにdependsOnを追加
// groovy // task myNextTask(dependsOn: 'myTask') { // doFirst { // println('nextTask') // } // } // kotlin tasks.register("myNextTask") { dependsOn("myTask") doFirst { println("nextTask") } }
定義済みTaskに属性を追加
// check taskに依存を追加する tasks.named("check") { dependsOn(ktlint) } // type指定 tasks.getByName<BootJar>("bootJar") { mainClassName = "com.example.demo.DemoApplicationKt" }
configurationsに追加
configurations.creating をdelegate
// groovy // configurations { // ktlint // } // dependencies { // ktlint "com.pinterest:ktlint:0.34.2" // } // kotlin val ktlint: Configuration by configurations.creating dependencies { ktlint("com.pinterest:ktlint:0.34.2") }
project propertyの取得
// gradle.properties foo=bar // groovy // def fooValue = hasProperty('foo') ? getProperty('foo') : '' // kotlin val fooValue = if (hasProperty("foo")) findProperty("foo") as String else ""
multi-projectでkotlinを適用
https://github.com/gradle/kotlin-dsl-samples/blob/master/samples/multi-kotlin-project-config-injection/build.gradle.kts 参照 configureEachを入れなくても設定されているようにも見えるのでちょっとわからん。
subproject { tasks { withType<KotlinCompile>().configureEach { kotlinOptions { freeCompilerArgs = listOf("-Xjsr305=strict") jvmTarget = "1.8" } } } }
その他 (適当に思いついたら記載)
// configurationsの定義とか // groovy // configurations { // all*.exclude module: 'spring-boot-starter-logging' // } // kotlin configurations { // allとかruntimeとかetc.. all { exclude(module = "spring-boot-starter-logging") } } // project 呼び出しとか // groovy // def configuration = project("configuration") // kotlin val configuration = project("configuration")
まとめ
困ったら kotlin-dsl-samples を見ると答えが書いてあることが。あとIntelliJの補完が優秀なので、とりあえず候補を出すと解決します。
実際のKotlin codeをIntelliJで読むと何しているのか結構わかったりすることがあります。