I have a functions that's an alternative to mavenCentral
, which creates an ArtifactRepository:
fun RepositoryHandler.myCustomRepository(): ArtifactRepository {
// about 20 lines of code
}
I have a multi-project Gradle build that also has a buildSrc
, and I want to
use myCustomRepository
:
buildSrc
The best I’ve found is to use settings.gradle.kts
and
buildSrc/settings.gradle.kts
and use the function in four places:
Unfortunately,
it seems that I also need to define four identical copies of the function,
two in each settings.gradle.kts
file. I haven't been able to find a single place
to define it that's visible to all four locations where I need to use it.
That is:
settings.gradle.kts
fun RepositoryHandler.myCustomRepository(): ArtifactRepository {
// copy #1
}
pluginManagement {
fun RepositoryHandler.myCustomRepository(): ArtifactRepository {
// copy #2
}
repositories {
myCustomRepository()
gradlePluginPortal()
}
}
dependencyResolutionManagement {
repositories {
myCustomRepository()
}
}
buildSrc/settings.gradle.kts
fun RepositoryHandler.myCustomRepository(): ArtifactRepository {
// copy #3
}
pluginManagement {
fun RepositoryHandler.myCustomRepository(): ArtifactRepository {
// copy #4
}
repositories {
myCustomRepository()
gradlePluginPortal()
}
}
dependencyResolutionManagement {
repositories {
myCustomRepository()
gradlePluginPortal()
}
}
Is there some way to define this function in only ONE place, and use it in all four of these places?
pluginManagement
is specialYou cannot simply use an external function in the pluginManagement
block because pluginManagement
, like the plugins
block, is isolated from the rest of the file1 so there is no import mechanism.
What you can do as an alternative is to write a Settings
plugin inside of an included build. Such a settings plugin can itself perform actions inside pluginManagement
, including calling a given function.
Also, a settings plugin, when applied inside the plugins
block, has its JAR added to classpath of the settings.gradle.kts
file so you can use any other functions defined in the plugin project in that file (though not pluginManagement
).
All in all that would look something like this:
An included build project which defines and exports a settings plugin using the Java Gradle plugin, and declares your function myCustomRepository()
. Here's the key source file:
// myIncludedBuild/src/main/kotlin/MySettingsPlugin.kt
class MySettingsPlugin : Plugin<Settings> {
override fun apply(target: Settings) {
target.pluginManagement.apply {
repositories.myCustomRepository()
}
}
}
fun RepositoryHandler.myCustomRepository() {
println(this::class.qualifiedName)
}
Then in settings.gradle.kts
of the main project you can do:
pluginManagement {
includeBuild("myIncludedBuild")
}
plugins {
// Calls myCustomRepository via its apply method
id("mySettingsPlugin")
}
dependencyResolutionManagement {
repositories.myCustomRepository()
}
buildSrc
's settings.gradle.kts
is identical except it needs a slightly different relative path to find the included build:
pluginManagement {
includeBuild("../myIncludedBuild")
}
Execute that build and you get the following output four times:
org.gradle.api.internal.artifacts.dsl.DefaultRepositoryHandler_Decorated
build.gradle.kts
filesNow you have an included build, you can proceed in similar fashion with Project
plugins, or directly use the buildscript
blocks to add the code of the included build project to any given build.gradle.kts
file.