android-studiogradleandroid-gradle-plugin

project-level build.gradle is missing the clean() task


My project-level (aka top-level, not module-level) build.gradle contains the following:

// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
    repositories {
        gradlePluginPortal()  
        mavenCentral()
        google()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:8.5.2'
        classpath("de.mannodermaus.gradle.plugins:android-junit5:1.8.2.1")
        classpath("org.mockito:mockito-inline:5.2.0")
    }
}

allprojects {
    repositories {
        gradlePluginPortal()
        mavenCentral()
        google()
    }
}

It works fine but an "old book" (circa Android Studio Arctic Fox, 2020.3.1) that discusses Gradle says that is should contain a clean task.

Then again, after a few paragraphs it also says

As written, this task is almost useless, and it is unclear why Google includes it, other than perhaps to point out that you are able to define custom tasks.

So I am unsure whether it must be there or not. Perhaps in the latest & greatest Android Studio (Koala, 2024.1.1) it is implied and is no longer needed?

How does this work?


Solution

  • The part you showed of your build script is actually all bad practice.

    If you want to define custom repositories where to retrieve plugins from (first third of your snippet), use the repositories block within the pluginManagement block within your settings script.

    If you want to add plugins to the classpath (the second third of your snippet) you should use the plugins { ... } block with apply false for the plugins.

    If you want to define repositories for all projects, use the repositories block within the dependencyResolutionManagement block within your settings script.

    Never use any way of cross-project configuration like allprojects { ... } or subprojects { ... } or project("...") { ... } or any other means. They immediately introduce project coupling which works against more sophisticated Gradle features and optimizations. If you want to share build logic, you should put it to convention plugins, for example implemented as precompiled script plugins, for example within buildSrc or any included build which is what I prefer.


    But regarding the actual question, you should usually never have a manual clean task.

    If you apply any plugin - at least the built-in ones or any that transitively applies a built-in plugin, you will also automatically apply the lifecycle-base plugin. That plugin adds a standard clean task that deletes the layout.buildDirectory. It also adds a task rule that adds a cleanXXX task for every task XXX that deletes the outputs of that task.

    If you do not apply any plugin that causes the lifecycle-base plugin to be applied, you will not have a clean task in that project. If you do, then you have it. It is usually always preferable not to register an own clean task. If there are no plugins applied, then most probably there is also nothing to clean up. And if there is something to clean up, it is better to just manually apply the lifecycle-base plugin and configure the standard clean task to delete additional locations like for example with

    tasks.clean {
        delete(layout.projectDirectory.dir("dist"))
    }