Gradle将zip压缩为buildDir

时间:2011-11-21 16:46:03

标签: gradle

我的项目有一个远程依赖项,它实际上只是某些文件的zip,需要在某处解压缩,以便构建可以从文件生成新的java源代码。 (我一般都是在谈论核心问题,而不是具体细节)

我不希望这会如此困难,但我一直无法让它发挥作用。这就是我创造的内容:

我定义了一个新配置:

configurations {
    newConf
}

后来,我为这种配置定义了一个依赖关系。它解析为我需要爆炸的zip文件:

dependencies {
    newConf "group:name:version@zip"
}

到目前为止,这些气味对我来说都是正确的,但如果有人不同意,我会倾听。

最后,我需要定义一个将zip分解为目录的任务,然后该目录将成为以后代码生成命令的输入。

task explodeModel {
    description = "unzip model into the specified 'modelSrc' directory"

    //input is a "files" collection (usually just one:  the zip)
    //output is the specified modelSrc dir

    File modelSrc = new File("$buildDir/modelSrc")
    outputs.files modelSrc

    doLast {
        configurations.newConf.allArtifacts.each { artifact -> println artifact }
    }

}

显然doLast还没有解压缩任何东西,我只是试图获得zipfile本身的绝对路径,这就是我被困的地方。我不知道如何获取文件的路径,以便我可以解压缩它。有什么帮助吗?

非常感谢

4 个答案:

答案 0 :(得分:12)

沿着这些方向尝试一下,它应该有效:

task explodeModel(type: Copy){
  configurations.newConf.filter { it.toString().endsWith(".zip") }.each{
    from zipTree(it)
  }
  into 'output/dir'
}

当然,如果您确定配置中的工件是拉链,则可以省略.zip过滤部分。

答案 1 :(得分:5)

我在一个插件中做了类似的事情。这应该适合你:

configurations.newConf.singleFile

假设只有一个文件。返回类型为java.io.File。 有关更多信息,请查看此课程GaePlugin.groovy。相关方法是configureDownloadSdk。解压缩的任务是GaeDownloadSdkTask.groovy

答案 2 :(得分:4)

这是我最近一直在做的事情,我对它很满意:
(此示例假定名为zipFiles的配置仅包含ZIP文件。)

ext.unpackedZipFiles = fileTree("$buildDir/unpackedZipFiles") { builtBy 'unpackZipFiles' }
task unpackZipFiles(type: Copy) {
    from configurations.zipFiles.files.collect { zipTree(it) }
    into unpackedZipFiles.dir
}

详细信息

我喜欢这种方法有几件事:

  1. 解压缩的输出不是在整个构建过程中散布神奇的字符串"$buildDir/unpackedZipFiles",而是由实际的FileTree表示。这使得在将来类似复制的任务中使用输出非常简单:

    aCopyLikeTask(type: Copy) {
        from unpackedZipFiles
        // ...
    }
    
  2. 使用解压缩文件的任务不直接依赖于解压缩文件的任务。相反,它们依赖于FileTree本身,它知道如何解压缩文件。请注意FileTree扩展Buildable,因此可以是任务的依赖项:

    aNonCopyTask(dependsOn: unpackedZipFiles) << {
        // ... do stuff that references unpackedZipFiles.dir
    }
    
  3. Project.fileTree()实际上返回ConfigurableFileTree,这就是我们可以指定由其构建的一个或更多任务的原因。此接口还通过File属性提供树的根dir,这通常很方便。例如:

    myExecTask(dependsOn: unpackedZipFiles) << {
        "${unpackedZipFiles.dir}/bin/runMe".execute([], unpackedZipFiles.dir)
    }
    

答案 3 :(得分:2)

我的解决方案(适用于我们的代码)将是

的内容
task explodeModel(type: Copy) {
    configurations.newConf.resolvedConfiguration.resolvedArtifacts.each { artifact ->
        if (artifact.file.name.endsWith('.zip')) {
            from zipTree(artifact.file)
            into '.'
        }
    }
}

此解决方案的优势在于它可以解决已解决的(而不是请求的)工件。