How do I extend gradle's clean task to delete a file?
Asked Answered
S

7

74

So far I've added the following to my build.gradle

apply plugin: 'base' 
clean << {
    delete '${rootDir}/api-library/auto-generated-classes/'
    println '${rootDir}/api-library/auto-generated-classes/'
}

However, not only is my file not deleted, but the print statement shows that ${rootDir} is not being converted to the root directory of my project.

Why won't this work, what concepts am I missing?

Sized answered 23/4, 2015 at 3:34 Comment(0)
W
70

You just need to use double quotes. Also, drop the << and use doFirst instead if you are planning to do the deletion during execution. Something like this:

clean.doFirst {
    delete "${rootDir}/api-library/auto-generated-classes/"
    println "${rootDir}/api-library/auto-generated-classes/"
}

Gradle build scripts are written in Groovy DSL. In Groovy you need to use double quotes for string interpolation (when you are using ${} as placeholders). Take a look at here.

Wohlen answered 23/4, 2015 at 3:55 Comment(2)
Not sure about it. It will be deleting the file at configuration phase, not during execution.Piezochemistry
The above comment is not true. doFirst is only evaluated during the execution phase. The calls doFirst and doLast can be executed multiple times. They add an action to the beginning or the end of the task’s actions list. When the task executes, the actions in the action list are executed in order. from docsCapitoline
A
63

<< is equivalent for clean.doLast. doFirst and doLast are ordering the operations at the execution phase, which is seldom relevant for delete operations.

In this case you don't need any of them. The clean task from base is of type Delete, so you simply need to pass it a closure to tell it at configuration time what to delete when it executes:

clean {
    delete 'someFile'
}

AS mushfek0001 correctly points it out in his answer, you should use double quotes for variable interpolation to work:

clean {
    delete "${buildDir}/someFile"
}

You need to have at least the base plugin applied for this to work, most other plugins, like the Java plugin either apply base or declare their own clean task of type delete Delete task. The error you would get if you don't have this is a missing clean method one.

apply plugin: 'base'
Apostle answered 29/6, 2016 at 5:44 Comment(6)
delete '${buildDir}/someFile' will not resolve the variable for buildDir. You need to use " here, e.g. delete "$buildDir/someFile"Tangled
corrected the typo of ' to ". Double wuotes are requried for GStringsApostle
But this way you completely replace the default behavior of clean. What if he has some more tasks attached to it?Wohlen
As pointed out in the documentation, the delete method of the Delete task: > Adds some files to be deleted by this task. As such, this does not replace previous behavior ( i.e. previous list of files to delete ), it just adds to it.Apostle
This results in an error for me: Could not find method clean() for arguments [build_6vh7849xb7rs3m0ite221ir66$_run_closure6@20f01807]Murtha
if you want to delete many files use delete fileTree(dir: "${projectDir}", include: '**.ext') See https://mcmap.net/q/270910/-gradle-delete-files-with-certain-extension/3495031Kissiah
T
21

In order to extend the clean task, you can use

clean.doFirst {}

or

clean.doLast {}

These will allow you to inject your own actions into the clean process. In order to delete files and directories you can use the "file" API which doesn't require any additional plugins.

Here is an example that will delete both a file and a directory as the last step in the clean task:

clean.doLast {
    file('src/main/someFile.txt').delete()
    file('src/main/libs').deleteDir()
}
Tailwind answered 20/10, 2016 at 19:7 Comment(0)
B
13

Gradle Kotlin Script analogue:

tasks {
    getByName<Delete>("clean") {
        delete.add("logs") // add accepts argument with Any type
    }
}
Brana answered 31/5, 2019 at 9:26 Comment(1)
You can also get the clean task by index: tasks["clean"]...Lowerclassman
U
12

Below one works for me (I prefer to use dependsOn),

task customCleanUp(type:Delete) {
   delete "your_folder", "your_file"
}

tasks.clean.dependsOn(tasks.customCleanUp)
Understandable answered 7/11, 2019 at 7:7 Comment(1)
It's important that the task is build with possibility of passing in parameters Authoring Tasks. This way it's easy to register a new task of a particular type and then just define your own inputs. While if task reads gradle properties directly in the action itself and you don't have option to overwrite those, maybe you won't manage to copy/duplicate it and will have to rewrite the logic in TaskAction.Lidia
S
1

There are options in gradle where you can extend a particular task ("clean" in your case) with doFirst (before the actual task), doLast (after the actual task).

You just need to replace single quotes with double quotes.

clean.doFirst {
    delete "${rootDir}/api-library/auto-generated-classes"
    println "${rootDir}/api-library/auto-generated-classes"
}
Scanlon answered 27/9, 2021 at 17:5 Comment(0)
G
1

Another solution for Kotlin DSL (build.gradle.kts):

tasks.clean {
    delete += listOf(
        "${rootDir}/logs.txt",
        projectDir.list()?.first { it/* name */ .contains("temp") }
    )
}

This deletes a file called logs.txt at the project root and deletes any directory/file that has temp in its name in this subproject (the folder containing this build file).

Georgeta answered 21/4, 2022 at 15:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.