我在 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
最佳答案
这是因为来自 buildSrc
的 foo.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/