Similar to my other question
I would like to improve my current ReplaceVersionRPlugin ( buildSrc/src/main/kotlin/versioningR.gradle.kts )
By default the plugin should replace all occurrences of @VERSION@ with project.version in my Java resource / webapp files.
My questions:
Is it possible to avoid the afterEvaluate?
What are the downsides of afterEvaluate in this case?
How can I replace @TOKEN@ in webapp files?
Is there an easier way to define the extension? Without default values I could simply create an interface.
In this casetasks.withType<ProcessResources> { (inside afterEvaluate and tasks.withType<ProcessResources>().all { are equivalent, correct?
lazy_configuration.html states: «Existing tasks will have their existing “raw” properties replaced by Providers as needed and in a backwards compatible way.»
Does this mean, that the ProcessResources tab should allow properties for the pattern in filesMatching and that this would avoid the usage of afterEvaluate?
If the property resourcePattern is not set, I would like the plugin to do nothing.
My current code:
import org.apache.tools.ant.filters.ReplaceTokens
open class ReplaceVersionRExtension @Inject constructor(
project: Project
) {
val tokens: MapProperty<String, String> = project.objects.mapProperty(String::class.java, String::class.java)
.convention(project.provider { mutableMapOf("VERSION" to "${project.version}") })
val resourcePattern: Property<String> = project.objects.property(String::class.java)
}
val replaceVersionR = extensions.create<ReplaceVersionRExtension>("replaceVersionR")
afterEvaluate {
tasks.withType<ProcessResources> {
inputs.property("tokens", replaceVersionR.tokens)
inputs.property("resourcePattern", replaceVersionR.resourcePattern)
filesMatching(replaceVersionR.resourcePattern.get()) {
filter<ReplaceTokens>("tokens" to replaceVersionR.tokens.get())
}
}
}
As you want to wait for the build script to configure the extension and the values you want to set are not lazy evaluated, probably not.
Well, if you would know for sure that nothing is eagerly realizing the task, you could use proper task configuration avoidance api and then probably would not need the afterEvaluate. But if anyone or anything is eagerly realizing one of the tasks, your values would maybe not be the correct ones.
What are the downsides of afterEvaluate in this case?
afterEvaluate always has the downside that there could be a later afterEvaluate that again changes the values that you read so you used stale values.
Is there an easier way to define the extension? Without default values I could simply create an interface.
Also with.
interface ReplaceVersionRExtension {
val tokens: MapProperty<String, String>
val resourcePattern: Property<String>
}
val replaceVersionR = extensions.create<ReplaceVersionRExtension>("replaceVersionR")
replaceVersionR.tokens.convention(project.provider { mutableMapOf("VERSION" to "${project.version}") })
In this casetasks.withType<ProcessResources> { (inside afterEvaluate and tasks.withType<ProcessResources>().all { are equivalent, correct?
Doesn’t matter whether inside afterEvaluate or outside, they are the same and they are both evil as they cause all tasks of that type to be realized and configured, whether they are going to be executed or not. Better use tasks.withType<ProcessResources>().configureEach { ... }.
lazy_configuration.html states: «Existing tasks will have their existing “raw” properties replaced by Providers as needed and in a backwards compatible way.»
Does this mean, that the ProcessResources tab should allow properties for the pattern in filesMatching and that this would avoid the usage of afterEvaluate ?
I cannot guess what they mean.
But I’d guess it as a solid maybe.
If the property resourcePattern is not set, I would like the plugin to do nothing.