Thunderforge
Thunderforge

Reputation: 20595

How can I use the Gradle Copy task to rename a directory on the path of a file I am copying?

Background

I have a Gradle Copy task like this:

task copyFromZip(type: Copy) {
    from zipTree("Example.zip")
    into "build/output"
}

Within the Zip file is something like this:

+--- photos
|    +--- StackOverflow
|         \--- foo.png
|    \--- Super User
|         \--- bar.png
+--- text
|    \--- Stack Exchange
|        +--- StackOverflow
|             \--- foo.txt
|        \--- Super User
|             \--- bar.txt

When I run the Copy task, the directories are preserved. For instance, I have build/output/photos/StackOverflow/foo.png.

Goal

What I want to do is rename the directories as I copy. For instance, say I realized that "StackOverflow" should have spaces in it. I want the file photos/StackOverflow/foo.png to be copied to build/output/photos/Stack Overflow/foo.png, and the same to be applied to the files in other folders with the name "StackOverflow" instead of "Stack Overflow".

What I've tried

My first thought was to add a rename{} block.

task copyFromZip(type: Copy) {
    from zipTree("Example.zip")
    into "build/output"
    rename { String filePath ->
        filePath.replace("StackOverflow", "Stack Overflow")
    }
}

However, I discovered that rename{} only gives the name of the file, not the path.

I also tried manipulating the relativePath using eachFile{}

task copyFromZip(type: Copy) {
    from zipTree("Example.zip")
    into "build/output"
    eachFile{ file ->
        file.relativePath = file.relativePath.replace("StackOverflow", "Stack Overflow")
    }
}

However, that results in a Could not expand ZIP error.

How can I use the Gradle Copy task to rename a directory on the path of a file I am copying?

Upvotes: 1

Views: 5511

Answers (1)

JB Nizet
JB Nizet

Reputation: 692181

You can use eachFile or filesMatching, which gives you access to all the details of the source path and of the destination path. For example:

task copy(type: Copy) {
    from zipTree("Example.zip")
    into "build/output"
    filesMatching("**/StackOverflow/**/*") {
        it.path = it.path.replace("StackOverflow", "Stack Overflow")
    }
}

Upvotes: 7

Related Questions