kotlin - 使用 kotlin dsl 修改 buildSrc 中 gradle 插件中的任务

标签 kotlin gradle gradle-kotlin-dsl

我在 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

最佳答案

这是因为来自 buildSrcfoo.bar.kts 必须首先编译,所以它必须是独立的。它无法预见它将应用于其他已经应用了 Kotlin 插件的构建脚本(这实际上很脆弱)。

这意味着两件事:

  • 在编译时,您无法在不依赖插件的情况下访问插件中的类型和函数(很可能在 buildSrc/build.gradle.kts 中声明)
  • 在运行时,您不能假设存在仅在应用某些插件(此处为 Kotlin 插件)时才可用的任务和扩展 - 您需要确保它已被应用。

要解决这个问题,您可以在 foo.bar.kts 本身中应用 Kotlin 插件,或者使用 withPlugin()plugins 等内容对其使用react.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 JVM 或 Kotlin Multiplatform,但不能同时使用两者)。 对于您来说情况可能并非如此,因为当使用这样的约定插件时,您通常确实希望对插件有自己的看法,但是当定义一个同时适用于 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 来声明对插件的依赖关系。

关于kotlin - 使用 kotlin dsl 修改 buildSrc 中 gradle 插件中的任务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74740037/

相关文章:

spring - 更新 JPA(Hibernate) 实体 : transactional or non-transactional and why? 的更好方法是什么

java - Gradle 无法找到打包为 OSGi bundle 的下载依赖项(非 OSGi 应用程序)

android - Android产品Gradle-kotlin-dsl中的香料

android - 如何使用 gradle kotlin dsl 设置单元测试 jvmargs

android - 如何使用Kotlin Gradle DSL在Android项目中启用ViewBing?

gradle - 如何在Gradle中获取原始Run任务的确切副本?

android - 为什么我不能直接访问 let 作用域函数中使用的对象,而不是在 Kotlin 中访问它?

gradle - Gradle-每个的命令行

android - searchview不适用于自定义适配器kotlin

android - 在最新检查期间无法捕获任务 ':app:preDebugBuild' 属性 'runtimeManifests' 的输入文件的快照