Hi, I want to share a dependency function between ...
# gradle
h
Hi, I want to share a dependency function between (sub)modules. Currently I have this thing in every
build.gradle.kts
:
Copy code
fun KotlinDependencyHandler.bomImplementation(config: BomConfig, limitTo: List<String> = emptyList()) {
    implementation(enforcedPlatform(config.platform))
    config.targets
        .filter { if (limitTo.isEmpty()) true else limitTo.contains(it) }
        .forEach {
            implementation(it)
        }
}
Is there a way to have this function only one time somewhere and have all gradles builds access it? I found this here in the history: https://kotlinlang.slack.com/archives/C19FD9681/p1592249840067900 I tried making my own plugin, but I couldn't quite figure out what I have to do to make it work.
c
Hey, have you read through https://docs.gradle.org/current/samples/sample_convention_plugins.html? If so, please mention what exactly didn't work for you.
t
also please vote for this issue
h
@CLOVIS I also stumbled upon this doc, but I don't know enough about gradle plugins to know what I would have to do with this and dismissed it at the time. If you say this is what I need I'll try a test implementation with this. I guess my function above would be in the
/kotlin/myproject.java-conventions.gradle.kts
equivalent then just without the other spotbug plugin? @tapchicoma I'll take a look and vote. Thanks to you both.
@CLOVIS I tried it and it did not work. I crated the file
buildSrc/src/kotlin/bomImplementation.gradle.kts
with the content:
Copy code
import org.gradle.kotlin.dsl.`kotlin-dsl`

plugins {
    `kotlin-dsl`
}

fun KotlinDependencyHandler.bomImplementation(config: BomConfig, limitTo: List<String> = emptyList()) {
    implementation(enforcedPlatform(config.platform))
    config.targets
        .filter { if (limitTo.isEmpty()) true else limitTo.contains(it) }
        .forEach {
            implementation(it)
        }
}
Then I added
id("bomImplementation")
to the
build.gradle.kts
of the module where I want to use the function. This all didn't work.
Turns out, I don't need a plugin. I just added
Copy code
implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.22")
to the
buildSrc/src/build.gradle.kts
and then I was able to just add
Copy code
import org.jetbrains.kotlin.gradle.plugin.KotlinDependencyHandler
fun KotlinDependencyHandler.bomImplementation(config: BomConfig, limitTo: List<String> = emptyList()) {
    implementation(enforcedPlatform(config.platform))
    config.targets
        .filter { if (limitTo.isEmpty()) true else limitTo.contains(it) }
        .forEach {
            implementation(it)
        }
}
to my
buildSrc/src/main/kotlin/Dependencies.kt
which also houses all the versions and bom configs.
1
Bonus my `BomConfig`:
Copy code
data class BomConfig(
    private val name: String,
    private val path: String,
    private val version: String,
    private val rawTargets: List<String>,

    val platform: String = "$path:$name-bom:$version"
) {
    val targets: List<String> = rawTargets.map { "$path:$it" }

    /**
     * For use with BOM that have multiple paths like Jackson.
     * Requires the full BOM path as well as the full path for each target.
     */
    constructor(bom: String, rawTargets: List<String>, bomSplit: List<String> = bom.split(":")) : this(
        name = bomSplit[1].removeSuffix("-bom"),
        path = bomSplit[0],
        version = bomSplit[2],
        platform = bom,
        rawTargets = rawTargets
    )
}
Maybe someone wants it.
Ah, slight update:
Copy code
data class BomConfig(
    private val name: String,
    private val path: String,
    private val version: String,
    private val targets: List<String> = emptyList(),

    val platform: String = "$path:$name-bom:$version",
    val fullTargets: Map<String, String> = targets.associateWith { "$path:$it" }
) {

    /**
     * For use with BOM that have multiple paths like Jackson.
     * Requires the full BOM path as well as the full path for each target.
     */
    constructor(bom: String, fullTargets: List<String>, bomSplit: List<String> = bom.split(":")) : this(
        name = bomSplit[1].removeSuffix("-bom"),
        path = bomSplit[0],
        version = bomSplit[2],
        platform = bom,
        fullTargets = fullTargets.associateBy { it.split(":").last() }
    )
}

fun KotlinDependencyHandler.bomImplementation(config: BomConfig, limitTo: List<String> = emptyList()) {
    implementation(enforcedPlatform(config.platform))
    config.fullTargets
        .filter { if (limitTo.isEmpty()) true else limitTo.contains(it.key) }
        .forEach {
            implementation(it.value)
        }
}