我正在使用这个简单的Gradle任务:
task syncTask(type: Sync) {
from "src/"
into "dest/"
}
根据docs,我希望将src
复制到dest
,src
中不存在的任何文件都会从dest
中删除。这基本上工作正常。但是,如果在同步后将文件添加到dest
,则在任务再次运行时无法识别。该项目简单地被认为是UP-TO-DATE,不采取任何行动。
是否可以配置同步任务,以便检测目标目录中添加的文件并再次运行任务?
> gradle -v
------------------------------------------------------------
Gradle 1.9
------------------------------------------------------------
Build time: 2013-11-19 08:20:02 UTC
Build number: none
Revision: 7970ec3503b4f5767ee1c1c69f8b4186c4763e3d
Groovy: 1.8.6
Ant: Apache Ant(TM) version 1.9.2 compiled on July 8 2013
Ivy: 2.2.0
JVM: 1.7.0_25 (Oracle Corporation 23.7-b01)
OS: Linux 3.2.0-53-generic amd64
编辑1:以下是重现行为的步骤:
$ mkdir src
$ touch src/a
$ mkdir dest
$ gradle syncTask
:syncTask
BUILD SUCCESSFUL
Total time: 1.113 secs
$ ls dest/
a
到目前为止,一切都按预期工作。现在,文件b
已添加到dest/
文件夹:
$ touch dest/b
$ ls dest/
a b
$ gradle syncTask
:syncTask UP-TO-DATE
BUILD SUCCESSFUL
Total time: 1.024 secs
我希望从b
中移除dest/
。但是,Sync任务似乎没有注意到它的输出已经改变,因此没有运行。
答案 0 :(得分:2)
是的,似乎Sync任务有点坏了,在Gradle 1.10中也是如此。 为了解决这个问题,我很快就破解了一个自定义任务,只需将它放在脚本中。
class SyncDir extends DefaultTask {
def inDir
def outDir
@TaskAction
def run() {
project.delete outDir
project.copy { from inDir; into outDir }
}
def from(name) {
inDir = new File(name)
}
def into(name) {
outDir = new File(name)
}
}
您可以像使用同步任务一样使用它。
task toto (type: SyncDir) {
from 'toto'
into 'tata/toto'
}
答案 1 :(得分:2)
据我所知,问题与此问题https://issues.gradle.org/browse/GRADLE-2270有关。如果所有输入文件都存在并且是最新的,则同步任务被视为最新,忽略任何其他文件。它在Gradle 1.0中报告过,但在Gradle 2.0中仍无效。
作为解决方法,我将以下块添加到我的同步任务
outputs.upToDateWhen {
def Set<String> names = inputs.files.files.collect{ _ -> _.name }
def Set<String> destDirContent = destinationDir.list().toList().toSet()
def boolean good = names.containsAll(destDirContent)
return good
}
在您的情况下,任务应该如下所示。
task syncTask(type: Sync) {
from "src/"
into "dest/"
outputs.upToDateWhen {
def Set<String> names = inputs.files.files.collect{ _ -> _.name }
def Set<String> destDirContent = destinationDir.list().toList().toSet()
def boolean good = names.containsAll(destDirContent)
return good
}
}
但是当源目录为空时,它不起作用(即任务被认为是UP-TO-DATE),这可能是因为Gradle代码中的一些快捷方式。这对我来说不是问题,所以我没有试图找到更好的解决方案,只是要注意这个案例。