Skip to content

Commit

Permalink
Fix subproject setup for sonar plugin (#54)
Browse files Browse the repository at this point in the history
  • Loading branch information
philipp94831 authored Jan 10, 2025
1 parent 34c4926 commit 841954a
Show file tree
Hide file tree
Showing 4 changed files with 134 additions and 10 deletions.
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ plugins {
id("com.bakdata.release") version "1.4.0"
// eat your own dog food - apply the plugins to this plugin project
id("com.bakdata.sonar") version "1.4.0"
id("com.bakdata.sonatype") version "1.4.0"
id("com.bakdata.sonatype") version "1.4.1"
id("org.gradle.kotlin.kotlin-dsl") version "4.1.2" apply false
id("com.gradle.plugin-publish") version "1.2.1" apply false
}
Expand Down
15 changes: 8 additions & 7 deletions sonar/src/main/kotlin/com/bakdata/gradle/SonarPlugin.kt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* The MIT License
*
* Copyright (c) 2024 bakdata GmbH
* Copyright (c) 2025 bakdata GmbH
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
Expand Down Expand Up @@ -69,22 +69,23 @@ class SonarPlugin : Plugin<Project> {
}

tasks.withType<JacocoReport> {
reports.xml.getRequired().set(true)
reports.xml.required.set(true)
}

rootProject.tasks.named("sonarqube") { dependsOn(tasks.withType<JacocoReport>(), tasks.withType<Test>()) }
}
}

