使用Gradle执行Kotlin脚本

将Kotlin脚本组织为Gradle任务

在本文中,您将学习如何将多个Kotlin脚本组织为Gradle任务,并使它们易于以这种方式执行。我已经找到关于此的讨论 这里. Somebody wanted to execute Kotlin scripts with Gradle build scripts which is, of course, possible 通过 using kotlinc as shown in 这个 (Groovy)构建脚本。但是,这看起来并不十分漂亮,并且如相应线程中所述,它也不是很高效且不可管理。另一个解决方案是使用用 Kotlin DSL and define custom tasks within a build.gradle.kts file, which obviously can hold and run Kotlin code naturally:

// build.gradle.kts
//
// Execute Kotlin task with:  gradle  -q foo

task("foo") {
  group = "com.kotlinexpertise"
  description = "my foo task"
  doLast {
    println("Hello from foo task")
  }
}

The problem with 这个 approach is that, in my case, I had multiple large Kotlin scripts I wanted to make executable 这个 way. If I had put all of them into tasks, the script would have been too bloated and hard to maintain. Note that in my case, these tasks would not contribute to the build logic directly but rather provide business-relevant tasks, which I wanted to make executable via Gradle.

Gradle buildSrc to the rescue

如中所述 Gradle文档, build logic and especially custom tasks shouldn't live within the build script directly. Gradle, therefore, offers the possibility to use a so-called buildSrc directory. This directory is treated as an included build, i.e. Gradle automatically compiles and tests 这个 code and makes it available on the build script classpath. The following shows a typical project structure using 这个 special buildSrc directory:

├── build.gradle //main build
├── buildSrc
│   ├── build.gradle //build for buildSrc
│   └── src //custom plugins, taks etc.
│       ├── main
│       │   └── java
│       │       └── com
│       │           └── enterprise
│       │               ├── Deploy.java
│       │               └── DeploymentPlugin.java
│       └── test
│           └── java
│               └── com
│                   └── enterprise
│                       └── DeploymentPluginTest.java
└── settings.gradle

As you can see 这里, the buildSrc has its own build.gradle, in which we define dependencies and plugins for buildSrc itself. As mentioned, the compiled code will be available for the surrounding build so that you can for instance define custom tasks in the buildSrc and use them in the main build.gradle.

Kotlin示例:使用Gradle执行Kotlin脚本

假设我们有两个较大的任务要作为Gradle任务使用,分别称为task1和task2。两项任务都非常适合与Kotlin一起实施。

原始项目构建如下所示:

import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

plugins {
    kotlin("jvm") version "1.2.51"
}

java.sourceSets {
    getByName("main").java.srcDirs("...")
}

repositories {
    mavenCentral()
}

dependencies {
    compile(kotlin("stdlib-jdk8"))
}

tasks.withType<KotlinCompile> {
    kotlinOptions.jvmTarget = "1.8"
}

This is very basic and there's nothing special in it. Now, the goal is to define two custom tasks taks1 and task2 within 这个 script. Both tasks are supposed to be executable via gradle -q task1|task2. To make 这个 possible, we create the buildSrc directory structure as shown above on the same level the build script already exists. Within the buildSrc, we now create the custom tasks as Kotlin classes:

package com.kotlinexpertise.tasks

import org.gradle.api.DefaultTask
import org.gradle.api.tasks.TaskAction
import java.sql.DriverManager

open class Task1 : DefaultTask() {

    init {
        group = "com.kotlinexpertise"
        description = "task1"
    }

    @TaskAction
    fun run() {
        Class.forName("com.mysql.jdbc.Driver")
        //heavy task implementation
    }
}

Just like we would define a task within a Gradle build script directly, we define group, description and the task itself in a method annotated with TaskAction, which we call run. Learn more about custom tasks 这里. To make 这个 a bit more interesting, we want to load a MySQL driver in 这个 task, which requires us to make the corresponding dependency available for the buildSrc build. Let's take a look at its build script (existing directly in buildSrc):

plugins {
    `kotlin-dsl`
}

repositories {
    mavenCentral()
}

dependencies {
    compile("mysql:mysql-connector-java:5.1.24")
}

As mentioned, we add the dependencies we want to use within the buildSrc. Another thing to note is that the org.gradle.kotlin.kotlin-dsl plugin is applied to 这个 build in order to set up the Kotlin compiler features and dependencies to match the ones shipped with Gradle. We used the nicer alias kotlin-dsl in 这个 example.

Now, after defining both Task1 and Task2 as subclasses of DefaultTask, they can be used in the main build.gradle.kts script like 这个:

import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import com.kotlinexpertise.tasks.*

//...

task<Task1>("task1")
task<Task1>("task2")

//...

Note that both probably need to be imported as shown 这里. In the console, gradle tasks will list them, and you can execute them 通过 running gradle -q task1 and gradle -q task2 respectively. You can also see the tasks listed in IntelliJ IDEA:

gradle_idea

源代码可以在这里找到: //github.com/s1monw1/gradle_buildSrc_kotlin

您可能想阅读其他 文章 有关Gradle Kotlin DSL的信息,以获取有关该主题的更多信息。请享用。

发表评论

您的电子邮件地址不会被公开。 必需的地方已做标记 *