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

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')

Related

How do I perform a rename on only one "from" in a Gradle Copy task?

I am trying to copy from multiple "from" locations on a single Gradle Copy task. For one of those - and only one - I want to also perform a rename operation.
This code works:
task dist(type: Copy) {
from task1
rename { filename -> filename.replace '-all.jar', '.jar' }
from task2 { exclude "lib" }
into "${projectDir}/dist"
}
But the renaming operation also affects task2. I tried doing it this way:
task dist(type: Copy) {
from task1 { rename { filename -> filename.replace '-all.jar', '.jar' } }
from task2 { exclude "lib" }
into "${projectDir}/dist"
}
But it does not do the renaming operation. The exclude operation on task2 works as expected. Is it possible? Am I missing something in the syntax?
Someone posted the solution here and deleted it before I could accept/reply, so I'm posting the correct form here for future reference:
task dist(type: Copy) {
from (task1) { rename { filename -> filename.replace '-all.jar', '.jar' } }
from (task2) { exclude "lib" }
into "${projectDir}/dist"
}
Thanks, Opalo!

Using a wildcard in gradle copy task

I'd like to copy a directory using a wildcard, however the from method of the Gradle copy task doesn't accept a wildcard.
// this doesn't work
task copyDirectory(type: Copy) {
from "/path/to/folder-*/"
into "/target"
}
// this does
task copyDirectory(type: Copy) {
from "/path/to/folder-1.0/"
into "/target"
}
Just use 'include' task property to specify exact files ot directories you need to copy, something like this:
task copyDirectory(type: Copy) {
from "/path/to/"
include 'test-*/'
into "/target"
}
Update: if you want to copy only directories content, then you have to deal with every file separately, something like this:
task copyDirectory(type: Copy) {
from "/path/to/"
include 'test-*/'
into "/target"
eachFile {
def segments = it.getRelativePath().getSegments() as List
it.setPath(segments.tail().join("/"))
return it
}
includeEmptyDirs = false
}

How can I define two different 'distribution' tasks in gradle?

The normal behavior of the distTar and distZip tasks from the application plugin in gradle seems to be to copy the contents of src/dist into the zip and tar files, but I have a subfolder in src/dist that I want to exclude from the default distribution, and include it for a new (extended) task, possibly to be called distZipWithJRE.
I have been able to exclude this folder in the default task as follows:
distributions.main {
contents {
from('build/config/main') {
into('config')
}
from('../src/dist') {
exclude('jre')
}
}
}
How can I define a second task that behaves just like the original (unmodified) task?
Using Gradle 4.8 I had to tweak the answer to use 'with' from CopySpec instead
distributions {
zipWithJRE {
baseName = 'zipWithJRE'
contents {
with distributions.main.contents
}
}
}
It seems that what you're looking for is in the docs. You need to leave current settings as is and for zipWithJRE create and configure custom distribution:
distributions {
zipWithJRE {
baseName = 'zipWithJRE'
contents {
from { distributions.main.contents }
}
}
}

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