gradle-properties-plugin icon indicating copy to clipboard operation
gradle-properties-plugin copied to clipboard

Provide a Kotlin DSL for the task methods.

Open dtbullock opened this issue 3 years ago • 2 comments

To invoke the groovy methods installed as extension properties of Task objects by applying gradle-properties-plugin from the Gradle Kotlin DSL using the 'check required properties as the first line of the task ' idiom, it is necessary to first install some Kotlin extension methods:

// These can be pasted into a build.gradle.kts ... though if provided *by the plugin* the getClosure() function could be private.

/* private */ fun getClosure(task: Task, closureName: String): groovy.lang.Closure<Any> {
    return (task.extensions["ext"] as ExtraPropertiesExtension).get(closureName) as (groovy.lang.Closure<Any>)
}

fun Task.requiredProperty(propertyName: String) {
    getClosure(this, "requiredProperty")(propertyName)
}

fun Task.requiredProperties(propertyNames: Array<String>) {
    getClosure(this, "requiredProperties")(propertyNames)
}

fun Task.recommendedProperty(propertyName: String, defaultFile: String) {
    getClosure(this, "recommendedProperty")(propertyName, defaultFile)
}

fun Task.recommendedProperties(propertyNames: Array<String>, defaultFile: String) {
    getClosure(this, "recommendedProperties")(mapOf(
        "names" to propertyNames,
        "defaultFile" to defaultFile
    ))
}

val Project.filterTokens : Map<String,String>
    get() = (ext["filterTokens"] as Map<String, String>)

It is then possible to use the suggested 'property check' idiom from scripted tasks:

val templateDir = File("${projectDir}/property-templates/")
val resourceDir = File("${projectDir}/src/main/resources/")

tasks.register<Copy>("prep") {

    requiredProperty("singleRequired")
    requiredProperties(arrayOf("foo", "bar"))
    recommendedProperty("singleRecomm", "fileA")
    recommendedProperties(arrayOf("applicationLogDir", "b"), "fileB")

    outputs.file(File(resourceDir, "log4j.properties"))

    from(templateDir)
    include("log4j.properties")
    into(resourceDir)
    filter(ReplaceTokens::class, "tokens" to project.filterTokens)

}

Notwithstanding the major design change (?) to be provoked by the configuration cache in future versions of Gradle, it'd be sweet if gradle-properties-plugin could distribute these extensions!

dtbullock avatar Mar 26 '21 01:03 dtbullock

Maybe better varargs than explicit Arrays

Vampire avatar Feb 02 '22 03:02 Vampire

It might even be better to not use ext properties at all which are in most cases just work-arounds instead of doing it properly. Instead it would probably be more appropriate to add an extension to the tasks. Unfortunately there will not be accessors generated for the Kotlin DSL, but as it will be available on all tasks, it would probably be ok to provide the accessors with the plugin. For Groovy DSL it would simply work. And it would then be for example

tasks.register("foo") {
    propertyRules {
        require("foo")
        recommend("bar", "baz")
    }
}

Vampire avatar Oct 26 '22 15:10 Vampire