如何使用自定义扩展功能扩展GradleKotlin DSL



我正在尝试构建我自己的扩展函数,它使用了C:/Users/<username>/.gradle/caches/7.3-20211011231002+0000/kotlin-dsl/accessors/5030f2917b46f065859e6c634449b97d/sources/org/gradle/kotlin/dsl/Accessors2oadk7let745pm8ahqypkqzlk.kt:63中的一个扩展方法,这似乎是一个非常内部的方法。

在我的buildSrc子项目中,我想尝试添加以下扩展功能

val org.gradle.api.Project.testSources
get() = sourceSets.getByName("test").output

有没有办法解决Kotlin DSL中定义的扩展函数(我的总体目标不是写project(":<name>").sourceSets["test"].output来写project(":<name>").testSources(。

我真的不明白为什么所有的扩展方法都不可用。。。。

我的buildSrc的build-gradle.kts。

plugins {
`kotlin-dsl`
}

Repo(这不会因为缺少一个文件而构建,我想将其保密,但这对这个问题不重要(

您可以在单个项目中共享扩展函数或字段扩展,只需在./buildSrc/src/main/kotlin/.kt文件中定义即可。然后可以将它们导入到项目的任何build.gradle.kts文件中。

例如,如果创建./buildSrc/src/main/kotlin/my/project/MyExtensions.kt

  • 请注意,这是一个.kt文件,而不是.kts文件
  • 还要注意,包是设置好的-IntelliJ在buildSrc中工作时经常忘记生成它
//MyExtensions.kt
package my.project
val org.gradle.api.Project.testSources
get() = sourceSets.getByName("test").output // compilation error...

但是。。。那个代码不起作用。因为它在.kt文件中,而不是在.kts文件中,Gradle魔术不会加载Kotlin DSLsourceSets访问器。

有关如何在没有Kotlin DSL访问器的情况下访问Gradle对象的提示,最好查看Gradle插件开发指南https://docs.gradle.org/current/userguide/custom_plugins.html.

您也可以在build.gradle.kts文件中使用cmd/ctrl + left click来查看Kotlin DSL接入器是什么…

// auto-generated Kotlin DSL accessor
/**
* Retrieves the [sourceSets][org.gradle.api.tasks.SourceSetContainer] extension.
*/
val org.gradle.api.Project.`sourceSets`: org.gradle.api.tasks.SourceSetContainer get() =
(this as org.gradle.api.plugins.ExtensionAware).extensions.getByName("sourceSets") as org.gradle.api.tasks.SourceSetContainer

自动生成的代码是一个良好的开端。

有几种方法可以访问Gradle对象。就我个人而言,我更喜欢按类型检索SourceSetContainer,而不是按字符串检索。下面是如何修复字段扩展的方法。

package my.project
import org.gradle.api.Project
import org.gradle.api.tasks.SourceSetContainer
import org.gradle.api.tasks.SourceSetOutput
import org.gradle.kotlin.dsl.findByType
val Project.testSources: SourceSetOutput?
get() = extensions
.findByType<SourceSetContainer>()
?.getByName("test")
?.output

现在,在<root>/build.gradle.kts中,您可以导入扩展,并按预期使用它。

//build.gradle.kts
import my.project.testSources
project.testSources?.files?.forEach { file: File? ->
logger.lifecycle("my extension function found a testSources file $file")
}

与插件共享功能-扩展感知

您还可以与常规Gradle插件共享函数。看见https://docs.gradle.org/current/dsl/org.gradle.api.plugins.ExtensionAware.html.然而,我认为定义扩展函数是不可能的。

最新更新