13

I have the following in a groovy-based build script. How do I do the same in a kotlin-based script?

processResources {

    filesMatching('application.properties'){
        expand(project.properties)
    }

}
mkobit
  • 43,979
  • 12
  • 156
  • 150
KevinS
  • 7,715
  • 4
  • 38
  • 56

3 Answers3

24

Why not to just use "withType" ? I just mean (IMHO)

tasks {
  withType<ProcessResources> {
.. 
}

looks much better than

tasks {
  "processResources"(ProcessResources::class) {
.. 
}

So,

tasks.withType<ProcessResources> {
    //from("${project.projectDir}src/main/resources")
    //into("${project.buildDir}/whatever/")
    filesMatching("*.cfg") {
        expand(project.properties)
    }
}

EDIT:

With newer release you can just do:

tasks.processResources {}

or

tasks { processResources {} }

generated accessors are "lazy" so it has all the benefits and no downsides.

SoBeRich
  • 682
  • 2
  • 8
  • 15
  • This should honestly be the correct answer. You would only need `"processResources"(ProcessResources::class)` if you weren't in a context where the Java plugin is applied. – varcharmander Oct 31 '19 at 04:32
  • @varcharmander also note what often escapes attention that in configures all tasks with such type for all `sourceSets` (e.g. also for `test` and any custom one). Which is a common mistake when people do `compileJava {}` it only affects `JavaCompile` task for `main` `sourceSet`, so it always should be `withType<...>` for any type of tasks which has their instances run for different `sourceSets` – SoBeRich Oct 31 '19 at 08:20
11

I think task should look like:

Edit: According this comment in gradle/kotlin-dsl repository. Task configuration should work this way:

import org.gradle.language.jvm.tasks.ProcessResources

apply {
    plugin("java")
}

(tasks.getByName("processResources") as ProcessResources).apply {
    filesMatching("application.properties") {
        expand(project.properties)
    }
}

Which is pretty ugly. So i suggest following utility function for this purpose, until one upstream done:

configure<ProcessResources>("processResources") {
    filesMatching("application.properties") {
        expand(project.properties)
    }
}

inline fun <reified C> Project.configure(name: String, configuration: C.() -> Unit) {
    (this.tasks.getByName(name) as C).configuration()
}
mkobit
  • 43,979
  • 12
  • 156
  • 150
Ruslan
  • 14,229
  • 8
  • 49
  • 67
  • That looks like it should work but I get an error. I think it could be a bug. Logged it here: https://discuss.gradle.org/t/in-gradle-script-kotlin-tasks-getbyname-with-closure-errors-with-value-is-null/20065/1 – KevinS Oct 18 '16 at 22:36
  • See the answer by @SoBeRich for a cleaner answer https://stackoverflow.com/a/48241682/2491459 – varcharmander Oct 31 '19 at 04:33
  • It was helpful. I'd like someone to make an groovy to kotlin-dsl converter! – NCrash Feb 03 '21 at 12:45
9

With updates to the APIs in newer release of the Kotlin DSL and Gradle, you can do something like:

import org.gradle.language.jvm.tasks.ProcessResources

plugins {
  java
}

tasks {
  "processResources"(ProcessResources::class) {
    filesMatching("application.properties") {
      expand(project.properties)
    }
  }
}

And also:

val processResources by tasks.getting(ProcessResources::class) {
  filesMatching("application.properties") {
    expand(project.properties)
  }
}
mkobit
  • 43,979
  • 12
  • 156
  • 150
  • This is also IMO anti-pattern to get reference to `TaskProvider<..>` when you are not using that reference. aslo with "newer release" (after time of your anserwer) you can just do `tasks.processResources {}` or `tasks { processResources {} }` generated accessors are "lazy" so it has all the benefits and do downsides. – SoBeRich Oct 31 '19 at 08:26