if (!subprojects.isEmpty()) {
if (subprojects.isNotEmpty()) {
tasks.register<JacocoReport>("jacocoRootReport") {
subprojects {
executionData(tasks.withType<JacocoReport>().map { it.executionData })

components.matching { it.name == "java" }.configureEach {
sourceDirectories.from(files(project.the<SourceSetContainer>()["main"].allSource.srcDirs))
classDirectories.from(files(project.the<SourceSetContainer>()["main"].output))
}
}
sourceDirectories.from(files(subprojects.map {
it.the<SourceSetContainer>()["main"].allSource.srcDirs
}))
classDirectories.from(files(subprojects.map { it.the<SourceSetContainer>()["main"].output }))
reports {
html.required.set(true)
xml.required.set(true)
Expand Down
69 changes: 68 additions & 1 deletion sonar/src/test/kotlin/com/bakdata/gradle/SonarPluginIT.kt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* The MIT License
*
* Copyright (c) 2019 bakdata GmbH
* Copyright (c) 2025 bakdata GmbH
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
Expand Down Expand Up @@ -129,4 +129,71 @@ internal class SonarPluginIT {
.haveExactly(1, taskWithPathAndOutcome(":sonarqube", TaskOutcome.SUCCESS))
}
}

@Test
fun testMultiModuleProjectWithRootJavaProject(@TempDir testProjectDir: Path) {
Files.writeString(
testProjectDir.resolve("build.gradle.kts"), """
plugins {
id("com.bakdata.sonar")
}
allprojects {
apply(plugin = "java")
repositories {
mavenCentral()
}
dependencies {
"testRuntimeOnly"("org.junit.jupiter:junit-jupiter-engine:5.3.0")
"testImplementation"("org.junit.jupiter:junit-jupiter-api:5.3.0")
}
tasks.withType<Test> {
useJUnitPlatform()
}
}
""".trimIndent()
)

val children = listOf("child")
Files.writeString(
testProjectDir.resolve("settings.gradle"),
"""include ${children.joinToString(",") { "'$it'" }}"""
)
children.forEach { child ->
Files.createDirectories(testProjectDir.resolve("$child/src/test/java/"))
Files.copy(
SonarPluginIT::class.java.getResourceAsStream("/DemoTest.java"),
testProjectDir.resolve("$child/src/test/java/DemoTest.java")
)
}
Files.createDirectories(testProjectDir.resolve("src/test/java/"))
Files.copy(
SonarPluginIT::class.java.getResourceAsStream("/DemoTest.java"),
testProjectDir.resolve("src/test/java/DemoTest.java")
)

val result = GradleRunner.create()
.withProjectDir(testProjectDir.toFile())
.withArguments(
"sonarqube",
"-Dsonar.scanner.dumpToFile=${testProjectDir.resolve("dump")}",
"--stacktrace",
"--info"
)
.withProjectPluginClassPath()
.build()

SoftAssertions.assertSoftly { softly ->
children.forEach { child ->
softly.assertThat(result.tasks)
.haveExactly(1, taskWithPathAndOutcome(":$child:compileTestJava", TaskOutcome.SUCCESS))
.haveExactly(1, taskWithPathAndOutcome(":$child:test", TaskOutcome.SUCCESS))
.haveExactly(1, taskWithPathAndOutcome(":$child:jacocoTestReport", TaskOutcome.SUCCESS))
}
softly.assertThat(result.tasks)
.haveExactly(1, taskWithPathAndOutcome(":compileTestJava", TaskOutcome.SUCCESS))
.haveExactly(1, taskWithPathAndOutcome(":test", TaskOutcome.SUCCESS))
.haveExactly(1, taskWithPathAndOutcome(":jacocoTestReport", TaskOutcome.SUCCESS))
.haveExactly(1, taskWithPathAndOutcome(":sonarqube", TaskOutcome.SUCCESS))
}
}
}
58 changes: 57 additions & 1 deletion sonar/src/test/kotlin/com/bakdata/gradle/SonarPluginTest.kt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* The MIT License
*
* Copyright (c) 2024 bakdata GmbH
* Copyright (c) 2025 bakdata GmbH
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
Expand Down Expand Up @@ -134,6 +134,62 @@ internal class SonarPluginTest {
}
}

@Test
fun testMultiModuleProjectWithJavaRootProjectWithJavaLast() {
val parent = ProjectBuilder.builder().withName("parent").build()
val child = ProjectBuilder.builder().withName("child").withParent(parent).build()
val children = listOf(child)

Assertions.assertThatCode {
parent.pluginManager.apply("com.bakdata.sonar")
parent.pluginManager.apply("java")
children.forEach { it.pluginManager.apply("java") }
parent.evaluate()
}.doesNotThrowAnyException()

SoftAssertions.assertSoftly { softly ->
children.forEach { child ->
softly.assertThat(child.tasks)
.haveExactly(1, taskWithName("jacocoTestReport"))
.haveExactly(0, taskWithName("sonarqube"))
}
}

SoftAssertions.assertSoftly { softly ->
softly.assertThat(parent.collectTasks())
.haveExactly(1, taskWithName("jacocoTestReport"))
.haveExactly(1, taskWithName("sonarqube"))
}
}

@Test
fun testMultiModuleProjectWithJavaRootProjectWithJavaFirst() {
val parent = ProjectBuilder.builder().withName("parent").build()
val child = ProjectBuilder.builder().withName("child").withParent(parent).build()
val children = listOf(child)

Assertions.assertThatCode {
parent.pluginManager.apply("java")
children.forEach { it.pluginManager.apply("java") }
parent.pluginManager.apply("com.bakdata.sonar")
parent.evaluate()
}.doesNotThrowAnyException()

SoftAssertions.assertSoftly { softly ->
children.forEach { child ->
softly.assertThat(child.tasks)
.haveExactly(1, taskWithName("jacocoTestReport"))
.haveExactly(0, taskWithName("sonarqube"))
}
}

SoftAssertions.assertSoftly { softly ->
softly.assertThat(parent.collectTasks())
.haveExactly(1, taskWithName("jacocoTestReport"))
.haveExactly(1, taskWithName("sonarqube"))
}
}

@Test
fun testWrongApplicationInMultiModuleProject() {
val parent = ProjectBuilder.builder().withName("parent").build()
Expand Down

0 comments on commit 841954a

Please sign in to comment.