I have an xml file where I want to just change a single line in the file and nothing else. I am able to change the content of the file but I canβt seem to figure out how to preserve that change while keeping the file name and location the same. Any ideas?
How about using Groovyβs GStringTemplateEngine
. (see detail)
for example.
Project structure is following.
.
βββ build.gradle
βββ src
β βββ main
β βββ java
β β βββ com
β β βββ sample
β β βββ model
β β βββ Person.java
β βββ resources
β β βββ application.properties
β βββ webapp
β βββ WEB-INF
β β βββ web.xml
β βββ index.html
βββ template
βββ application.properties
And if you wish to change application.properties
file, when creating war file.
build.gradle
file is as following.
// declaration of plugins/dependencies/repositories
import groovy.text.GStringTemplateEngine
task prepareApplicationProperties {
// load template file
def template = file('template/application.properties')
// changing file via stage
def appProperties = file('src/main/resources/application.properties')
outputs.file appProperties
outputs.upToDateWhen {
false
}
doLast {
// change contents via cli options
def env = project.hasProperty('appPort') ? appPort : 'dev'
def port = env == 'dev' ? 8080 : appPort as int
def binding = [port: port]
// change file contents
def tmp = new GStringTemplateEngine()
.createTemplate(template)
.make(binding)
appProperties.write(tmp.toString(), 'UTF-8')
}
}
tasks.idea.dependsOn 'prepareApplicationProperties'
tasks.war.dependsOn 'prepareApplicationProperties'
This script generates application.properties
file before idea
task(if you use eclipse change idea
to eclipse
) and war
task.
Template file is following.
server.port=$port
if you run idea
task (thus this is develop environment), without -PappPort
optionβ¦
$ ./gradlew idea
Then application.properties
will becomes as follows.
server.port=8080
If you run war
task with -PappPort
optionβ¦
$ ./gradlew war -PappPort=9999
Then the contents of WEB-INF/classes/application.properties
file becomes
server.port=9999
You can leverage Groovyβs SimpleTemplateEngine by just passing a map to any Copy
taskβs expand()
method.
war {
expand hostname: 'server.foo.org'
}
Unfortunately, we cannot use templating in the file that needs to have its content replaced, we would need to do some sort of replace(). I think it boils down to my limited knowledge of Gradle and Groovy.
Possibly easiest to use with(CopySpec)
in either the war or processResources tasks (depending on the target folder)
war {
with copySpec {
from 'src/template/webapp'
filter(ReplaceTokens, tokens: ['someToken':'someValue'])
}
}
processResources {
with copySpec {
from 'src/template/resources'
filter(ReplaceTokens, tokens: ['someToken':'someValue'])
}
}
Link to stackoverflow post for better quality : https://stackoverflow.com/questions/33464577
To complement Lance_Java
's answer, I found this idiom more simple if thereβs only one value you are looking to change:
task generateSources(type: Copy) {
from 'src/replaceme/java'
into "$buildDir/generated-src"
filter { line -> line.replaceAll('xxx', 'aaa') }
}