Lets say I have properties file config.properties
which has
prop1=abc
prop2=xyz
and a template-config.xml
that looks something like
<bean id="id1" >
<property name="prop1" value="${prop1}" />
<property name="prop2" value="${prop2}" />
</bean>
I have 2 Questions:
Is there a way I can use the property file in the expand() portion of the gradle copy task to inject the properties into the config from gradle.build.kts?
Is there a way I can use expand to fill in only one of the properties without throwing an error?
So far I have
tasks.register<Copy>("create-config-from-template") {
from("$buildDir/resources/main/template-config.xml")
into("$buildDir/dist")
expand(Pair("prop1", "abc"))
}
However, this throws an error
Missing property (prop2) for Groovy template expansion. Defined keys [prop1].
I know that I can also specify the value for prop2 inside "expand()", but for my purposes it would help if I could only inject some of the properties and not others. Is there a simple way to tell gradle not to worry about the other "${}" properties in the file?
If not, is there a way I can use the actual property file as the set of properties to expand? I can't seem to find the Kotlin DSL syntax for this anywhere.
Thank you very much in advance.
CodePudding user response:
For 1, you can use configure the existing processResources
task to apply additional configuration to a specific file. In this case template-config.xml
, for example:
tasks.processResources {
filesMatching("**/template-config.xml") {
val examplePropertiesTextResource = resources.text.fromFile(layout.projectDirectory.file("example.properties"))
val exampleProperties = Properties().apply {
FileInputStream(examplePropertiesTextResource.asFile()).use { load(it) }
}
val examplePropertiesMap = mutableMapOf<String, Any>().apply {
exampleProperties.forEach { k, v -> put(k.toString(), v) }
}
expand(examplePropertiesMap)
}
}
filesMatching
will match on the file you want. Then the proceeding lines load the properties file, in this case a file name example.properties
in the project's root directory. It is then transformed into a Map<String, Any>
and passed to the expand
method.
However, for 2, with the above approach it will fail if any properties are missing. This is because the underlying expansion engine (SimpleTemplateEngine
) does not allow such configuration
As an alternative, you can use ExpandTokens
from Apache ANT to achieve the replacement when some properties are missing:
tasks.processResources {
filesMatching("**/template-config.xml") {
val examplePropertiesTextResource = resources.text.fromFile(layout.projectDirectory.file("example.properties"))
val exampleProperties = Properties().apply {
FileInputStream(examplePropertiesTextResource.asFile()).use { load(it) }
}
val examplePropertiesMap = mapOf<String, Any>("tokens" to exampleProperties.toMap())
println(examplePropertiesMap)
filter(examplePropertiesMap, ReplaceTokens::class.java)
}
}
Note that for ReplaceTokens
, you must change the placeholders from ${example}
to @example@
:
<bean id="id1" >
<property name="prop1" value="@prop1@" />
<property name="prop2" value="@prop2@" />
</bean>
This is because Gradle only accepts a Class
and ReplaceTokens
is final
, so you can't extend the class to use ${}
as the placeholders.