我有一个Gradle构建脚本,可以成功构建我的项目并编译我需要的所有工件。
但是,在某些情况下,我想让其他开发人员选择修补一些文件。例如,在其中一个档案中有一个xml文件,其中包含有关数据库挂钩的信息 - 一些开发人员使用其他版本(甚至引擎),并且需要在使用构建输出之前更改这些。
我不想让他们对版本控制的文件进行更改(他们可能会错误地提交),而是让他们选择使用构建脚本适用的本地个人补丁文件。
在旧的蚂蚁脚本中,我们做了类似的事情
<target name="appcontext-patch" if="applicationContext.patch.file">
<patch patchfile="${applicationContext.patch.file}" originalfile="${dist.dir}/applicationContext.xml"/>
</target>
但我无法弄清楚如何在Gradle中进行等效操作。有没有比尝试直接将其转换为对ant.patch
的调用更好(即更惯用)的方式?
某些背景
这就是文件首先在存档中结束的方式:
into('META-INF') {
from 'deployment', {
include 'applicationContext.xml'
rename { fn -> "jboss-spring.xml" }
}
}
如果我能做一些类似
的事情,那将是 fantabulousinto('META-INF') {
from 'deployment', {
include 'applicationContext.xml'
rename { fn -> "jboss-spring.xml' }
patch 'local/applicationContext.xml.patch'
}
}
并在将文件放入存档之前应用补丁文件。我不介意编写一些代码来实现这一点,但我对Gradle很新,我不知道从哪里开始。
答案 0 :(得分:4)
你应该能够直接将你的蚂蚁电话翻译成gradle。
The gradle doc on how to do this generically.基本上,属性成为命名参数,子标记成为闭包。文档中有很多很好的例子。
完成翻译的ant任务后,您可以在适当的任务中输入doFirst或doLast块。
我的第一个猜测是这样的:
apply plugin: 'java'
assemble.doFirst {
ant.patch(patchfile: applicationContext.patch.file,
originalFile: "${dist.dir}/applicationContext.xml")
}
那是未经测试的,所以但我很确定它会让你开始走上正确的道路。目的是在java插件组装您的存档之前,您希望gradle调用一个闭包。在这种情况下,闭包将执行修补xml的ant动作。
或者,您可以使用上面的任务执行复制和标记。
task myCopyTask(type: Copy) {
...
} << {
ant.patch(patchfile: applicationContext.patch.file,
originalFile: "${dist.dir}/applicationContext.xml")
}
在这种情况下,您自己编写任务,左移操作符(<<
)相当于.doLast
,但整个冷却程度更低。我不确定你喜欢哪种方法,但如果你已经有一个复制任务首先获取文件,我认为doLast使相关代码块尽可能保持彼此接近。
答案 1 :(得分:1)
如果你想在飞行中更多地这样做,我可以想到两种主要技巧。两者都涉及编写一些代码,但它们可能对您更具吸引力,我非常有信心gradle没有内置任何内容的这种行为。
就我个人而言,我认为#1是更好的解决方案,因为您不需要复制Copy任务的内部。自定义过滤器感觉更清洁,更可重复使用。
1)编写您在复制任务中指定的自定义过滤器。我无法帮助详细说明如何编写自定义过滤器,但我会开始here.您应该能够将自定义过滤器放在buildSrc中(有关gradle.org的大量信息),然后您只需将其导入gradle文件的顶部即可。如果你用groovy写它,我想你甚至可以再次使用ant.patch()
。
task copyAndPatch() {
into('META-INF') {
from 'deployment', {
include 'applicationContext.xml'
rename { fn -> "jboss-spring.xml' }
filter(MyCustomFilterThatDoesAPatch, patchFile: 'local/applicationContext.xml.patch')
}
}
2)编写自定义任务。再说一次,我leave the details to the experts但是你可以放弃复制任务的子类,添加一个'patch'属性,然后在执行期间跳进去做脏工作。
答案 2 :(得分:1)
RFC 5621定义了一种XML修补语言,该语言使用XPath来定位要修补的文档中的位置。它非常适合调整配置文件。
有open source implementation in Java(免责声明:我是作者)。它包括一个过滤器,可以在Gradle中使用该过滤器在任何实现CopySpec的任务期间修补XML文件。例如:
buildscript {
repositories { jcenter() }
dependencies { classpath "com.github.dnault:xml-patch:0.3.0" }
}
import com.github.dnault.xmlpatch.filter.XmlPatch
task copyAndPatch(type: Copy) {
// Patch file in RFC 5621 format
def patchPath = 'local/applicationContext-patch.xml'
inputs.file patchPath
into('META-INF') {
from 'deployment', {
include 'applicationContext.xml'
rename { 'jboss-spring.xml' }
filter(XmlPatch, patch: patchPath)
}
}
}