如何使用Gradle从包含TGZ的TAR中提取文件?

如何使用Gradle从包含TGZ的TAR中提取文件?,gradle,tar,docker-image,Gradle,Tar,Docker Image,我有一个tar文件,其中包含多个tar.gz文件(Docker图像),我想从中提取一个文件。在shell脚本中实现这一点很简单,但在使用Gradle时似乎有点棘手 这就是我到目前为止所做的: task extractOuter(type: Copy) { dependsOn jibBuildTar from tarTree(file("${buildDir}/jib-image.tar")) include "*.tar.gz"

我有一个
tar
文件,其中包含多个
tar.gz
文件(Docker图像),我想从中提取一个文件。在shell脚本中实现这一点很简单,但在使用Gradle时似乎有点棘手

这就是我到目前为止所做的:

task extractOuter(type: Copy) {
    dependsOn jibBuildTar
    from tarTree(file("${buildDir}/jib-image.tar"))
    include "*.tar.gz"
    into "${buildDir}/tgz"
}

task extractInner(type: Copy) {
    dependsOn extractOuter
    from (fileTree(dir: "${buildDir}/tgz").collect { tarTree(it) }) {
        include "**/filename"
        includeEmptyDirs = false
    }
    into "${buildDir}/files"
}
一开始它似乎可以工作,但后来证明它偶尔会失败:
extractInner
任务找不到该文件。也许我没有正确使用Gradle的懒惰评估

如何让它工作?还是有完全不同的更优雅的方式

在shell脚本中执行此操作非常简单

您可以通过使用任务类型继续使用shell脚本

但使用Gradle时似乎有点棘手

到目前为止,你所知道的是你是如何与格拉德合作的。Gradle的优点是它不会执行已经发生的工作。有关更多详细信息,请参阅

一开始它似乎可以工作,但后来证明它偶尔会失败:ExtractInternal任务找不到该文件。也许我没有正确使用Gradle的懒惰评估

这在上面链接的文档(我的重点)中被调用:

有些任务,如复制或Jar,通常没有意义使其可缓存,因为Gradle只是将文件从一个位置复制到另一个位置。将不产生输出或没有任务操作的任务设为可缓存,也没有意义

因此,您已经声明了任务,但尚未将其配置为生成任何可能导致或可能不导致问题的输出,因为您希望任务依赖项的输出存在

由于扩展,您可以使用
输出
设置任务输出

task extractOuter(type: Copy) {
    dependsOn jibBuildTar
    outputs.dir(file("$buildDir/tgz")
    from tarTree(file("${buildDir}/jib-image.tar"))
    include "*.tar.gz"
    into "${buildDir}/tgz"
}

task extractInner(type: Copy) {
    dependsOn extractOuter
    outputs.dir(file("$buildDir/files")
    from (fileTree(dir: "${buildDir}/tgz").collect { tarTree(it) }) {
        include "**/filename"
        includeEmptyDirs = false
    }
    into "${buildDir}/files"
}

添加
outputs.dir
无法解决问题。然而,你的回答帮助我更好地理解了格拉德尔。我在完成任务的最后一个任务中使用了
doFirst
块。