You can share extension functions, or field extension, within a single project by simply defining them in .kt files in ./buildSrc/src/main/kotlin/. You can then import them into any of the project's build.gradle.kts files.
For example, if you create ./buildSrc/src/main/kotlin/my/project/MyExtensions.kt
- Note that it's a
.kt, not .kts file.
- Also note that the package is set - often IntelliJ forgets to generate it when working in buildSrc!
//MyExtensions.kt
package my.project
val org.gradle.api.Project.testSources
get() = sourceSets.getByName("test").output // compilation error...
But... that code won't work. Because it's in a .kt file, not a .kts, the Gradle magic won't load the Kotlin DSL sourceSets accessor.
For tips on how to access Gradle objects without the Kotlin DSL accessors, looking at the Gradle Plugin development guide is best https://docs.gradle.org/current/userguide/custom_plugins.html.
You can also cmd/ctrl + left click in the build.gradle.kts files to see what the Kotlin DSL accessor is...
// 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
The auto generated code is a good start.
There's a few ways of accessing Gradle objects. Personally I'd prefer to retrieve the SourceSetContainer by type, not by string. And so here's how to fix your field extension.
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
Now in <root>/build.gradle.kts you can import the extension, and use it as expected.
//build.gradle.kts
import my.project.testSources
project.testSources?.files?.forEach { file: File? ->
logger.lifecycle("my extension function found a testSources file $file")
}
Sharing functions with plugins - Extension Aware
You can also share functions with regular Gradle plugins. See https://docs.gradle.org/current/dsl/org.gradle.api.plugins.ExtensionAware.html. However I don't think defining extension functions is possible.