Copy files and rename - Gradle - gradle

I know there are already a couple of StackOverflow posts regarding copying and renaming for Gradle but sadly none seem to be applicable to my issue...
I'm trying to copy and rename files from multiple directories, here's my approach:
task copyReportsForDocs(type: Copy) {
from rootProject.files("path1",
"path2",
"path3",
"path4")
into genDir
rename '(.*)_$d_(.*)', '$1$2'
}
The files which should be renamed look something like this:
captured_0_foobar_request.adoc
captured_0_foobar_response.adoc
captured_1_fuubar_request.adoc
captured_1_fuubar_response.adoc
I just need the front portion to be deleted so it looks something like this:
foobar_request.adoc
foobar_response.adoc
fuubar_request.adoc
fuubar_response.adoc
Any help is appreciated, thanks!

This worked for me:
task copyReportsForDocs(type: Sync) {
from(rootProject.file("path")) {
include '**/*foo*'
rename 'captured_\\d+_(.+)', '$1'
}
}

Related

Gradle copies all the files if at least one is not up-to-date

For instance, I've got the following task:
task testCopy(type: Copy) {
from ("folder/copy_from")
into ("folder/copy_to")
eachFile {println it.name}
}
Unless the inner files of the folder copy_from are touched, task works fine. As soon as I change, let's say one file in the folder copy_from, then Gradle begins to copy all the files from copy_from folder into copy_to instead of copying only one changed/added file.
Is this behaviour expected? Is there a way to make Gradle copy only changed/added file?
Yes based on this github issue and gradle discuss:
The build is incremental in the sense that the copy task only executes
when things have changed but it isn’t incremental itself, in that it
only copies inputs that have been modified.
I couldn't find a propper solution, but one solution is just splitting your task into smaller ones with specific types.
task copy1(type: Copy) {
into 'build/out'
from ('src') {
include 'docs/*.txt'
}
eachFile {println it.name}
}
task copy2(type: Copy) {
into 'build/out'
from ('src') {
include 'docs/*.md'
}
eachFile {println it.name}
}
task copy3 {
dependsOn copy1, copy2
}
It's not exactly what you want but it improves the performance by reducing files to copy.
when you change a text file and run gradle copy3 it just copies the text files not md files.
UPDATE:
Ant copy task doesn't have this problem
from it's documentation:
By default, files are only copied if the source file is newer than the destination file, or when the destination file does not exist. However, you can explicitly overwrite files with the overwrite attribute
So you can use ant copy task instead, as we can use ant tasks from gradle:
task copyFromAnt {
doLast {
ant.copy(todir: 'build/out') {
fileset(dir: 'src')
}
}
}
ant logs the files it copies so you can check the log with help of gradle -d and grep:
gradle copyFromAnt -d | grep "\[ant:copy\]"
and to see just the files it copies with out up-to-dat and etc. you can use the below command:
gradle copyFromAnt -d | grep "\[ant:copy\] Copying"

Delete directory with all files in it using gradle task

In my project's root I have a directory as follows:
build/exploded-project/WEB-INF/classes
I want to delete all the files in the classes directory using a gradle task. I tried the of the following combinations but none of them worked:
task deleteBuild(type: Delete) {
project.delete 'build/exploded-project/WEB-INF/classes/'
}
task deleteBuild(type: Delete) {
delete 'build/exploded-project/WEB-INF/classes/'
}
task deleteBuild(type: Delete) {
delete '$rootProject.projectDir/build/exploded-project/WEB-INF/classes/'
}
task deleteBuild(type: Delete) {
delete fileTree('build/exploded-project/WEB-INF/classes').matching {
include '**/*.class'
}
}
Your second variant is correct and works fine here.
Though I'd recommend not hardcoding the path.
Use $buildDir instead of build, or if the path is the output path of another task use the respective property of that task.
If it doesn't work for you, run with -i or -d to get more information about what is going on and possibly going wrong.
As suggested a better approach is to use Gradle Variables.
Try:
task deleteBuild(type: Delete) {
delete "$buildDir/exploded-project/WEB-INF/classes/"
}
Pay attention to replace the single quote with the double one.
Regards,
S.

Delete only those folders and files that are not used by another resources from windows 'Temp 'folder using Gradle task

I am writing a gradle script to delete files and folder which are not used by other resources inside the 'Temp' folder in Windows i.e %TEMP%'. However, if some files are used by another resources, then it will not delete and throw exception when I try to delete. I tried:
task cleanTempFile(type: Delete) {
def directoryPath = "/path/to/temp/folder.."
file(directoryPath).deleteDir();
}
This will actually work as expected (not delete used ones but delete the ones that are not used by any resources). However, the problem is that it deletes the 'Temp' folder itself. I want to KEEP the Temp folder but delete contents inside of it. I tried :
task cleanTempFile(type: Delete) {
//delete files
delete fileTree(dir: 'path/to/temp/folder' , include: '**/*.*')
//deletes folder
file( directoryPath ).list().each{
a -> delete "path/to/temp/folder/${a}"
}
}
but it gives me error saying unable to delete the file. It does not work if any of the files and folder are used by other resources (e.g open a file and try to delete the folder, unopened or unused are not deleted). Is there any way I can achieve this? I appreciate any help or suggestion. Thank you.

how to exclude path information in gradle zip task

Apologies in advance for this simple question I am relatively new to Gradle.
I would like to run a Zip task during my Build process and create a .zip file in my "archive" directory but without the source file's directory structure. I managed to get the task working but its retaining the directory structure. I read that for linux Zip there is the option -j or -r which flattens the directory but I am not sure if this is available to me via the Gradle task.
My input file structures looks similar to the below,
./libs/
./libs/file1.jar
./scripts/script1.sh
./scripts/script2.sh
but I would like to end up with a Zip file with directory structure as follows,
./
./file1.jar
./script1.sh
./script2.sh
My current Zip task is as follows,
task makeZipForDeploy(type: Zip) {
from 'build/'
include 'libs/*' //to include all files in libs folder
include 'scripts/*' //to include all files in the scripts folder
archiveName("${archiveFileName}")
destinationDir file("${archivePath}")
}
the solution was even more trivial than I thought. The below will flatten the structure
task makeZipForDeploy(type: Zip) {
from 'build/libs' //to include all files in libs folder
from 'build/scripts' //to include all files in the scripts folder
archiveName("${archiveFileName}")
destinationDir file("${archivePath}")
}

Regex Directory matching in Groovy

As part of Gradle delete task, I would like to delete all tar files beginning with CSW and ending with .tar.gz from a directory. How can I achieve it with Groovy?
I tried something like below:
delete (file('delivery/').eachDirMatch(~/^CSW$.*.gz/))
But it doesn't work. How do I employ the regex in Groovy. As compared to shell it is something like rm -rf CSW*.tar.gz
I will answer with a gradle solution as you refer to gradle in your question. Something along the lines of:
myTask(type: Delete) {
delete fileTree(dir: 'delivery' , include: '**/CSW*.tar.gz')
}
where the delete method call is configuration time and configures what will be deleted when the task eventually runs. For details it might be worth looking through the gradle docs on the fileTree method.
If you need to stay pure groovy you could do something along the lines of:
new AntBuilder().fileScanner {
fileset(dir: 'delivery', includes: '**/CSW*.tar.gz')
}.each { File f ->
f.delete()
}
If this code lives in a gradle script I would recommend sticking with option one as it retains the gradle up-to-date checking and fits well within the gradle configuration vs execution time pattern.
If you really want to go regex as opposed to the above style patterns you can certainly do that, though I would personally not see much of a point given your requirements.

Resources