codeYogico
codeYogico

Reputation: 13

Custom Configuration dependency declaration

I am trying to convert build.gradle to kotlin dsl. Using gradle 7.4.1.What the right way to declare custom configuration. For custom configuration like


    configurations { grafana }
    
    sourceSets { grafana }

and within dependencies block


    grafanaImplementation "org.slf4j:slf4j-simple:1.7.36"
    grafanaImplementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
    grafanaRuntimeOnly "org.jetbrains.kotlin:kotlin-stdlib-jdk8"

While I am in kotlin-dsl I am doing


    val grafana by configurations.creating
    
    val grafanaSourceSet = sourceSets.create("grafana")

and within dependency block

  grafana("org.slf4j:slf4j-simple:1.7.36")
  grafana("org.jetbrains.kotlin:kotlin-stdlib-jdk8")

When I try to put grafanaImplementation/ grafanaRuntimeOnly within kotlin dsl, it fails.

What is the equivalent of grafanaImplementation/ grafanaRuntimeOnly within kotlin dsl

Upvotes: 1

Views: 1454

Answers (1)

aSemy
aSemy

Reputation: 7110

Quick fix

When you do

val grafanaSourceSet = sourceSets.create("grafana")

behind the scenes Gradle will create the required configurations, grafanaImplementation, grafanaRuntimeOnly, etc, so you can use them without error like this:

val grafanaSourceSet = sourceSets.create("grafana")

dependencies {
  "grafanaImplementation"("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
  "grafanaRuntimeOnly"("org.slf4j:slf4j-simple:1.7.36")
}

This approach is more like how Groovy works - it basically disables type-checking and the strings will be evaluated during Gradle execution.

Generated DSL accessors

However, string-typing is not why we like Kotlin! We want type-safety and auto completion hints. That's exactly what we see with the implementation() and runtimeOnly(). So how do we get them for grafanaImplementation() and grafanaRuntimeOnly()?

Basically, Gradle will scan the registered config and when it sees that a plugin creates an implementation configuration, it generates Kotlin DSL accessors. However, it can't generate accessors for the build.gradle.kts that contains the definition for the accessors... that's too late. So we need to define the config earlier. We can do that with a buildSrc plugin.

buildSrc Grafana convention plugin

  1. Set up a buildSrc project (this is covered more in the Gradle docs or other StackOverflow answers)

  2. Create a pre-compiled script plugin for Grafana config

    // $projectRoot/buildSrc/src/main/kotlin/grafana.convention.gradle.kts
    
    plugins {
      // using 'sourceSets' requires the Java plugin, so we must apply it
      java
    }
    
    val grafanaSourceSet = sourceSets.create("grafana")
    

    Note that this convention plugin is quite opinionated as it applies the Java plugin. In more complex setups you might want to instead react to the Java plugin, rather than always applying it.

  3. Now apply the convention plugin, and Gradle will generate the Kotlin DSL accessors!

    // $projectRoot/build.gradle.kts
    
    plugins {
      id("grafana.convention")
    }
    
    dependencies {
      // no string-typing needed!
      grafanaImplementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
      grafanaRuntimeOnly("org.slf4j:slf4j-simple:1.7.36")
    }
    

Upvotes: 2

Related Questions