Remove a directory when unzipping - gradle

I am unpacking a zip file into a directory. The zip file has an extra top level directory that I don't want in the unzipped destination.
task unpackDojoSource(type: Copy) {
new File("build/dojo/src").mkdirs()
from(zipTree(dojoSource)) {
eachFile { details -> details.path =
details.path.substring(details.relativePath.segments[0].length()) }
} into "build/dojo/src"
}
The task produces the following output
/dijit
/dojo
/dojo-release-1.7.2
/dijit
/dojo
/dojox
/util
/dojox
/util
Is there a way I can prevent the dojo-release directory from being created?
Ref:
http://gradle.markmail.org/thread/x6gmbrhhen63rybe#query:+page:1+mid:lws7nlqcncjumnvs+state:results

I just stumble upon the same problem. Only thing you need to do is to add includeEmptyDirs = false into your copy spec like this:
task unpackDojoSource(type: Copy) {
new File("build/dojo/src").mkdirs()
from(zipTree(dojoSource)) {
eachFile { details -> details.path =
details.path.substring(details.relativePath.segments[0].length()) }
} into "build/dojo/src"
includeEmptyDirs = false
}
The resulting structure will not contain the empty directories left by flattening.

I've just ran across this myself. I worked around it by doing a delete afterwards. Less than ideal but still effective.
delete "dojo-release-1.7.2"

Related

Gradle task to delete contents in a directory but exclude jar file

I still trying to learn Gradle Task authoring.
I found the following solution to help with deleting the contents of a directory while leaving the directory untouched.
However can I please have help modifying it to exclude specific files such as the .jar file?
How to delete an empty directory (or the directory with all contents recursively) in gradle?
The solution was given by Heri
task deleteGraphicsAssets(type: Delete) {
def dirName = "src"
file( dirName ).list().each{
f -> delete "${dirName}/${f}"
}
}
task deleteGraphicsAssets(type: Delete) {
doLast {
file('src').eachFileRecurse(groovy.io.FileType.FILES) { File file ->
//Delete all files except *.jar
if (!file.name.endsWith('.jar')) {
delete file
}
}
}
}
Another option, is using Filetree for more advanced filter, for example:
task deleteGraphicsAssets(type: Delete) {
delete fileTree(dir: "tempDir", exclude: "dontDelete.jar")
}

Gradle zip: how to include and rename one file easily?

Create a zip adding file "hello/world.xml" under directory "foo/bar" as "hello/universe.xml"
task myZip(type: Zip) {
from ("foo/bar") {
include "hello/world.xml"
filesMatching("hello/*") {
it.path = "hello/universe.xml"
}
}
}
filesMatching(...) will impact performance obviously.
What is a better way? like:
task myZip(type: Zip) {
from ("foo/bar") {
include ("hello/world.xml") {
rename "hello/universe.xml"
}
}
}
But rename is not supported with include.
I don't get why you are using filesMatching at all. You are only including one single file in your child CopySpec. Simply rename it and everything is fine:
task myZip(type: Zip) {
from ('foo/bar') {
include 'hello/world.xml'
rename { 'hello/universe.xml' }
}
}
If you want to include multiple files (or even copy all), but only want to rename one of them, specify which file(s) to rename with a regular expression as first argument:
task myZip(type: Zip) {
from 'foo/bar'
rename 'hello/world.xml' 'hello/universe.xml'
}
If the last one did not work, try:
rename ('a.java', 'b.java')

Weird behaviour of a simple gradle copy task

I am completely baffled by the gradle behaviour of a Copy task into multiple directories.
I intend to copy all files from src/common into
target/dir1/ps_modules
target/dir2/ps_modules
target/dir3/ps_modules
Below is how my build.gradle looks:
project.ext.dirs = ["dir1", "dir2", "dir3"]
// ensures that ps_modules directory is created before copying
def ensurePsModulesDir() {
dirs.each {
def psModules = file("target/$it/ps_modules")
if (!(psModules.exists())) {
println("Creating ps_modules directory $psModules as it doesn't exist yet")
mkdir psModules
}
}
}
task copyCommons(type: Copy) {
doFirst {
ensurePsModulesDir()
}
from("src/common")
dirs.each {
into "target/$it/ps_modules"
}
}
The result of running the command ./gradlew copyCommons is completely weird.
The folder creation works as expected, however, the contents/files are copied only in the target/dir3/ps_modules directory. The rest two directories remain empty.
Any help would be appreciated.
Below is the screen grab of target directory tree once the job is run:
I think you want to do something like:
task copyCommons(type: Copy) {
dirs.each {
with copySpec {
from "src/common"
into "target/$it/ps_modules"
}
}
}
I think you can get rid of the ensurePsModulesDir() with this change
* edit *
it seems that the copy task is forcing us to set a destination dir. You might think that setting destinationDir = '.' is ok but it's used in up-to-date checking so likely the task will NEVER be considered up-to-date so will always run. I suggest you use project.copy(...) instead of a Copy task. Eg
task copyCommons {
// setup inputs and outputs manually
inputs.dir "src/common"
dirs.each {
outputs.dir "target/$it/ps_modules"
}
doLast {
dirs.each { dir ->
project.copy {
from "src/common"
into "target/$dir/ps_modules"
}
}
}
}
You can configure a single into for a task of type Copy. In this particular example gradle behaves as expected. Since dir3 is the last element on the list it is finally configured as a destination. Please have a look at this question - which you can find helpful. Also this thread might be helpful as well.

