使用Kotlindsl在buildSrc中修改gradle插件中的任务

lymgl2op  于 2022-12-13  发布在  Kotlin
关注(0)|答案(1)|浏览(229)

我在buildSrc/src/main/kotlin/foo.bar.kts中有一个Gradle插件,我试图在其中修改任务,但这些修改失败。如果我删除任务修改部分,其余部分,即设置存储库,工作正常。
我想我错过了语法如何修改模块中的任务导入此插件。
buildSrc/src/main/kotlin/foo.bar.kts

repositories {
    mavenCentral()
}

tasks.test {
    useJUnitPlatform()
}

tasks.withType<KotlinCompile>() {
    kotlinOptions.jvmTarget = "11"
}

在我的build.gradle.kts中使用插件

plugins {
  id("foo.bar")
}

./gradlew clean build生成的错误

> Task :buildSrc:compileKotlin FAILED
e: /some/path/buildSrc/src/main/kotlin/foo.bar.gradle.kts: (8, 7): Unresolved reference: test
e: /some/path/buildSrc/src/main/kotlin/foo.bar.gradle.kts: (9, 5): Unresolved reference: useJUnitPlatform
e: /some/path/buildSrc/src/main/kotlin/foo.bar.gradle.kts: (12, 16): Unresolved reference: KotlinCompile
e: /some/path/buildSrc/src/main/kotlin/foo.bar.gradle.kts: (12, 33): Type mismatch: inferred type is () -> Unit but Class<TypeVariable(S)!> was expected
e: /some/path/buildSrc/src/main/kotlin/foo.bar.gradle.kts: (13, 5): Unresolved reference: kotlinOptions
e: /some/path/code/buildSrc/src/main/kotlin/foo.bar.gradle.kts: (13, 19): Variable expected
k10s72fa

k10s72fa1#

这是因为buildSrcfoo.bar.kts必须先编译,所以它必须是自包含的。它不能预见它会被应用到其他已经应用了Kotlin插件的构建脚本中(这实际上是脆弱的)。
这意味着两件事:

  • 在编译时,如果没有对插件的依赖,你就不能从插件访问类型和函数(很可能在buildSrc/build.gradle.kts中声明)
  • 在运行时,你不能假设任务和扩展的存在,只有当应用一些插件(这里,Kotlin插件)时才可用--你需要确保它已经被应用。

要解决这个问题,你可以在foo.bar.kts中应用Kotlin插件,或者用withPlugin()plugins.withId()来应对它:

plugins {
    kotlin("jvm")
}

repositories {
    mavenCentral()
}

tasks.test {
    useJUnitPlatform()
}

tasks.withType<KotlinCompile>() {
    kotlinOptions.jvmTarget = "11"
}

为此,您可能需要依赖buildSrc/build.gradle.kts中的Kotlin插件:

dependencies {
    implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.7.21")
}

有时候你不想在你的Kotlin插件被应用的时候强制应用它(因为可能使用的项目可能需要Kotlin或KotlinMultiplatform,但不是两者都需要)。对您来说可能不是这样的情况,因为当使用像这样的约定插件时,您通常确实希望对插件固执己见,但是当定义一个既适用于JVM又适用于多平台的约定时,它仍然是有用的。
如果你需要这种惰性和/或条件配置,你可以注册一个配置,这个配置只在给定的插件使用plugins.withId(...)时才被应用。不需要afterEvaluate之类的。例如:

plugins.withId("org.jetbrains.kotlin.jvm") {
    tasks.named<Test>("test") {
        useJUnitPlatform()
    }
    tasks.withType<KotlinCompile>() {
        kotlinOptions.jvmTarget = "11"
    }
}

plugins.withId("org.jetbrains.kotlin.multiplatform") {
    tasks.withType<Test>().configureEach {
        useJUnitPlatform()
    }
    tasks.withType<KotlinCompileCommon>() {
        // ..
    }
}

请注意,如果需要使用插件中的类,仍然需要buildSrc/build.gradle.kts来声明对插件的依赖。

相关问题