Vít Kotačka
Vít Kotačka

Reputation: 1612

How to efficiently populate extra properties in the Gradle Kotlin DSL?

I'm migrating Gradle build scripts from Groovy to Kotlin DSL and one of the things which is not really documented is how to populate extra properties.

In Groovy, I can write:

ext {
    comp = 'node_exporter'
    compVersion = '0.16.0'
    compProject = 'prometheus'
    arch = 'linux-amd64'
    tarball = "v${compVersion}/${comp}-${compVersion}.${arch}.tar.gz"
    downloadSrc = "https://github.com/${compProject}/${comp}/releases/download/${tarball}"
    unzipDir = "${comp}-${compVersion}.${arch}"
}

I figured out that in the Kotlin DSL, I can achive the same functionality with:

val comp by extra { "filebeat" }
val compVersion by extra { "6.4.0" }
val arch by extra { "linux-x86_64" }
val tarball by extra { "${comp}-${compVersion}-${arch}.tar.gz" }
val downloadSrc by extra { "https://artifacts.elastic.co/downloads/beats/${comp}/${tarball}" }
val unzipDir by extra { "${comp}-${compVersion}-${arch}" }

which looks pretty repetitive.

Implementation of ExtraPropertiesExtension in Kotlin is a little bit complex, but at the end, it holds just plain old Map<String, Object>.

So, my question: is it possible to populate extra object with multiple properties more easily, than just repeating val myProp by extra { "myValue"}?

Upvotes: 13

Views: 9370

Answers (2)

V&#237;t Kotačka
V&#237;t Kotačka

Reputation: 1612

According the current (5.2.1) documentation:

All enhanced objects in Gradle’s domain model can hold extra user-defined properties. This includes, but is not limited to, projects, tasks, and source sets.

Extra properties can be added, read and set via the owning object’s extra property. Alternatively, they can be addressed via Kotlin delegated properties using by extra.

Here is an example of using extra properties on the Project and Task objects:

val kotlinVersion by extra { "1.3.21" }
val kotlinDslVersion by extra("1.1.3")
extra["isKotlinDsl"] = true

tasks.register("printExtProps") {
    extra["kotlinPositive"] = true

    doLast {
        // Extra properties defined on the Project object
        println("Kotlin version: $kotlinVersion")
        println("Kotlin DSL version: $kotlinDslVersion")
        println("Is Kotlin DSL: ${project.extra["isKotlinDsl"]}")
        // Extra properties defined on the Task object
        // this means the current Task
        println("Kotlin positive: ${this.extra["kotlinPositive"]}")
    }
}

Upvotes: 11

Malcolm
Malcolm

Reputation: 41510

You don't have to use delegation, just write extra.set("propertyName", "propertyValue"). You can do this with an apply block if you want:

extra.apply {
    set("propertyName", "propertyValue")
    set("propertyName2", "propertyValue2")
}

Upvotes: 8

Related Questions