From eb7ddc648e22ffe2dbb016638946316c7f2f2a43 Mon Sep 17 00:00:00 2001 From: Nisheeth Barthwal Date: Tue, 4 Oct 2022 18:40:12 +0200 Subject: [PATCH] use jacocoAggregation plugin (#58) * remove dependabot as it does not support Versions.kt --- .github/dependabot.yml | 6 ---- README.md | 13 ++++++- build.gradle.kts | 2 +- src/main/kotlin/CoverallsReporter.kt | 7 ++-- src/main/kotlin/SourceReportParser.kt | 7 ++-- src/test/kotlin/CoverallsReporterTest.kt | 1 + src/test/kotlin/SourceReportParserTest.kt | 42 +++++++++++++++++++++++ 7 files changed, 64 insertions(+), 14 deletions(-) delete mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml deleted file mode 100644 index dfa800a..0000000 --- a/.github/dependabot.yml +++ /dev/null @@ -1,6 +0,0 @@ -version: 2 -updates: - - package-ecosystem: "gradle" - directory: "/" - schedule: - interval: "monthly" diff --git a/README.md b/README.md index b6614ed..5b297c7 100644 --- a/README.md +++ b/README.md @@ -75,6 +75,17 @@ jacocoTestReport { ``` ## Multi-Project Support - Pure Kotlin/Java +It is recommended to use the [JaCoCo Aggregation plugin](https://docs.gradle.org/current/userguide/jacoco_report_aggregation_plugin.html) to consolidate +the test reports. Please refer to the [sample](https://docs.gradle.org/current/samples/sample_jvm_multi_project_with_code_coverage_standalone.html) on the website, on how to configure the plugin, +and specify the output file in the `coverallsJacoco` config. + +```kotlin +coverallsJacoco { + reportPath = "code-coverage-report/build/reports/jacoco/testCodeCoverageReport/testCodeCoverageReport.xml" +} +``` + +## (Not Recommended) Multi-Project Support - Pure Kotlin/Java To consolidate multiple JaCoCo coverage reports, the following code can be used to add a new task `codeCoverageReport` ```kotlin tasks.register("codeCoverageReport") { @@ -116,7 +127,7 @@ tasks.register("codeCoverageReport") { } ``` -## Multi-Project Support - Android +## (Not Recommended) Multi-Project Support - Android To consolidate multiple JaCoCo coverage reports on Android multi-project configurations, the following code can be used to add a new task `jacocoFullReport` diff --git a/build.gradle.kts b/build.gradle.kts index 6a07217..057dd99 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,7 +1,7 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile group = "com.github.nbaztec" -version = "1.2.14" +version = "1.2.15" buildscript { repositories { diff --git a/src/main/kotlin/CoverallsReporter.kt b/src/main/kotlin/CoverallsReporter.kt index 8596ba8..8305335 100644 --- a/src/main/kotlin/CoverallsReporter.kt +++ b/src/main/kotlin/CoverallsReporter.kt @@ -70,14 +70,16 @@ class CoverallsReporter(val envGetter: EnvGetter) { source_files = sourceFiles, ) - pluginExtension.coverallsRequest?.writeText(req.json(), Charsets.UTF_8) + val reqJson = req.json() + pluginExtension.coverallsRequest?.writeText(reqJson, Charsets.UTF_8) + logger.debug("request-json: $reqJson") if (pluginExtension.dryRun) { logger.info("skip sending to coveralls in dry run") return } - send(pluginExtension.apiEndpoint, req.json()) + send(pluginExtension.apiEndpoint, reqJson) } fun send(endpoint: String, reqJson: String) { @@ -102,7 +104,6 @@ class CoverallsReporter(val envGetter: EnvGetter) { } logger.info("sending payload to coveralls") - logger.debug(reqJson) val res = httpClient.execute(httpPost) if (res.statusLine.statusCode != 200) { throw Exception( diff --git a/src/main/kotlin/SourceReportParser.kt b/src/main/kotlin/SourceReportParser.kt index 3fdcba9..56da0a8 100644 --- a/src/main/kotlin/SourceReportParser.kt +++ b/src/main/kotlin/SourceReportParser.kt @@ -68,14 +68,15 @@ object SourceReportParser { fun parse(project: Project): List { val pluginExtension = project.extensions.getByType(CoverallsJacocoPluginExtension::class.java) + // if sources are not specified, then lookup android source sets, or if jacocoAggregate plugin is present, + // else fallback to main source set val sourceDirs = if (pluginExtension.reportSourceSets.count() == 0) { if (hasAndroidExtension) { project.extensions.findByType(BaseAppModuleExtension::class.java)!!.sourceSets .getByName("main").java.srcDirs.filterNotNull() - } else { - project.extensions.getByType(SourceSetContainer::class.java) + } else project.configurations.findByName("allCodeCoverageReportSourceDirectories")?.files + ?: project.extensions.getByType(SourceSetContainer::class.java) .getByName("main").allJava.srcDirs.filterNotNull() - } } else { pluginExtension.reportSourceSets.toList() } diff --git a/src/test/kotlin/CoverallsReporterTest.kt b/src/test/kotlin/CoverallsReporterTest.kt index 1875ad6..d04d970 100644 --- a/src/test/kotlin/CoverallsReporterTest.kt +++ b/src/test/kotlin/CoverallsReporterTest.kt @@ -241,6 +241,7 @@ Content-Transfer-Encoding: binary val project = mockk { every { rootDir } returns testRepo + every { configurations.findByName(any()) } returns null every { extensions.getByType(SourceSetContainer::class.java) } returns sourceSetContainer every { extensions.getByType(CoverallsJacocoPluginExtension::class.java) } returns pluginExtension } diff --git a/src/test/kotlin/SourceReportParserTest.kt b/src/test/kotlin/SourceReportParserTest.kt index 6b87c6c..5d98f26 100644 --- a/src/test/kotlin/SourceReportParserTest.kt +++ b/src/test/kotlin/SourceReportParserTest.kt @@ -19,6 +19,7 @@ internal class SourceReportParserTest { fun `SourceReportParser parses skips parsing if source directories empty`() { val project = mockk { every { rootDir } returns File("src/test/resources/testrepo") + every { configurations.findByName(any()) } returns null every { extensions.getByType(SourceSetContainer::class.java) } returns mockk { every { getByName("main").allJava.srcDirs } returns emptySet() } @@ -36,6 +37,7 @@ internal class SourceReportParserTest { fun `SourceReportParser parses simple jacoco report with java styled package`() { val project = mockk { every { rootDir } returns File("src/test/resources/testrepo") + every { configurations.findByName(any()) } returns null every { extensions.getByType(SourceSetContainer::class.java) } returns mockk { every { getByName("main").allJava.srcDirs } returns setOf(testJavaStyleSourceDir) } @@ -60,6 +62,7 @@ internal class SourceReportParserTest { fun `SourceReportParser parses simple android jacoco report with kotlin styled root package`() { val project = mockk { every { rootDir } returns File("src/test/resources/testrepo") + every { configurations.findByName(any()) } returns null every { extensions.getByType(SourceSetContainer::class.java) } returns mockk { every { getByName("main").allJava.srcDirs } returns setOf(testKotlinStyleSourceDir) } @@ -89,6 +92,7 @@ internal class SourceReportParserTest { fun `SourceReportParser parses simple jacoco report without android classes`() { val project = mockk { every { rootDir } returns File("src/test/resources/testrepo") + every { configurations.findByName(any()) } returns null every { extensions.getByType(SourceSetContainer::class.java) } returns mockk { every { getByName("main").allJava.srcDirs } returns setOf(testKotlinStyleSourceDir) } @@ -118,6 +122,7 @@ internal class SourceReportParserTest { fun `SourceReportParser parses simple jacoco report with kotlin styled root package`() { val project = mockk { every { rootDir } returns File("src/test/resources/testrepo") + every { configurations.findByName(any()) } returns null every { extensions.getByType(SourceSetContainer::class.java) } returns mockk { every { getByName("main").allJava.srcDirs } returns setOf(testKotlinStyleSourceDir) } @@ -147,6 +152,7 @@ internal class SourceReportParserTest { fun `SourceReportParser uses report source sets and parses jacoco report`() { val project = mockk { every { rootDir } returns File("src/test/resources/testrepo") + every { configurations.findByName(any()) } returns null every { extensions.getByType(CoverallsJacocoPluginExtension::class.java) } returns mockk { every { reportPath } returns testReport.path every { reportSourceSets } returns listOf( @@ -177,10 +183,46 @@ internal class SourceReportParserTest { assertEquals(expected, actual) } + @Test + fun `SourceReportParser uses jacocoAggregation provided source sets and parses jacoco report`() { + val project = mockk { + every { rootDir } returns File("src/test/resources/testrepo") + every { configurations.findByName("allCodeCoverageReportSourceDirectories") } returns mockk { + every { files } returns setOf( testKotlinStyleSourceDir, + testKotlinStyleSourceDirAdditional) + } + every { extensions.getByType(CoverallsJacocoPluginExtension::class.java) } returns mockk { + every { reportPath } returns testReport.path + every { reportSourceSets } returns emptySet() + } + } + + val actual = SourceReportParser.parse(project) + val expected = listOf( + SourceReport( + "src/main/kotlin/Main.kt", + "36083cd4c2ac736f9210fd3ed23504b5", + listOf(null, null, null, null, 1, 1, 1, 1, null, 1, 1, 0, 0, 1, 1, null, 1, 1, 1) + ), + SourceReport( + "src/main/kotlin/internal/Util.kt", + "805ee340f4d661be591b4eb42f6164d2", + listOf(null, null, null, null, 1, 1, 1, null, null) + ), + SourceReport( + "src/anotherMain/kotlin/Lib.kt", + "8b5c1c773cf81996efc19a08f0ac3648", + listOf(null, null, null, null, 1, 1, 1, null, null, null, null, null, null) + ) + ) + assertEquals(expected, actual) + } + @Test fun `SourceReportParser ignores lines in report that are missing in source`() { val project = mockk { every { rootDir } returns File("src/test/resources/testrepo") + every { configurations.findByName(any()) } returns null every { extensions.getByType(CoverallsJacocoPluginExtension::class.java) } returns mockk { every { reportPath } returns testReportMissingLines.path every { reportSourceSets } returns listOf(