How can I expand contents from a zipTree in a way that only the contents of a given sub directory gets extracted
Use an include filter:
task unzip(type: Copy) {
from zipTree(zipFile)
into "unzipped"
include "dir/to/unzip/**"
}
Hi Peter thank you this has but this does unzipās but it extracts the all directory tree and not the contents from that given subdirectory. Say if the contents of the zip where: /Aā+
|
BāC
|
D----E
|-----F If the include is āA/Dā, I was expecting to have only E F In the output
If the include is āA/Dā, I was expecting to have only E F In the output
Thatās not how include works. Ideally, you could achieve your goal with rename. However, rename currently operates on file names rather than file paths. What you can do is to add another copy task/action that copies everything below A/D to a new place. Or, code a solution based on zipTree(zipFile).visit { ā¦ }.
Thank you, Peter
Vote++ for a ārenameā variant that can operate on full file paths
You can use the āeachFile {}ā hook to do this.
task unzip(type: Copy) {
from zipTree(zipFile)
into "unzipped"
eachFile { FileCopyDetails fcp ->
if (fcp.relativePath.pathString.startsWith("dir/to/unzip/")) {
// remap the file to the root
fcp.relativePath = new RelativePath(fcp.file, fcp.relativePath.segments[3..-1])
} else {
fcp.exclude()
}
}
}
Thatās untested, but it should be pretty close.
docs:
http://www.gradle.org/docs/current/javadoc/org/gradle/api/file/RelativePath.html http://gradle.org/docs/current/dsl/org.gradle.api.tasks.Copy.html#org.gradle.api.tasks.Copy:eachFile(groovy.lang.Closure)
@Luke it is necessary to coerce the segments back into a String Array after removing elements. The code below works but has the unintended side effect of also copying the original directory structure with no files in it. Any thoughts?
eachFile { FileCopyDetails fcp ->
if (fcp.relativePath.pathString.startsWith(appName)) {
// remap the file to the root
def segments = fcp.relativePath.segments
def pathsegments =segments[1..-1] as String[]
fcp.relativePath = new RelativePath(!fcp.file.isDirectory(), pathsegments)
}
else {
fcp.exclude()
}
}
You need to specify to ignore empty dirs:
task unzip(type: Copy) {
ā¦
includeEmptyDirs = false
}
We actually do have directories in the structure that are empty that we would like to unzip. Any Ideas?
This is a limitation of the API. You could keep track of what all the directories will be in the eachFile, and use a ādoLast { project.delete āremapped dirā }ā.
Iām hitting this same issue. Utility could be improved if the zipTree method took argument for a directory within the archive from which to root the tree. For example:
task unzip(type: Copy) {
from zipTree(zipFile, root: 'directory/in/the/zip/to/consider/as/root')
into destDir
include 'paths/relative/to/root'
}
@Ryan, that seems like a good solution to a common problem. Raised GRADLE-3025 to track it.
Ant to the rescue! https://ant.apache.org/manual/Tasks/unzip.html
task unzip(){
ant.unzip(src: 'temp/test.war', dest:'lib', overwrite:"true") {
patternset( ) {
include( name: 'WEB-INF/lib/*.jar' )
}
mapper(type:"flatten")
}
}
Although the Copy task with the zipTree sort of makes sense, it isnāt the first place you look when trying to unzip something. Why isnāt there a wrapper task called Unzip?
+1 for GRADLE-3025.
Iām trying to combine the output of several subprojects with āapplicationā plugin into one āmasterā ādistZipā. Not being able to select the content in the subdirectories of the child distZips direclty is making me put a lot of effort into itā¦