How do I delete a subset of files?

The semantics around deletion are very confusing to me. I want to delete a subset of files in a directory during task execution. The Delete task doesn’t appear to support any include or exclude, so I tried this:

task cleanTempDir(type: Delete) {

FileTree tree = fileTree (dir: “tempDir”);

tree.exclude “dont_delete.txt”

tree.each { File file ->

delete(file)

}

}

Unforunately, probably due to the problem described by Peter on SO here, this deletes the files during configuration phase, rather than execution phase.

I don’t understand why, since it seems to me the call to delete should be on the Delete task.

I next tried this:

task cleanTempDir {

doLast {

FileTree tree = fileTree (dir: “tempDir”);

tree.exclude “dont_delete.txt”

tree.each { File file ->

delete(file)

}

}

}

This works but does not delete directories, since each iterates over each file as a full path.

How do I get Gradle to do what I want? I must be missing something. It seems like the Delete task should have some straightforward way to do this, similar to these:

task cleanTempDir(type: Delete) {

delete “tempDir” {

exclude “dont_delete.txt”

}

}

task cleanTempDir(type: Delete) {

delete “tempDir”

exclude “dont_delete.txt”

}

You need this:

task cleanTempDir(type: Delete) {
      delete fileTree(dir: "tempDir", exclude: "dont_delete.txt")
  }
1 Like

Hi Luke,

That’s cleaner syntax, but it still has the same behavior as my solution … the directories are still left behind.

Even this example (without an exclude) still leaves empty directories behind:

task cleanTempDir(type: Delete) {

delete fileTree(dir: “tempDir”)

}

I need both directories and files deleted.

I actually can’t see a way to do this. Let’s come at it a different direction.

Why do you need to delete a tree except for some files?

This is a script for deploying artifacts on a remote user’s system. FYI, I’m mimicking an existing (brittle) Ant build, and am constrained by how much logic I can change w/o introducing risk.

The directory in question contains a mix of both source and content. The source directories need to be deleted and redeployed to, whereas the content directories are quite large and need to be left alone. Something like this:

/dirToDelete/a – source files, should be deleted

/dirToDelete/b – content files, should NOT be deleted

/dirToDelete/c – content files, should NOT be deleted

/dirToDelete/d – source files, should be deleted

Now I could write a script such that it specifically deletes “a” and “d”, but I’d like to avoid having to modify the script if we happen to add an “e” directory. Ant supports this like so:

<delete>

<fileset dir="/dirToDelete">

<exclude name= “b/*” />

<exclude name= “c/*” />

</fileset>

</delete>

So ultimately I could just use AntBuilder under the hood. But it seems like this is a reasonable feature for Gradle to support.

I’ve raised GRADLE-2822 for this. You’ll have to use the Ant functionality in the meantime I’m afraid.

K, thanks for the update.