Skip to content

Commit 9667d69

Browse files
SCANGRADLE-263 Declare build/sonar/ as an output directory (#395)
mark SonarTask as never up-to-date, because input are not all declared; thus gradle cannot compute correctly if the SonarTask is up to date or not
1 parent da16651 commit 9667d69

File tree

5 files changed

+69
-9
lines changed

5 files changed

+69
-9
lines changed

integrationTests/src/test/java/org/sonarqube/gradle/AbstractGradleIT.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -345,7 +345,7 @@ static void assertThatPluginDoesNotCreateGradleDeprecationWarnings(String text)
345345
}
346346

347347
static boolean isUnexpectedWarning(String line){
348-
if(line.contains("SonarResolverTask.java:108") || line.contains("SonarResolverTask.java:111")){
348+
if(line.contains("SonarResolverTask.java:152") || line.contains("SonarResolverTask.java:155")){
349349
// These warnings are expected until we properly support Gradle 9
350350
return false;
351351
}

src/main/java/org/sonarqube/gradle/SonarQubePlugin.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,13 +88,15 @@ public void apply(Project project) {
8888
task.setDescription("Analyzes " + project + " and its subprojects with Sonar. This task is deprecated. Use 'sonar' instead.");
8989
task.setGroup(JavaBasePlugin.VERIFICATION_GROUP);
9090
task.setResolverFiles(resolverFiles);
91+
task.setBuildSonar(project.getLayout().getBuildDirectory().dir("sonar"));
9192
configureTask(task, project, actionBroadcastMap);
9293
});
9394

9495
tasks.register(SonarExtension.SONAR_TASK_NAME, SonarTask.class, task -> {
9596
task.setDescription("Analyzes " + project + " and its subprojects with Sonar.");
9697
task.setGroup(JavaBasePlugin.VERIFICATION_GROUP);
9798
task.setResolverFiles(resolverFiles);
99+
task.setBuildSonar(project.getLayout().getBuildDirectory().dir("sonar"));
98100
configureTask(task, project, actionBroadcastMap);
99101
});
100102
}

src/main/java/org/sonarqube/gradle/SonarResolverTask.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,17 +26,16 @@
2626
import java.util.logging.Level;
2727
import java.util.logging.Logger;
2828
import java.util.stream.Collectors;
29+
import javax.inject.Inject;
2930
import org.gradle.api.DefaultTask;
3031
import org.gradle.api.file.FileCollection;
3132
import org.gradle.api.provider.Provider;
3233
import org.gradle.api.tasks.Input;
3334
import org.gradle.api.tasks.Internal;
3435
import org.gradle.api.tasks.OutputFile;
3536
import org.gradle.api.tasks.TaskAction;
36-
import org.gradle.api.tasks.UntrackedTask;
3737

3838

