在 Gradle 中压平 FileTree 的第一个目录

问题描述 投票:0回答:3

我正在编写一个任务来将 tarball 提取到目录中。我无法控制这个 tarball 的内容。

压缩包包含一个目录,其中包含我真正关心的所有文件。我想从该目录中提取所有内容并将其复制到我的目的地。

示例:

/root/subdir
/root/subdir/file1
/root/file2

想要的:

/subdir
/subdir/file1
/file2

这是我迄今为止尝试过的方法,但这似乎是一种非常愚蠢的方法:

copy {
    eachFile {
        def segments = it.getRelativePath().getSegments() as List
        it.setPath(segments.tail().join("/"))
        return it
    }
    from tarTree(resources.gzip('mytarfile.tar.gz'))
    into destinationDir
}

对于每个文件,我获取其路径的元素,删除第一个,用

/
连接它,然后将其设置为文件的路径。这确实有效......有点。问题是这会产生以下结构:

/root/subdir
/root/subdir/file1
/root/file2
/subdir
/subdir/file1
/file2

我可以自己删除根目录作为任务的最终操作,但我觉得应该有一种更简单的方法来执行此操作。

groovy gradle
3个回答
3
投票

使用groovy的语法,我们可以使用正则表达式来消除第一个路径段:

task myCopyTask(type: Copy) {
    eachFile {
        path -= ~/^.+?\//
    }
    from tarTree(resources.gzip('mytarfile.tar.gz'))
    into destinationDir

    includeEmptyDirs = false // ignore empty directories
}

2
投票

AFAIK,唯一的方法是解压 zip、tar、tgz 文件:(

这里有一个未解决的问题 请大家去投票吧!

在那之前,解决方案不是很漂亮,但也不是那么难。 在下面的示例中,我假设您想要从仅包含 apache-tomcat zip 文件的“tomcat”配置中删除“apache-tomcat-XYZ”根级目录。

def unpackDir = "$buildDir/tmp/apache.tomcat.unpack" task unpack(type: Copy) { from configurations.tomcat.collect { zipTree(it).matching { // these would be global items I might want to exclude exclude '**/EMPTY.txt' exclude '**/examples/**', '**/work/**' } } into unpackDir } def mainFiles = copySpec { from { // use of a closure here defers evaluation until execution time // It might not be clear, but this next line "moves down" // one directory and makes everything work "${unpackDir}/apache-tomcat-7.0.59" } // these excludes are only made up for an example // you would only use/need these here if you were going to have // multiple such copySpec's. Otherwise, define everything in the // global unpack above. exclude '**/webapps/**' exclude '**/lib/**' } task createBetterPackage(type: Zip) { baseName 'apache-tomcat' with mainFiles } createBetterPackage.dependsOn(unpack)
    

0
投票
Gradle 团队使用 stdlib

扩展了文档来解决这个问题(与 JoeG 链接的相同)

让我引用相关部分

tasks.register<Copy>("unpackLibsDirectory") { from(zipTree("src/resources/thirdPartyResources.zip")) { include("libs/**") eachFile { relativePath = RelativePath(true, *relativePath.segments.drop(1).toTypedArray()) } includeEmptyDirs = false } into(layout.buildDirectory.dir("resources")) }

  • include
     仅提取位于 libs 目录中的文件子集
  • eachFile
     通过从文件路径中删除 libs 段,将解压文件的路径重新映射到目标目录
  • includeEmptyDirs
     忽略重新映射产生的空目录,请参阅下面的注意事项
注意:您无法使用此技术更改空目录的目标路径。您可以在本期

问题中了解更多信息。

© www.soinside.com 2019 - 2024. All rights reserved.