diff --git a/gradle/defaults.gradle b/gradle/defaults.gradle index a011add67b9..0ce26d143c9 100644 --- a/gradle/defaults.gradle +++ b/gradle/defaults.gradle @@ -63,5 +63,17 @@ allprojects { scriptResources = { buildscript -> return file(buildscript.sourceFile.absolutePath.replaceAll('.gradle$', "")) } + + // LUCENE-9505: utility function that sets up dummy outputs for a task so that + // clean[TaskName] works and allows selective re-runs. + setupDummyOutputs = { Task task -> + File dummyOutput = file("${task.project.buildDir}/tasks/${task.name}/dummy-output.txt") + task.outputs.file(dummyOutput) + task.doLast { + if (!dummyOutput.exists()) { + dummyOutput.createNewFile() + } + } + } } } diff --git a/gradle/validation/ecj-lint.gradle b/gradle/validation/ecj-lint.gradle index 3dcb2c00669..1e645d0f8dc 100644 --- a/gradle/validation/ecj-lint.gradle +++ b/gradle/validation/ecj-lint.gradle @@ -37,7 +37,7 @@ allprojects { def lintTasks = sourceSets.collect { sourceSet -> def srcDirs = sourceSet.java.srcDirs.findAll { dir -> dir.exists() } - tasks.create(sourceSet.getTaskName("ecjLint", null), JavaExec, { + tasks.create(sourceSet.getTaskName("ecjLint", null), JavaExec, {task -> // This dependency is on a configuration; technically it causes // all dependencies to be resolved before this task executes // (this includes scheduling tasks that compile the @@ -46,8 +46,9 @@ allprojects { // The inputs are all source files from the sourceSet. inputs.files sourceSet.allSource.asFileTree - // The outputs are always up to date (we don't generate anything). - outputs.upToDateWhen { true } + + // This task has no proper outputs. + setupDummyOutputs(task) // We create a task for all source sets but ignore those // that don't have any Java source directories. diff --git a/gradle/validation/gradlew-scripts-tweaked.gradle b/gradle/validation/gradlew-scripts-tweaked.gradle index c0bc6472c4e..fa3ba6d883e 100644 --- a/gradle/validation/gradlew-scripts-tweaked.gradle +++ b/gradle/validation/gradlew-scripts-tweaked.gradle @@ -21,14 +21,16 @@ import java.nio.charset.StandardCharsets // don't fork a daemon subprocess on the initial run. configure(rootProject) { - task gradlewScriptsTweaked() { + task gradlewScriptsTweaked() { task -> def scripts = [ file("gradlew"), file("gradlew.bat") ] inputs.files(scripts) - outputs.upToDateWhen { true } + + // This task has no proper outputs. + setupDummyOutputs(task) doFirst { scripts.each { file -> diff --git a/gradle/validation/validate-log-calls.gradle b/gradle/validation/validate-log-calls.gradle index cd99901d04d..b548c2116ce 100644 --- a/gradle/validation/validate-log-calls.gradle +++ b/gradle/validation/validate-log-calls.gradle @@ -36,10 +36,13 @@ import org.apache.tools.ant.BuildException configure(subprojects.findAll { it.path.startsWith(':solr') }) { plugins.withType(JavaPlugin) { - task validateLogCalls(type: ValidateLogCallsTask) { + task validateLogCalls(type: ValidateLogCallsTask) { task -> description "Checks that log calls are either validated or conform to efficient patterns." group "verification" + // This task has no proper outputs. + setupDummyOutputs(task) + sourceFiles = files(sourceSets*.java) } } @@ -230,11 +233,6 @@ class ValidateLogCallsTask extends DefaultTask { @InputFiles FileCollection sourceFiles - ValidateLogCallsTask() { - // No explicit outputs (outputs always up to date). - outputs.upToDateWhen { true } - } - @TaskAction def checkLogLines() { sourceFiles.each { checkFile(it) } diff --git a/gradle/validation/validate-source-patterns.gradle b/gradle/validation/validate-source-patterns.gradle index 03ab081eef1..5b027d8d6bb 100644 --- a/gradle/validation/validate-source-patterns.gradle +++ b/gradle/validation/validate-source-patterns.gradle @@ -30,10 +30,13 @@ buildscript { } configure(rootProject) { - task("validateSourcePatterns", type: ValidateSourcePatternsTask) { + task("validateSourcePatterns", type: ValidateSourcePatternsTask) { task -> group = 'Verification' description = 'Validate Source Patterns' - + + // This task has no proper outputs. + setupDummyOutputs(task) + sourceFiles = project.fileTree(project.rootDir) { [ 'java', 'jflex', 'py', 'pl', 'g4', 'jj', 'html', 'js', @@ -68,11 +71,6 @@ configure(rootProject) { class ValidateSourcePatternsTask extends DefaultTask { - ValidateSourcePatternsTask() { - // this task has no outputs, so it's always uptodate (if inputs don't change). - outputs.upToDateWhen { true } - } - @InputFiles ConfigurableFileTree sourceFiles