I have a custom task to output a generated resourc...
# community-support
r
I have a custom task to output a generated resource file... not entirely happy with it. Interested in anyone's take. Code in thread.
Copy code
val generatedResourceDir = layout.buildDirectory.dir("generated/resources")

sourceSets {
  main {
    resources.srcDir(generatedResourceDir)
  }
}

tasks {

  val setVersions by registering(Sync::class) {
    from(layout.projectDirectory.dir("src/main/resource-templates"))
    into(generatedResourceDir)
    rename { fileName ->
      fileName.replace("-template", "")
    }
    expand(
      "GIT_HASH" to (System.getenv("GIT_HASH") ?: "local"),
      "VERSION" to (System.getenv("VERSION") ?: "local"),
    )
  }

  processResources {
    dependsOn(setVersions)
  }
}
I feel slightly uncomfortable about: • hardcoding
"src/main"
- can I derive that somehow? • hardcoding
"generated/"
as it's a convention - can I derive it somehow?
p
You should use
Copy code
sourceSets {
  main {
    resources.srcDir(tasks.setVersions)
  }
}
šŸ‘† 1
and remove dependsOn
r
Nice, thanks
Though I think in kotlin I have to use
resources.srcDir(tasks.named("setVersions"))
p
It depends: you can also use
val setVersions by tasks.registering
and
srcDir(setVersions)
later
šŸ‘ 1
t
Wrt the paths, you can't derive those no. If you were creating a more generic task applying to each source set (
sourceSets.configureEach
), then you could derive the
main
from the source set, but that's it (and you should create a sourceset specific subdir inside your
generated
).
r
OK, so now I'm at:
Copy code
val setVersions by tasks.registering(Sync::class) {
  from(layout.projectDirectory.dir("src/main/resource-templates"))
  into(layout.buildDirectory.dir("generated/resources/from-templates"))
  rename { fileName ->
    fileName.replace("-template", "")
  }
  expand(
    "GIT_HASH" to (System.getenv("GIT_HASH") ?: "local"),
    "BUILD_NUMBER" to (System.getenv("BUILD_NUMBER") ?: "local"),
  )
}

sourceSets {
  main {
    resources.srcDir(setVersions)
  }
}
šŸ‘ 1
Perhaps it should be:
Copy code
val templateResources by tasks.registering(Sync::class) {
  from(layout.projectDirectory.dir("src/main/resource-templates"))
  into(layout.buildDirectory.dir("generated/resources/from-templates"))
  rename { fileName ->
    fileName.removeSuffix("-template")
  }
  expand(System.getenv())
}
or is making the entire env available foolish?
OK, that's a bad idea - the configuration cache doesn't like
System.getenv()
and Groovy's SimpleTemplateEngine can't cope with missing env vars.
v
Another thought, why do you need a custom sync task anyway? If there are reasons, then like the others said, make the task the resources src dir without manual paths and dependsOn. But you could also just have the file in
src/main/resources
directly and configure the
processResources
task to do the
expand
on the file. Besides that, either way remember to also set the filtering charset, at least if input or output can ever contain non-ascii characters.
r
I'd completely forgotten that processResources could do expansion.
(Though I switched to generating a Kotlin file in the end, as I couldn't see much benefit in generating a JSON file and then using a JSON parser to turn it into an instance of a data class when I could just instantiate the instance in a generated file, which I think does need the intermediate sync task)
v
It has several advantages to use a resource file you read at runtime. I'm just going to mention the most prominent. With runtime classpath normalization you can make things like test task and so on up to date if only that file changed. If the generated class changed, it is out-of-date.