Gradle zip任务失败,因为zip不存在

Gradle zip任务失败,因为zip不存在,gradle,Gradle,我有一个gradle构建脚本,其中包含一个类似于以下内容的任务: task unzip_foo_bar (type: Copy) { from zipTree ("foo.zip").matching { include '**/bar.h' }.singleFile into "build" } 在执行任务之前,会将.zip文件从外部存储库提取到本地工作区 但出于某种原因,当您将.matching与.singleFile一起使用时,Gradle希望在编译脚本时,zip文件已经

我有一个gradle构建脚本,其中包含一个类似于以下内容的任务:

task unzip_foo_bar (type: Copy) {
    from zipTree ("foo.zip").matching { include '**/bar.h' }.singleFile
    into "build"
}
在执行任务之前,会将.zip文件从外部存储库提取到本地工作区

但出于某种原因,当您将.matching与.singleFile一起使用时,Gradle希望在编译脚本时,zip文件已经存在于本地工作区中

在这种情况下,由于.zip文件在编译时不存在,脚本编译失败

因此,以下工作没有问题:

task unzip_foo_bar (type: Copy) {
    from zipTree ("foo.zip")
    into "build"
}
在本例中,Gradle能够编译脚本,并且它可以正常工作

有人能解释行为上的差异吗

第一个实现的原因是,我希望能够从.zip存档中提取单个文件,而不是将存档中的所有文件转储到本地工作区


我该怎么做呢?

Gradle中的方法
zipTree
返回一个
FileTree
,它支持延迟求值,因此只有在需要时才确定树的内容。各种任务类型(如
Copy
任务)通过允许用户传递树作为输入来支持此行为。可以在配置阶段构造树,但只有在执行任务时,才会在执行阶段查询树

现在,第一个示例的问题是调用
singleFile
会触发树计算,因为它需要返回
File
的实例。要查找该文件,Gradle需要打开
.zip
文件,但由于找不到该文件而失败。
匹配
调用不是问题,因为它会创建另一个
文件树
。因此,只需放弃对
singleFile
的调用,您的代码就可以工作了:

from zipTree ("foo.zip").matching { include '**/bar.h' }
但是,如果希望保留仅一个文件与模式匹配的断言,可以将表达式包装在一个
闭包中,该闭包将作为一个整体进行惰性计算:

from { zipTree ("foo.zip").matching { include '**/bar.h' }.singleFile }

Gradle中的方法
zipTree
返回一个
FileTree
,它支持延迟求值,因此只有在需要时才确定树的内容。各种任务类型(如
Copy
任务)通过允许用户传递树作为输入来支持此行为。可以在配置阶段构造树,但只有在执行任务时,才会在执行阶段查询树

现在,第一个示例的问题是调用
singleFile
会触发树计算,因为它需要返回
File
的实例。要查找该文件,Gradle需要打开
.zip
文件,但由于找不到该文件而失败。
匹配
调用不是问题,因为它会创建另一个
文件树
。因此,只需放弃对
singleFile
的调用,您的代码就可以工作了:

from zipTree ("foo.zip").matching { include '**/bar.h' }
但是,如果希望保留仅一个文件与模式匹配的断言,可以将表达式包装在一个
闭包中,该闭包将作为一个整体进行惰性计算:

from { zipTree ("foo.zip").matching { include '**/bar.h' }.singleFile }