为什么Gradle Copy任务会对目标目录中的所有内容进行快照?

时间:2014-02-23 10:04:12

标签: gradle file-permissions

我遇到了Copy任务的问题,如以下示例所示:

task deploy(type: Copy) {
    from "foo.txt"
    into "/deployment"
}

其中/deployment的内容如下:

-rw-r--r--  1 oliverc  oliverc    343 Feb 20 14:18 foo.txt
drwxr-x--- 22 oliverc  oliverc   4096 Feb 22 00:00 basic
drwxr-x---  9 root     root      4096 Jan 24 17:55 important

当我运行./gradlew deploy --stacktrace(作为oliverc用户)时,Gradle * 会抱怨:

org.gradle.api.GradleException: Could not list contents of directory '/deployment/important' as it is not readable.
    at org.gradle.api.internal.file.collections.DirectoryFileTree.walkDir(DirectoryFileTree.java:141)
    at ... 
    at org.gradle.api.internal.changedetection.state.DefaultFileSnapshotter.snapshot(DefaultFileSnapshotter.java:44)
    at ...

显然,投诉是正确的(/deployment/importantroot所有,并且没有世界上可读的权限)。但很明显,Gradle的快照机制正在尝试捕获into目标中的所有内容。所以:

  1. 为什么Copy任务会关心此目录中不相关的内容?
  2. 是否有Gradle级别的解决方法? ** (我们假设我坚持使用这些权限和目录布局。)
  3. <小时/> <子> *这是使用Gradle 1.10测试的。我没有调查这是否是其他版本的问题。

    **我意识到我可以使用Project.copy而不是Copy任务,但后来我失去了增量部署。

2 个答案:

答案 0 :(得分:1)

它会快照所有内容,以查看任务是否是最新的。如果自上次运行任务以来源和目标没有更改,则Gradle通过不执行任何操作来优化它,并且该任务被标记为UP-TO-DATE。

我的猜测是,他们不会试图变得聪明并且确切地确定目标目录的哪些文件必须被快照,因为复制任务也接受includerename闭包,因此任务不能假设没有任何东西不会被复制到important文件夹。

通常,Gradle更好地(并假设)可以清理每个目标目录,并且目标目录不会由两个单独的任务共享。

我没有测试过这种解决方法,但我会尝试使用Project.copy()定义自己的任务,并明确而精确地指定其输入和输出,以免丢失增量部署。

答案 1 :(得分:1)

这是Copy任务的已知限制,其输出当前被定义为输出目录。我认为没有涉及Copy任务的解决方案;您可以使用Project.copy,也可以实现自己的复制任务类型,例如,将其输出定义为一组文件而不是目录。

PS:Copy并非真正增量;它可以复制一切,也可以不复制。