Skip to content

Commit

Permalink
Added include/exclude DSL
Browse files Browse the repository at this point in the history
  • Loading branch information
gmazzo committed Apr 26, 2023
1 parent 1c278bb commit 956c99a
Show file tree
Hide file tree
Showing 7 changed files with 126 additions and 6 deletions.
26 changes: 26 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,32 @@ now promoted to dedicated Gradle plugins:
[io.github.gmazzo.test.aggregation.coverage](https://plugins.gradle.org/plugin/io.github.gmazzo.test.aggregation.coverage) and
[io.github.gmazzo.test.aggregation.results](https://plugins.gradle.org/plugin/io.github.gmazzo.test.aggregation.results)

## Filtering content
The plugins will automatically aggregate `android` modules and `java` modules that also apply `jacoco` plugin on the
`jacocoAggregation` and the `testReportAggregation` configurations.

You control which projects are effectively included by using the DSL:
```kotlin
testAggregation {
modules {
include(project(":app"))
exclude(projects.lib)
}
}
```

## Filtering coverage classes
You can use the DSL to include/exclude `.class` **files** from the aggregated JaCoCo coverage report:
```kotlin
testAggregation {
coverage {
include("com/**/Login*") // will only include classes starting with `com.` containing `Login` on its name
}
}
```
It's important to realize the filtering is done at `.class` file level (compiled classes).
You should not use classes names here but GLOB patterns.

# Demo project for aggregating Jacoco Android & JVM coverage reports
This is an example project that illustrates how can the
[JaCoCo Report Aggregation Plugin](https://docs.gradle.org/current/userguide/jacoco_report_aggregation_plugin.html) and
Expand Down
10 changes: 10 additions & 0 deletions demo-project/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,13 @@ plugins {
id("io.github.gmazzo.test.aggregation.results")
id("io.github.gmazzo.test.aggregation.coverage")
}

testAggregation {
modules {
include(projects.demoProject.app, projects.demoProject.domain, projects.demoProject.login)
exclude(rootProject)
}
coverage {
exclude("**/ContentMainBinding*")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,29 @@ package io.github.gmazzo.android.test.aggregation
import com.android.build.api.variant.AndroidComponentsExtension
import com.android.build.gradle.TestedExtension
import org.gradle.api.Project
import org.gradle.api.artifacts.Configuration
import org.gradle.kotlin.dsl.create
import org.gradle.kotlin.dsl.findByType
import org.gradle.kotlin.dsl.getByName
import org.gradle.kotlin.dsl.testAggregation
import org.gradle.kotlin.dsl.the

internal val Project.android
get() = the<TestedExtension>()

internal val Project.androidComponents
get() = extensions.getByName<AndroidComponentsExtension<*, *, *>>("androidComponents")

internal val Project.testAggregationExtension: TestAggregationExtension
get() = extensions.findByType()
?: extensions.create<TestAggregationExtension>("testAggregation").apply {
modules.includes.finalizeValueOnRead()
modules.excludes.finalizeValueOnRead()
}

internal fun TestAggregationExtension.aggregateProject(project: Project, config: Configuration) =
modules.includes(project) &&
config.dependencies.add(project.dependencies.testAggregation(project))

private fun TestAggregationExtension.Modules.includes(project: Project) =
(includes.get().isEmpty() || project in includes.get()) && project !in excludes.get()
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package io.github.gmazzo.android.test.aggregation

import org.gradle.api.Action
import org.gradle.api.Project
import org.gradle.api.artifacts.ProjectDependency
import org.gradle.api.provider.SetProperty
import org.gradle.api.tasks.Nested
import org.gradle.kotlin.dsl.invoke

abstract class TestAggregationExtension {

@get:Nested
abstract val modules: Modules

fun modules(configure: Action<Modules>) = configure(modules)

/**
* Controls which module should be automatically aggregated
*/
abstract class Modules {

abstract val includes: SetProperty<Project>

abstract val excludes: SetProperty<Project>

fun include(vararg includes: Project) = apply {
this.includes.addAll(*includes)
}

fun include(includes: Iterable<Project>) = apply {
this.includes.addAll(includes)
}

fun include(vararg includes: ProjectDependency) =
include(includes.map { it.dependencyProject })

fun exclude(vararg excludes: Project) = apply {
this.excludes.addAll(*excludes)
}

fun exclude(excludes: Iterable<Project>) = apply {
this.excludes.addAll(excludes)
}

fun exclude(vararg excludes: ProjectDependency) =
exclude(excludes.map { it.dependencyProject })

}

}

Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@ package io.github.gmazzo.android.test.aggregation
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.attributes.TestSuiteType
import org.gradle.api.plugins.ExtensionAware
import org.gradle.api.reporting.ReportingExtension
import org.gradle.api.tasks.util.PatternFilterable
import org.gradle.api.tasks.util.PatternSet
import org.gradle.kotlin.dsl.apply
import org.gradle.kotlin.dsl.create
import org.gradle.kotlin.dsl.getValue
import org.gradle.kotlin.dsl.provideDelegate
import org.gradle.kotlin.dsl.testAggregation
import org.gradle.kotlin.dsl.the
import org.gradle.language.base.plugins.LifecycleBasePlugin
import org.gradle.testing.jacoco.plugins.JacocoCoverageReport
Expand All @@ -19,24 +21,34 @@ class TestCoverageAggregationPlugin : Plugin<Project> {
apply(plugin = "reporting-base")
apply(plugin = "jacoco-report-aggregation")

val extension = testAggregationExtension
val coverageExtension = (testAggregationExtension as ExtensionAware).extensions
.create(PatternFilterable::class, "coverage", PatternSet::class)

val jacocoReport =
the<ReportingExtension>().reports.create<JacocoCoverageReport>("jacocoTestReport") {
testType.set(TestSuiteType.UNIT_TEST)
reportTask.configure {
classDirectories.setFrom(
files(*classDirectories.from.toTypedArray()).asFileTree
.matching(coverageExtension)
)
}
}

val jacocoAggregation by configurations

allprojects {
plugins.withId("java") {
plugins.withId("jacoco") {
jacocoAggregation.dependencies.add(dependencies.testAggregation(project))
extension.aggregateProject(project, jacocoAggregation)
}
}

plugins.withId("com.android.base") {
apply<AndroidTestCoverageAggregationPlugin>()

jacocoAggregation.dependencies.add(dependencies.testAggregation(project))
extension.aggregateProject(project, jacocoAggregation)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import org.gradle.kotlin.dsl.apply
import org.gradle.kotlin.dsl.create
import org.gradle.kotlin.dsl.getValue
import org.gradle.kotlin.dsl.provideDelegate
import org.gradle.kotlin.dsl.testAggregation
import org.gradle.kotlin.dsl.the
import org.gradle.language.base.plugins.LifecycleBasePlugin

Expand All @@ -19,6 +18,8 @@ class TestResultsAggregationPlugin : Plugin<Project> {
apply(plugin = "reporting-base")
apply(plugin = "test-report-aggregation")

val extension = testAggregationExtension

val testResultsReport =
the<ReportingExtension>().reports.create<AggregateTestReport>("testAggregateTestReport") {
testType.set(TestSuiteType.UNIT_TEST)
Expand All @@ -29,13 +30,13 @@ class TestResultsAggregationPlugin : Plugin<Project> {
allprojects {

plugins.withId("jvm-test-suite") {
testReportAggregation.dependencies.add(dependencies.testAggregation(project))
extension.aggregateProject(project, testReportAggregation)
}

plugins.withId("com.android.base") {
apply<AndroidTestResultsAggregationPlugin>()

testReportAggregation.dependencies.add(dependencies.testAggregation(project))
extension.aggregateProject(project, testReportAggregation)
}
}

Expand Down
2 changes: 2 additions & 0 deletions settings.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS")

apply(from = "gradle/shared.settings.gradle.kts")

rootProject.name = "gradle-android-test-aggregation-plugin"
Expand Down

0 comments on commit 956c99a

Please sign in to comment.