在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
开源软件名称(OpenSource Name):jnizet/gradle-kotlin-dsl-migration-guide开源软件地址(OpenSource Url):https://github.com/jnizet/gradle-kotlin-dsl-migration-guide开源编程语言(OpenSource Language):Kotlin 100.0%开源软件介绍(OpenSource Introduction):The missing migration guide to the Gradle Kotlin DSL
In case you didn’t know, Gradle build scripts can be written in Kotlin rather than Groovy. However, as far as I know, the Kotlin DSL has never been properly documented. The closest I found to a documentation is the set of examples in the kotlin-dsl project This README hopefully constitutes the temporary missing guide to migrate from the Groovy DSL to the Kotlin DSL. It assumes you already know the Groovy DSL, and that you’re familiar with the Kotlin language syntax. DisclaimerI’m by no means an expert of Gradle and even less of its Kotlin DSL. What follows is what I understood and tested. There might be better ways of doing, and this guide is not, at all, exhaustive. So issues and PRs are welcome. File namesTo use the Kotlin DSL, simply name your files The In a multi-project build, you can have some modules using the Groovy DSL (and thus use Applying built-in pluginsUsing the Groovy
plugins {
id 'java'
id 'jacoco'
} Kotlin
plugins {
java
id("jacoco")
} As you can see with the But the Kotlin DSL also defines extension properties for all (AFAIK) built-in plugins, so you can use them, as shown above with the You can also use the older Groovy
apply plugin: 'checkstyle' Kotlin
apply(plugin = "checkstyle") Applying external pluginsUsing the Groovy
plugins {
id 'org.springframework.boot' version '2.0.1.RELEASE'
} Kotlin
plugins {
id("org.springframework.boot") version "2.0.1.RELEASE"
} You can also use the older Groovy
buildscript {
repositories {
gradlePluginPortal()
}
dependencies {
classpath("gradle.plugin.com.boxfuse.client:gradle-plugin-publishing:5.0.3")
}
}
apply plugin: 'org.flywaydb.flyway' Kotlin
buildscript {
repositories {
gradlePluginPortal()
}
dependencies {
classpath("gradle.plugin.com.boxfuse.client:gradle-plugin-publishing:5.0.3")
}
}
apply(plugin = "org.flywaydb.flyway") Applying the Kotlin pluginIf you’re using Kotlin to write your build scripts, you probably also use Kotlin in your project. Applying the Kotlin plugin is no different from applying any external other plugin. But the DSL has an extension function to make it shorter: Groovy
plugins {
id 'org.jetbrains.kotlin.jvm' version '1.2.41'
} Kotlin
plugins {
kotlin("jvm") version "1.2.41"
} Customizing an existing taskThis is where Groovy and Kotlin start to differ. Since Kotlin is a statically typed language, and since you want to benefit from this static typing by discovering available properties and methods using auto-completion, you need to know and provide the type of the task you want to configure. Here is how you can configure a single property of the existing Groovy
jar.archiveName = 'foo.jar' Kotlin
val jar: Jar by tasks
jar.archiveName = "foo.jar" Note that specifying the type of the task explicitly is necessary. Otherwise, the script won’t compile because the inferred type of You can, however, omit the type if you only need to configure properties or call methods declared in Groovy
test.doLast {
println("test completed")
} Kotlin
val test by tasks
test.doLast { println("test completed") } If you need to configure several properties or call multiple methods on the same task you can group them in a block as follows: Groovy
jar {
archiveName = 'foo.jar'
into('META-INF') {
from('bar')
}
} Kotlin
val jar by tasks.getting(Jar::class) {
archiveName = "foo.jar"
into("META-INF") {
from("bar")
}
} If you already have a Kotlin
val jar: Jar by tasks
jar.apply {
archiveName = "foo.jar"
into("META-INF") {
from("bar")
}
} But there is another idiomatic way to configure tasks: using a Groovy
jar {
archiveName = 'foo.jar'
into('META-INF') {
from('bar')
}
}
test.doLast {
println("test completed")
} Kotlin
tasks {
"jar"(Jar::class) {
archiveName = "foo.jar"
into("META-INF") {
from("bar")
}
}
"test" {
doLast { println("test completed") }
}
} Once again, note that if you need to apply task-specific configurations, you need to provide the type of the task ( This means that you’ll sometimes need to dive in the documentation or source code of custom plugins to discover what the types of its custom tasks are, and to import them, or use their fully qualified name. Groovy
plugins {
id('java')
id 'org.springframework.boot' version '2.0.1.RELEASE'
}
repositories {
mavenCentral()
}
apply plugin: 'io.spring.dependency-management'
bootJar {
archiveName = 'app.jar'
mainClassName = 'com.ninja_squad.demo.Demo'
}
bootRun {
main = 'com.ninja_squad.demo.Demo'
args '--spring.profiles.active=demo'
} Kotlin
import org.springframework.boot.gradle.tasks.bundling.BootJar
import org.springframework.boot.gradle.tasks.run.BootRun
plugins {
java
id("org.springframework.boot") version "2.0.1.RELEASE"
}
repositories {
mavenCentral()
}
apply(plugin = "io.spring.dependency-management")
tasks {
"bootJar"(BootJar::class) {
archiveName = "app.jar"
mainClassName = "com.ninja_squad.demo.Demo"
}
"bootRun"(BootRun::class) {
main = "com.ninja_squad.demo.Demo"
args("--spring.profiles.active=demo")
}
} Creating a taskCreating a task can be done by declaring delegated property, delegating to Groovy
task greeting {
println('always printed: configuration phase')
doLast {
println('only printed if executed: execution phase')
}
} Kotlin
val greeting by tasks.creating {
println("always printed: configuration phase")
doLast {
println("only printed if executed: execution phase")
}
} Sometimes you want to create a task of a given type ( Groovy
task docZip(type: Zip) {
archiveName = 'doc.zip'
from 'doc'
} Kotlin
val docZip by tasks.creating(Zip::class) {
archiveName = "doc.zip"
from("doc")
} The same things can also be done using the Groovy
task greeting2 {
println('always printed: configuration phase')
doLast {
println('only printed if executed: execution phase')
}
}
task docZip2(type: Zip) {
archiveName = 'doc.zip'
from 'doc'
} Kotlin
tasks {
"greeting2" {
println("always printed: configuration phase")
doLast {
println("only printed if executed: execution phase")
}
}
"docZip2"(Zip::class) {
archiveName = "doc2.zip"
from("doc")
}
} Notice that creating a task uses the exact same syntax as customizing an existing task. This can be confusing, and even lead to bugs: your intention might be to customize an existing task, but if you use the wrong task name, you will end up creating a new task rather than customizing the existing task. The reader might also not know if your intention is to customize an existing task, or to create a new one. For these two reasons, you might prefer using these slightly more verbose variants, which clearly show your intent and avoid the previously described bug: Kotlin
tasks {
// get and customize the existing task named test. Fails if there is no test task.
val test by getting {
doLast { println("test completed") }
}
// create a new docZip3 task. Fails if a task docZip3 already exists.
val docZip3 by creating(Zip::class) {
archiveName = "doc3.zip"
from("doc")
}
} DependenciesDeclaring dependencies in the existing Java configurations is not much different from doing it in Groovy: Groovy
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'io.jsonwebtoken:jjwt:0.9.0'
runtimeOnly 'org.postgresql:postgresql'
testImplementation('org.springframework.boot:spring-boot-starter-test') {
exclude(module: 'junit')
}
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine'
} Kotlin
dependencies {
implementation("org.springframework.boot:spring-boot-starter-web")
implementation("io.jsonwebtoken:jjwt:0.9.0")
runtimeOnly("org.postgresql:postgresql")
testImplementation("org.springframework.boot:spring-boot-starter-test") {
exclude(module = "junit")
}
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine")
} Custom configurationsSometimes you need to add your own configuration, and add dependencies to that configuration: Groovy
configurations {
db
integTestImplementation {
extendsFrom testImplementation
}
}
dependencies {
db 'org.postgresql:postgresql'
integTestImplementation 'com.ninja-squad:DbSetup:2.1.0'
} Kotlin
val db by configurations.creating
val integTestImplementation by configurations.creating {
extendsFrom(configurations["testImplementation"])
}
dependencies {
db("org.postgresql:postgresql")
integTestImplementation("com.ninja-squad:DbSetup:2.1.0")
} Note that, in the above example, you can only use Kotlin
// get the existing testRuntimeOnly configuration
val testRuntimeOnly by configurations
dependencies {
testRuntimeOnly("org.postgresql:postgresql")
"db"("org.postgresql:postgresql")
"integTestImplementation"("com.ninja-squad:DbSetup:2.1.0")
} ExtensionsMany plugins come with extensions to configure them. If those plugins are applied using the On the other hand, if you use the older Groovy
jacoco {
toolVersion = "0.8.1"
}
springBoot {
buildInfo {
properties {
time = null
}
}
}
checkstyle {
maxErrors = 10
} Kotlin
jacoco {
toolVersion = "0.8.1"
}
springBoot {
buildInfo {
properties {
time = null
}
}
}
configure<CheckstyleExtension> {
maxErrors = 10
} |
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论