Always up-to-date if ouput directory is deleted

Task:

task generateJavadoc(type: Javadoc) {
    source = sourceSets.main.java
    classpath = sourceSets.main.compileClasspath + sourceSets.main.runtimeClasspath
    destinationDir = file("${buildDir}/javadoc-public-html")

    doLast {
        //...some other logic...
        //
        delete "${buildDir}/javadoc-public-html"
    }
}

Is always up-to-date starting from second gradle call.

Gradle command: gradle clean assemble generateJavadoc

Please explain why it is always up-to-date. Currently I’m solving this with outputs.upToDateWhen { false }

Your destinationDir is set to ${buildDir}/javadoc-public-html. The task creates this directory and writes Javadoc to it. Then the last thing you do is delete "${buildDir}/javadoc-public-html".

Therefore, the only output of the task is a non-existent directory, which Gradle determines on the first run. Gradle already sees you have the expected state (non-existent directory) on the second run, so there’s no reason to run the task again. If ...some other logic... is actually creating other output, you’re not properly declaring that.

Yes, I create another output there. Here is the full task code

task generateJavadoc(type: Javadoc) {
    source = sourceSets.main.java
    classpath = sourceSets.main.compileClasspath + sourceSets.main.runtimeClasspath
    includes = includesPatternForPublicFiles(sourceSets.main.java)
    destinationDir = file("${buildDir}/javadoc-public-html")

    doLast {
        ant.jar(compress: "true", destfile: "${buildDir}/javadoc-public/modulename-javadoc.jar", basedir: "${buildDir}/javadoc-public-html")
        delete "${buildDir}/javadoc-public-html"
    }
}

Any advice about output declaration not to have the task always up-to-date?

You should minimally declare ${buildDir}/javadoc-public as an output directory or ${buildDir}/javadoc-public/modulename-javadoc.jar as an output file.

However, deleting the directory in the task as well as combining the generation and jar creation is atypical. Generally, these would be two separate tasks that depend on each other and you would not delete the folder as part of the regular build.