Skip to content

Commit

Permalink
SONARGRADL-124 Remove implicit dependency of the sonar task on the co…
Browse files Browse the repository at this point in the history
…mpile tasks
  • Loading branch information
leveretka committed Mar 21, 2024
1 parent 7d7feec commit 1367c64
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 159 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,11 @@

import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Collections;
import java.util.Properties;
import java.util.stream.Stream;

import org.junit.Test;
import org.junit.BeforeClass;

Expand All @@ -43,7 +46,7 @@ public static void beforeAll() {

@Test
public void testUsingDefaultVariant() throws Exception {
Properties props = runGradlewSonarSimulationModeWithEnv("/android-gradle-default-variant", emptyMap(), "test");
Properties props = runGradlewSonarSimulationModeWithEnv("/android-gradle-default-variant", emptyMap(), "test", "compileDemoMinApi23DebugAndroidTestJavaWithJavac");

Path baseDir = Paths.get(props.getProperty("sonar.projectBaseDir"));

Expand All @@ -57,6 +60,7 @@ public void testUsingDefaultVariant() throws Exception {

assertThat(Paths.get(props.getProperty("sonar.java.binaries")))
.isEqualTo(baseDir.resolve("build/intermediates/javac/demoMinApi23Debug/classes"));

// For Android Gradle Plugin version 8 and greater, the debugAndroidTest artifacts are no longer present in the same folder
if (getAndroidGradleVersion().isGreaterThanOrEqualTo("8.0.0")) {
assertThat(stream(props.getProperty("sonar.java.test.binaries").split(",")).map(Paths::get))
Expand All @@ -83,7 +87,7 @@ public void testUsingDefaultVariant() throws Exception {

@Test
public void testAndroidDynamicFeature() throws Exception {
Properties props = runGradlewSonarSimulationMode("/android-gradle-dynamic-feature");
Properties props = runGradlewSonarSimulationModeWithEnv("/android-gradle-dynamic-feature", emptyMap(), "test", "compileDebugAndroidTestJavaWithJavac");

Path baseDir = Paths.get(props.getProperty("sonar.projectBaseDir"));

Expand All @@ -105,7 +109,8 @@ public void testAndroidDynamicFeature() throws Exception {
assertThat(stream(props.getProperty(":app.sonar.java.test.binaries").split(",")).map(Paths::get))
.containsOnly(
baseDir.resolve("app/build/intermediates/javac/debugUnitTest/classes"),
baseDir.resolve("app/build/intermediates/javac/debugAndroidTest/classes"));
baseDir.resolve("app/build/intermediates/javac/debugAndroidTest/classes")
);

assertThat(props.getProperty(":app.sonar.java.libraries")).contains("android.jar");
assertThat(props.getProperty(":app.sonar.java.libraries")).doesNotContain("junit-4.12.jar");
Expand All @@ -124,7 +129,8 @@ public void testAndroidDynamicFeature() throws Exception {
assertThat(stream(props.getProperty(":mydynamicfeature.sonar.java.test.binaries").split(",")).map(Paths::get))
.containsOnly(
baseDir.resolve("mydynamicfeature/build/intermediates/javac/debugUnitTest/classes"),
baseDir.resolve("mydynamicfeature/build/intermediates/javac/debugAndroidTest/classes"));
baseDir.resolve("mydynamicfeature/build/intermediates/javac/debugAndroidTest/classes")
);

assertThat(props.getProperty(":mydynamicfeature.sonar.java.libraries")).contains("android.jar");
assertThat(props.getProperty(":mydynamicfeature.sonar.java.libraries")).doesNotContain("junit-4.12.jar");
Expand Down Expand Up @@ -159,7 +165,7 @@ public void testSpecifyVariant() throws Exception {

@Test
public void testMultiModule() throws Exception {
Properties props = runGradlewSonarSimulationMode("/multi-module-android-studio");
Properties props = runGradlewSonarSimulationModeWithEnv("/multi-module-android-studio", emptyMap(), "test", "compileDebugAndroidTestJavaWithJavac");

Path baseDir = Paths.get(props.getProperty("sonar.projectBaseDir"));

Expand All @@ -180,7 +186,8 @@ public void testMultiModule() throws Exception {
assertThat(stream(props.getProperty(":app.sonar.java.test.binaries").split(",")).map(Paths::get))
.containsOnly(
baseDir.resolve("app/build/intermediates/javac/debugUnitTest/classes"),
baseDir.resolve("app/build/intermediates/javac/debugAndroidTest/classes"));
baseDir.resolve("app/build/intermediates/javac/debugAndroidTest/classes")
);

assertThat(props.getProperty(":app.sonar.java.libraries")).contains("android.jar");
assertThat(props.getProperty(":app.sonar.java.libraries")).doesNotContain("hamcrest-core-1.3.jar");
Expand All @@ -195,7 +202,16 @@ public void testingBlueprintWithDynamicFeatureModule_default_flavor() throws Exc

// First flavor that is picked up seems to be the flavor1

Properties props = runGradlewSonarSimulationMode("/AndroidTestingBlueprintWithDynamicFeatureModule");
Properties props = runGradlewSonarSimulationModeWithEnv(
"/AndroidTestingBlueprintWithDynamicFeatureModule",
emptyMap(),
"assembleDebug",
"compileFlavor1DebugUnitTestJavaWithJavac",
"compileFlavor1DebugAndroidTestJavaWithJavac",
"compileDebugAndroidTestJavaWithJavac",
"compileDebugUnitTestJavaWithJavac",
"compileTestJava"
);

Path baseDir = Paths.get(props.getProperty("sonar.projectBaseDir"));

Expand Down Expand Up @@ -284,26 +300,30 @@ public void testingBlueprintWithDynamicFeatureModule_default_flavor() throws Exc
}

@Test
public void testingBlueprintWithDynamicFeatureModule_task_dependencies() throws Exception {
public void testSonarTaskHasNoDependencies() throws Exception {
// First flavor that is picked up seems to be the flavor1

RunResult result = runGradlewWithEnvQuietly("/AndroidTestingBlueprintWithDynamicFeatureModule", null, emptyMap(), "sonar", "--dry-run", "--max-workers=1");

assertThat(stream(result.getLog().split("\\r?\\n")).sorted()).containsSubsequence(
":app:compileFlavor1DebugAndroidTestJavaWithJavac SKIPPED",
":app:compileFlavor1DebugUnitTestJavaWithJavac SKIPPED",
":module-android-library:compileDebugAndroidTestJavaWithJavac SKIPPED",
":module-android-library:compileDebugUnitTestJavaWithJavac SKIPPED",
":module-flavor1-androidTest-only:compileDebugJavaWithJavac SKIPPED",
":module-plain-java:compileTestJava SKIPPED",
":module_android_feature:compileFlavor1DebugJavaWithJavac SKIPPED",
":sonar SKIPPED");
Stream<String> logs = stream(result.getLog().split("\\r?\\n")).sorted();

assertThat(logs)
.contains(":sonar SKIPPED")
.doesNotContainAnyElementsOf(Arrays.asList(
":app:compileFlavor1DebugAndroidTestJavaWithJavac SKIPPED",
":app:compileFlavor1DebugUnitTestJavaWithJavac SKIPPED",
":module-android-library:compileDebugAndroidTestJavaWithJavac SKIPPED",
":module-android-library:compileDebugUnitTestJavaWithJavac SKIPPED",
":module-flavor1-androidTest-only:compileDebugJavaWithJavac SKIPPED",
":module-plain-java:compileTestJava SKIPPED",
":module_android_feature:compileFlavor1DebugJavaWithJavac SKIPPED")
);
}

// SONARGRADL-22
@Test
public void noDebugVariant() throws Exception {
Properties props = runGradlewSonarSimulationMode("/android-gradle-no-debug");
Properties props = runGradlewSonarSimulationModeWithEnv("/android-gradle-no-debug", emptyMap(), "compileReleaseUnitTestJavaWithJavac", "compileReleaseJavaWithJavac");

Path baseDir = Paths.get(props.getProperty("sonar.projectBaseDir"));

Expand Down Expand Up @@ -338,6 +358,4 @@ public void testAndroidLintReport() throws Exception {
assertThat(Paths.get(props.getProperty(":app4.sonar.androidLint.reportPaths"))).isEqualTo(baseDir.resolve("app4/build/reports/lint-results-fullRelease.xml"));

}


}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
Expand All @@ -37,7 +38,7 @@ public class GradleTest extends AbstractGradleIT {

@Test
public void testSimpleJavaProject() throws Exception {
Properties props = runGradlewSonarSimulationMode("/java-gradle-simple");
Properties props = runGradlewSonarSimulationModeWithEnv("/java-gradle-simple", Collections.emptyMap(), "compileJava", "compileTestJava");

Path baseDir = Paths.get(props.getProperty("sonar.projectBaseDir"));

Expand Down Expand Up @@ -108,7 +109,7 @@ public void testCompileOnly() throws Exception {
@Test
public void testCustomConfiguration() throws Exception {

Properties props = runGradlewSonarSimulationMode("/java-gradle-custom-config");
Properties props = runGradlewSonarSimulationModeWithEnv("/java-gradle-custom-config", emptyMap(), "compileJava", "compileTestJava");

Path baseDir = Paths.get(props.getProperty("sonar.projectBaseDir"));

Expand All @@ -124,7 +125,7 @@ public void testCustomConfiguration() throws Exception {

@Test
public void mixJavaGroovyProject() throws Exception {
Properties props = runGradlewSonarSimulationModeWithEnv("/java-groovy-tests-gradle", emptyMap(), "test");
Properties props = runGradlewSonarSimulationModeWithEnv("/java-groovy-tests-gradle", emptyMap(), "build");

Path baseDir = Paths.get(props.getProperty("sonar.projectBaseDir"));

Expand Down Expand Up @@ -166,7 +167,7 @@ public void module_inclusion_duplicate_key() throws Exception {
// SONARGRADL-5
@Test
public void testMultimoduleProjectWithSourceInRoot() throws Exception {
Properties props = runGradlewSonarSimulationMode("/multi-module-source-in-root");
Properties props = runGradlewSonarSimulationModeWithEnv("/multi-module-source-in-root", emptyMap(), "compileJava", "compileTestJava");

Path baseDir = Paths.get(props.getProperty("sonar.projectBaseDir"));

Expand Down Expand Up @@ -236,7 +237,7 @@ public void testJaCoCoProperties() throws Exception {
// Use report.required
project = "/java-gradle-jacoco-after-7";
}
Properties props = runGradlewSonarSimulationModeWithEnv(project, emptyMap(), "test", "jacocoTestReport");
Properties props = runGradlewSonarSimulationModeWithEnv(project, emptyMap(), "processResources", "processTestResources", "test", "jacocoTestReport");
Path baseDir = Paths.get(props.getProperty("sonar.projectBaseDir"));
assertThat(props.getProperty("sonar.jacoco.reportPaths")).contains(baseDir.resolve("build/jacoco/test.exec").toString());
assertThat(props.getProperty("sonar.coverage.jacoco.xmlReportPaths")).contains(baseDir.resolve("build/reports/jacoco/test/jacocoTestReport.xml").toString());
Expand All @@ -256,7 +257,7 @@ public void testProjectWithConfigurationCacheDoubleExecutionsShouldWork() throws
@Test
public void testKotlinMultiplatformProject() throws Exception {
Assume.assumeTrue("Tests only applies to version 6.8.3 or greater", getGradleVersion().isGreaterThanOrEqualTo("6.8.3"));
Properties props = runGradlewSonarSimulationMode("/kotlin-multiplatform");
Properties props = runGradlewSonarSimulationModeWithEnv("/kotlin-multiplatform", emptyMap(), "compileCommonMainKotlinMetadata", "compileKotlinJvm", "compileKotlinMetadata", "compileTestKotlinJvm");

Path baseDir = Paths.get(props.getProperty("sonar.projectBaseDir"));

Expand All @@ -280,7 +281,7 @@ public void testKotlinMultiplatformProject() throws Exception {
@Test
public void testKotlinMultiplatformWithSubmoduleProject() throws Exception {
Assume.assumeTrue("Tests only applies to version 6.8.3 or greater", getGradleVersion().isGreaterThanOrEqualTo("6.8.3"));
Properties props = runGradlewSonarSimulationMode("/kotlin-multiplatform-with-submodule");
Properties props = runGradlewSonarSimulationModeWithEnv("/kotlin-multiplatform-with-submodule", emptyMap(), "compileCommonMainKotlinMetadata", "compileKotlinJvm", "compileKotlinMetadata", "compileTestKotlinJvm");

Path baseDir = Paths.get(props.getProperty("sonar.projectBaseDir"));

Expand All @@ -303,7 +304,7 @@ public void testKotlinMultiplatformWithSubmoduleProject() throws Exception {

@Test
public void testKotlinJvmProject() throws Exception {
Properties props = runGradlewSonarSimulationMode("/kotlin-jvm");
Properties props = runGradlewSonarSimulationModeWithEnv("/kotlin-jvm", emptyMap(), "compileKotlin", "compileTestKotlin");

Path baseDir = Paths.get(props.getProperty("sonar.projectBaseDir"));

Expand All @@ -318,7 +319,7 @@ public void testKotlinJvmProject() throws Exception {

@Test
public void testKotlinJvmWithSubmoduleProject() throws Exception {
Properties props = runGradlewSonarSimulationMode("/kotlin-jvm-submodule");
Properties props = runGradlewSonarSimulationModeWithEnv("/kotlin-jvm-submodule", emptyMap(), "compileKotlin", "compileTestKotlin");

Path baseDir = Paths.get(props.getProperty("sonar.projectBaseDir"));

Expand Down
18 changes: 2 additions & 16 deletions src/main/java/org/sonarqube/gradle/SonarQubePlugin.java
Original file line number Diff line number Diff line change
Expand Up @@ -110,22 +110,8 @@ private static void configureTask(SonarTask sonarTask, Project project, Map<Stri
sonarTask.setProperties(conventionProvider);
}

boolean skipImplicitCompilation = Boolean.getBoolean("sonar.gradle.skipCompile");

if (skipImplicitCompilation) {
sonarTask.mustRunAfter(getJavaCompileTasks(project));
sonarTask.mustRunAfter(getAndroidCompileTasks(project));
} else {
LOGGER.warn(
"The '{}' task depends on compile tasks. This behavior is now deprecated and will be removed in version 5.x. " +
"To avoid implicit compilation, set property 'sonar.gradle.skipCompile' to 'true' " +
"and make sure your project is compiled, before analysis has started.",
sonarTask.getName()
);
sonarTask.dependsOn(getJavaCompileTasks(project));
sonarTask.dependsOn(getAndroidCompileTasks(project));
}

sonarTask.mustRunAfter(getJavaCompileTasks(project));
sonarTask.mustRunAfter(getAndroidCompileTasks(project));
sonarTask.mustRunAfter(getJavaTestTasks(project));
sonarTask.mustRunAfter(getJacocoTasks(project));
setNotCompatibleWithConfigurationCache(sonarTask);
Expand Down
67 changes: 0 additions & 67 deletions src/test/groovy/org/sonarqube/gradle/FunctionalTests.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -325,71 +325,4 @@ class FunctionalTests extends Specification {
props.load(outFile.newDataInputStream())
props."sonar.java.enablePreview" == "true"
}

def "warn if using implicit compilation"() {
given:
settingsFile << "rootProject.name = 'java-task-toolchains'"
buildFile << """
plugins {
id 'org.sonarqube'
}
"""

when:
def result = GradleRunner.create()
.withProjectDir(testProjectDir.toFile())
.forwardOutput()
.withArguments('sonar', '-Dsonar.scanner.dumpToFile=' + outFile.toAbsolutePath())
.withPluginClasspath()
.build()
then:
result.task(":sonar").outcome == SUCCESS

result.output.contains("The 'sonar' task depends on compile tasks. This behavior is now deprecated and will be removed in version 5.x. To avoid implicit compilation, set property 'sonar.gradle.skipCompile' to 'true' and make sure your project is compiled, before analysis has started.")
}

def "do not warn if implicit compilation is disabled"() {
given:
settingsFile << "rootProject.name = 'java-task-toolchains'"
buildFile << """
plugins {
id 'org.sonarqube'
}
"""

when:
def result = GradleRunner.create()
.withProjectDir(testProjectDir.toFile())
.forwardOutput()
.withArguments('sonar', '-Dsonar.gradle.skipCompile=true', '-Dsonar.scanner.dumpToFile=' + outFile.toAbsolutePath())
.withPluginClasspath()
.build()

then:
result.task(":sonar").outcome == SUCCESS
!result.output.contains("The 'sonar' task depends on compile tasks. This behavior is now deprecated and will be removed in version 5.x. To avoid implicit compilation, set property 'sonar.gradle.skipCompile' to 'true' and make sure your project is compiled, before analysis has started.")
}

def "warn if `sonar.gradle.skipCompile` is set to false"() {
given:
settingsFile << "rootProject.name = 'java-task-toolchains'"
buildFile << """
plugins {
id 'org.sonarqube'
}
"""

when:
def result = GradleRunner.create()
.withProjectDir(testProjectDir.toFile())
.forwardOutput()
.withArguments('sonar', '-Dsonar.gradle.skipCompile=false', '-Dsonar.scanner.dumpToFile=' + outFile.toAbsolutePath())
.withPluginClasspath()
.build()

then:
result.task(":sonar").outcome == SUCCESS

result.output.contains("The 'sonar' task depends on compile tasks. This behavior is now deprecated and will be removed in version 5.x. To avoid implicit compilation, set property 'sonar.gradle.skipCompile' to 'true' and make sure your project is compiled, before analysis has started.")
}
}
Loading

0 comments on commit 1367c64

Please sign in to comment.