我需要复制现有的战争文件并更新其中的xml文件。我对如何做到这一点的想法是:
- 从现有战争中提取文件
- 替换文件中的字符串
- 复制战争
- 将修改后的文件添加回复制的战争
我可以用 Gradle 完成前 3 步,但我只能弄清楚如何使用 Ant 完成最后一步。
task updateWar() << {
def originalWar = file("deploy/mywar.war")
def outputDir = file("deploy")
def wars = [ "war1", "war2" ]
wars.each() { warFile ->
delete "deploy/WEB-INF/ejb.xml"
copy {
//Step 1
from(zipTree(originalWar)) {
include 'WEB-INF/ejb.xml'
}
into outputDir
//Step 2
filter{
String line -> line.replaceAll("<value>OriginalText</value>",
"<value>UpdatedText</value>")
}
}
//Step 3
copy {
from outputDir
into outputDir
include 'mywar.war'
rename 'mywar.war',"${warFile}.war"
}
//Step 4
ant.jar(update: "true", destfile: deploy/${warFile}.war") {
fileset(dir: deploy", includes: 'WEB-INF/**')
}
}
}
理想情况下,会有一个过滤器选项,允许我在复制时修改指定的文件,但我还没有解决这个问题。
如何在 Gradle 中有效地做到这一点,而不会退回到蚂蚁?甚至是一种时髦的渐进式方法可以一步到位吗?
编辑:我离得更近了。使用原始战争中的拉链树的 Zip 任务是第一个关键步骤。文件匹配与过滤器相结合是秘密武器!但是,我不能像复制方法那样在循环中使用它,所以我仍然陷入:(
task updateWar(type: Zip) {
def originalWar = file("deploy/mywar.war")
def outputDir = file("deploy")
archiveName = "war2.war"
destinationDir = outputDir
from (zipTree(originalWar),{
filesMatching("WEB-INF/ejb.xml") {
filter{
String line -> line.replaceAll("<value>OriginalText</value>",
"<value>UpdatedText</value>")
}
}
})
}
假设您只想将war
中的原始文件替换为res
文件夹中的文件,以下是操作方法:
task updateWar(type: Zip) {
def originalWar = file("deploy/mywar.war")
archiveBaseName = 'mywar'
archiveExtension = 'war'
from(zipTree(originalWar)) {
// Remove the original ejb.xml if it exists
exclude("**/WEB-INF/ejb.xml")
}
// Include our own ejb.xml
from('res/ejb.xml') {
into('WEB-INF/')
}
}
使用 Gradle 7.x,您可以通过 DuplicatesStrategy 替换存档 (zip) 文件。它不提供"覆盖"策略,购买您可以使用"排除"策略和反向复制顺序达到相同的结果。喜欢这个:
task updateWar(type: Zip) {
...
duplicatesStrategy 'exclude'
// First copy the overriding files.
from('res/ejb.xml') {
into('WEB-INF/')
}
// Then copy the common content.
// (duplicate files it will be skipped)
from(zipTree(originalWar)) {
...
}
}