如何使用 Gradle 更新现有的 war/jar/zip 文件



我需要复制现有的战争文件并更新其中的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)) {
        ...
    }
}

最新更新