39-
@UntrackedTask(because = "task must always be recomputed, as we cannot declare input output properly")
4039
public abstract class SonarResolverTask extends DefaultTask {
4140
public static final String TASK_NAME = "sonarResolver";
4241
public static final String TASK_DESCRIPTION = "Resolves and serializes project information and classpath for SonarQube analysis.";
@@ -51,6 +50,14 @@ public abstract class SonarResolverTask extends DefaultTask {
5150
private File outputDirectory;
5251
private Provider<Boolean> skipProject;
5352

53+
@Inject
54+
public SonarResolverTask() {
55+
super();
56+
// some input are annotated with internal, thus grade cannot correctly compute if the task is up to date or not
57+
this.getOutputs().upToDateWhen(task -> false);
58+
}
59+
60+
5461
@Input
5562
public String getProjectName() {
5663
return projectName;

src/main/java/org/sonarqube/gradle/SonarTask.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131
import java.util.Map;
3232
import java.util.stream.Collectors;
3333
import javax.annotation.Nullable;
34+
import javax.inject.Inject;
35+
import org.gradle.api.file.Directory;
3436
import org.gradle.api.internal.ConventionTask;
3537
import org.gradle.api.logging.LogLevel;
3638
import org.gradle.api.logging.Logger;
@@ -39,6 +41,7 @@
3941
import org.gradle.api.tasks.Input;
4042
import org.gradle.api.tasks.InputFiles;
4143
import org.gradle.api.tasks.Internal;
44+
import org.gradle.api.tasks.OutputDirectory;
4245
import org.gradle.api.tasks.TaskAction;
4346
import org.gradle.util.GradleVersion;
4447
import org.jetbrains.annotations.VisibleForTesting;
@@ -63,6 +66,7 @@ public class SonarTask extends ConventionTask {
6366
private LogOutput logOutput = new DefaultLogOutput();
6467

6568
private Provider<Map<String, String>> properties;
69+
private Provider<Directory> buildSonar;
6670

6771
private static class DefaultLogOutput implements LogOutput {
6872
@Override
@@ -89,6 +93,13 @@ public void log(String formattedMessage, Level level) {
8993
}
9094
}
9195

96+
@Inject
97+
public SonarTask(){
98+
super();
99+
// some input are annotated with internal, thus grade cannot correctly compute if the task is up to date or not
100+
this.getOutputs().upToDateWhen(task -> false);
101+
}
102+
92103
/**
93104
* Logs output from the given {@link Level} at the {@link LogLevel#LIFECYCLE} log level, which is the default log
94105
* level for Gradle tasks. This can be used to specify the level of Sonar Scanner which it output during standard
@@ -213,6 +224,19 @@ public void setResolverFiles(List<File> resolverFiles) {
213224
this.resolverFiles = resolverFiles;
214225
}
215226

227+
/**
228+
* @return folder containing all files generated by the analysis
229+
* {@code null} values are not permitted.
230+
*/
231+
@OutputDirectory
232+
public Provider<Directory> getBuildSonar() {
233+
return this.buildSonar;
234+
}
235+
236+
public void setBuildSonar(Provider<Directory> buildSonar) {
237+
this.buildSonar = buildSonar;
238+
}
239+
216240
/**
217241
* Finish the configuration of `sonar.java.libraries` and `sonar.java.test.libraries` by resolving the class paths that
218242
* were attached to the task at configuration time.

src/test/groovy/org/sonarqube/gradle/FunctionalTests.groovy

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ class FunctionalTests extends Specification {
186186
id 'java'
187187
id 'org.sonarqube'
188188
}
189-
189+
190190
compileJava {
191191
options.compilerArgs.addAll(['--release', '10'])
192192
}
@@ -334,7 +334,7 @@ class FunctionalTests extends Specification {
334334
id 'java'
335335
id 'org.sonarqube'
336336
}
337-
337+
338338
compileJava {
339339
options.release = 8
340340
}
@@ -369,7 +369,7 @@ class FunctionalTests extends Specification {
369369
id 'java'
370370
id 'org.sonarqube'
371371
}
372-
372+
373373
compileJava {
374374
options.compilerArgs.addAll("--enable-preview")
375375
}
@@ -431,7 +431,7 @@ class FunctionalTests extends Specification {
431431
id 'java'
432432
id 'org.sonarqube'
433433
}
434-
434+
435435
compileJava {
436436
options.compilerArgs = [
437437
file("/")
@@ -545,7 +545,7 @@ class FunctionalTests extends Specification {
545545
id 'java'
546546
id 'org.sonarqube'
547547
}
548-
548+
549549
sonar {
550550
properties {
551551
$sonarSourcesProperty
@@ -800,7 +800,7 @@ class FunctionalTests extends Specification {
800800
if (!System.getProperty("os.name").toLowerCase().contains("windows")) {
801801
configureJacocoGradleTestkitPlugin(multiModuleProjectDir);
802802
}
803-
803+
804804

805805
when:
806806
def result = GradleRunner.create()
@@ -818,6 +818,33 @@ class FunctionalTests extends Specification {
818818

819819
}
820820

821+
def "check sonar and sonarResolver are not up to date"() {
822+
given:
823+
settingsFile << "rootProject.name = 'java-task-toolchains'"
824+
buildFile << """
825+
plugins {
826+
id 'org.sonarqube'
827+
id 'java'
828+
}
829+
"""
830+
831+
when:
832+
def command = GradleRunner.create()
833+
.withProjectDir(projectDir.toFile())
834+
.forwardOutput()
835+
.withArguments('sonar', '-Dsonar.scanner.internal.dumpToFile=' + outFile.toAbsolutePath(), '--info')
836+
.withPluginClasspath()
837+
838+
def run1 = command.build()
839+
def run2 = command.build()
840+
841+
then:
842+
assert run1.task(":sonar").getOutcome() == SUCCESS
843+
assert run2.task(":sonar").getOutcome() == SUCCESS
844+
assert run2.getOutput().contains("':sonarResolver' is not up-to-date")
845+
assert run2.getOutput().contains("':sonar' is not up-to-date")
846+
}
847+
821848
private Path projectDir(String project) {
822849
return Path.of(this.class.getResource("/projects/"+project).toURI());
823850
}

0 commit comments

Comments
 (0)