Gradle copy without overwrite

Is there a way to avoid overwriting files, when using task type:Copy?
This is my task:
task unpack1(type:Copy)
{
duplicatesStrategy= DuplicatesStrategy.EXCLUDE
delete(rootDir.getPath()+"/tmp")
from zipTree(rootDir.getPath()+"/app-war/app.war")
into rootDir.getPath()+"/tmp"
duplicatesStrategy= DuplicatesStrategy.EXCLUDE
from rootDir.getPath()+"/tmp"
into "WebContent"
}
I want to avoid to specify all the files using exclude 'file/file*'.
It looks like that duplicatesStrategy= DuplicatesStrategy.EXCLUDE doesn't work. I read about an issue on gradle 0.9 but I'm using Gradle 2.1.
Is this problem still there?
Or am I misunderstanding how this task should be used properly?
Thanks
A further refinement of BugOrFeature's answer. It's using simple strings for the from and into parameters, uses the CopySpec's destinationDir property to resolve the destination file's relative path to a File:
task ensureLocalTestProperties(type: Copy) {
from zipTree('/app-war/app.war')
into 'WebContent'
eachFile {
if (it.relativePath.getFile(destinationDir).exists()) {
it.exclude()
}
}
}
You can always check first if the file exists in the destination directory:
task copyFileIfNotExists << {
if (!file('destination/directory/myFile').exists())
copy {
from("source/directory")
into("destination/directory")
include("myFile")
}
}
Sample based on Peter's comment:
task unpack1(type: Copy) {
def destination = project.file("WebContent")
from rootDir.getPath() + "/tmp"
into destination
eachFile {
if (it.getRelativePath().getFile(destination).exists()) {
it.exclude()
}
}
}

How to delete an empty directory (or the directory with all contents recursively) in gradle?

I can't figure out how to delete all contents of a directory.
For cleaning out a directory, I want to remove all files and directories inside it: I want to wipe everything there is inside (files and directories).
I tried this with the delete task, but I can't figure out to make it also remove directories and not just files. I've tried different ways to specify the directories, but nothing works.
task deleteGraphicsAssets(type:Delete) {
delete fileTree('src').include('**/*')
}
.
task deleteGraphicsAssets(type:Delete) {
delete fileTree('src').include('/')
}
.
task deleteGraphicsAssets(type:Delete) {
delete fileTree('src').include('*')
}
Any help appreciated!
Edit:
This works - yet it seems a bit like a hack.
task deleteGraphicsAssets(type: Delete) {
def dirName = "src"
delete dirName
doLast {
file(dirName).mkdirs()
}
}
I was looking for something like:
task deleteGraphicsAssets(type: Delete) {
deleteContentsOfDirectory "src"
}
or
task deleteGraphicsAssets(type: Delete) {
delete {dir : "src", keepRoot : true }
}
To delete the src directory and all its contents:
task deleteGraphicsAssets(type: Delete) {
delete "src"
}
At the risk of resurrecting an answered topic, there's a relatively easy way to do this.
This task will delete all files and directories under 'src' without traversing the file tree and without removing to 'src' dir
task deleteGraphicsAssets(type:Delete) {
delete file('src').listFiles()
}
Groovy enhances the File class with several methods. You can delete a directory with all it's subdirectories and files using deleteDir() method.
task deletebin << {
def binDir = new File('bin')
binDir.deleteDir()
}
Following will delete all content from the src folder but leaves the folder itself untouched:
task deleteGraphicsAssets(type: Delete) {
def dirName = "src"
file( dirName ).list().each{
f ->
delete "${dirName}/${f}"
}
}
clean {
delete += fileTree('src').include('**/*')
}
This 'clean' task's configuration seems to work.
Found using FileTree#visit worked.
ConfigurableFileTree ft = fileTree('someDir')
ft.include("xxx")
ft.exclude("yyy")
task delteFilesOnly() {
doLast {
//// for test
//ft.each { File file ->
// println "===== " + file.absolutePath
//}
delete ft
}
}
task deleteFilesAndDirs(){
doLast {
ft.visit { FileVisitDetails fvd ->
//// for test
//println "----- " + file.absolutePath
delete fvd.file
}
}
}

Resources