Skip to content

Commit 72bc921

Browse files
committed
Finish adding Jacoco support
1 parent 5f73d09 commit 72bc921

File tree

5 files changed

+87
-0
lines changed

5 files changed

+87
-0
lines changed

unified-prototype/unified-plugin/gradle/libs.versions.toml

+5
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ ksp = "1.9.22-1.0.18"
77
android = "8.3.0"
88
hilt = "2.50"
99

10+
apache-commons = "3.3.1"
11+
1012
[libraries]
1113
# Kotlin dependencies
1214
kotlin-multiplatform = { module = "org.jetbrains.kotlin.multiplatform:org.jetbrains.kotlin.multiplatform.gradle.plugin", version.ref = "kotlin" }
@@ -19,3 +21,6 @@ android-kotlin-android = { module = "org.jetbrains.kotlin.android:org.jetbrains.
1921
hilt-android-plugin = { module = "com.google.dagger:hilt-android-gradle-plugin", version.ref = "hilt" }
2022
hilt-android = { module = "com.google.dagger:hilt-android", version.ref = "hilt"}
2123
hilt-compiler = { module = "com.google.dagger:hilt-android-compiler", version.ref = "hilt" }
24+
25+
# Other libraries
26+
apache-commons-lang = { module = "org.apache.commons:commons-lang3", version.ref = "apache-commons" }

unified-prototype/unified-plugin/plugin-android/build.gradle.kts

+2
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ dependencies {
1212

1313
implementation(libs.ksp.plugin)
1414
implementation(libs.hilt.android.plugin)
15+
16+
implementation(libs.apache.commons.lang)
1517
}
1618

1719
gradlePlugin {

unified-prototype/unified-plugin/plugin-android/src/main/java/org/gradle/api/experimental/android/library/AndroidLibrary.java

+6
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,12 @@ public interface AndroidLibrary {
5656
@Restricted
5757
Property<Boolean> getIncludeKotlinSerialization();
5858

59+
/**
60+
* Whether or not to set up Jacoco support.
61+
*/
62+
@Restricted
63+
Property<Boolean> getConfigureJacoco();
64+
5965
@Nested
6066
AndroidLibraryDependencies getDependencies();
6167

unified-prototype/unified-plugin/plugin-android/src/main/java/org/gradle/api/experimental/android/library/StandaloneAndroidLibraryPlugin.java

+1
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ public void apply(Project project) {
3333
dslModel.getCompileSdk().convention(DEFAULT_SDKS.TARGET_ANDROID_SDK);
3434
dslModel.getMinSdk().convention(DEFAULT_SDKS.MIN_ANDROID_SDK); // https://developer.android.com/build/multidex#mdex-gradle
3535
dslModel.getIncludeKotlinSerialization().convention(false);
36+
dslModel.getConfigureJacoco().convention(false);
3637

3738
// And Test Options
3839
dslModel.getTestOptions().getIncludeAndroidResources().convention(false);

unified-prototype/unified-plugin/plugin-android/src/main/java/org/gradle/api/experimental/android/nia/NiaSupport.java

+73
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,21 @@
66
import com.android.build.api.variant.BuiltArtifactsLoader;
77
import com.android.build.api.variant.HasAndroidTest;
88
import com.android.build.api.variant.LibraryAndroidComponentsExtension;
9+
import org.apache.commons.lang3.StringUtils;
910
import org.gradle.api.*;
1011
import org.gradle.api.experimental.android.DEFAULT_SDKS;
1112
import org.gradle.api.experimental.android.library.AndroidLibrary;
1213
import org.gradle.api.file.Directory;
1314
import org.gradle.api.provider.Provider;
15+
import org.gradle.api.tasks.testing.Test;
16+
import org.gradle.testing.jacoco.plugins.JacocoPluginExtension;
17+
import org.gradle.testing.jacoco.plugins.JacocoTaskExtension;
18+
import org.gradle.testing.jacoco.tasks.JacocoReport;
1419
import org.jetbrains.annotations.NotNull;
1520
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptions;
1621
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile;
1722

23+
import java.io.File;
1824
import java.lang.reflect.Method;
1925
import java.util.*;
2026
import java.util.function.BiConsumer;
@@ -43,6 +49,10 @@ public static void configureNia(Project project,
4349
configureGradleManagedDevices(androidLib);
4450
configureLint(androidLib);
4551
configurePrintApksTask(project, androidLibComponents);
52+
53+
if (dslModel.getConfigureJacoco().get()) {
54+
configureJacoco(project, androidLib);
55+
}
4656
}
4757

4858
private static void configureLint(LibraryExtension androidLib) {
@@ -211,4 +221,67 @@ private static void configurePrintApksTask(Project project, AndroidComponentsExt
211221
}
212222
});
213223
}
224+
225+
private static List<String> coverageExclusions() {
226+
return Arrays.asList(
227+
"**/R.class",
228+
"**/R$*.class",
229+
"**/BuildConfig.*",
230+
"**/Manifest*.*"
231+
);
232+
}
233+
234+
@SuppressWarnings("deprecation")
235+
private static void configureJacoco(Project project, LibraryExtension androidLib) {
236+
project.getPlugins().apply("jacoco");
237+
238+
androidLib.getBuildTypes().configureEach(buildType -> {
239+
buildType.setEnableAndroidTestCoverage(true);
240+
buildType.setEnableUnitTestCoverage(true);
241+
});
242+
243+
JacocoPluginExtension jacocoPluginExtension = project.getExtensions().getByType(JacocoPluginExtension.class);
244+
jacocoPluginExtension.setToolVersion("0.8.7");
245+
246+
LibraryAndroidComponentsExtension androidLibComponents = project.getExtensions().getByType(LibraryAndroidComponentsExtension.class);
247+
androidLibComponents.onVariants(androidLibComponents.selector().all(), variant -> {
248+
final String testTaskName = "test" + StringUtils.capitalize(variant.getName()) + "UnitTest";
249+
final File buildDir = project.getLayout().getBuildDirectory().get().getAsFile();
250+
project.getTasks().register("jacoco" + StringUtils.capitalize(testTaskName) + "Report", JacocoReport.class, task -> {
251+
task.dependsOn(testTaskName);
252+
253+
task.reports(report -> {
254+
report.getXml().getRequired().set(true);
255+
report.getXml().getRequired().set(true);
256+
});
257+
258+
task.getClassDirectories().setFrom(
259+
project.fileTree(project.getBuildDir() + "/tmp/kotlin-classes/" + variant.getName(), tree -> {
260+
tree.exclude(coverageExclusions());
261+
})
262+
);
263+
264+
task.getSourceDirectories().setFrom(
265+
project.files(project.getProjectDir() + "/src/main/java", project.getProjectDir() + "/src/main/kotlin"
266+
));
267+
268+
task.getExecutionData().setFrom(
269+
project.files(buildDir + "/jacoco/" + testTaskName + ".exec")
270+
);
271+
});
272+
});
273+
274+
project.getTasks().withType(Test.class, test -> {
275+
JacocoTaskExtension jacocoTaskExtension = test.getExtensions().getByType(JacocoTaskExtension.class);
276+
277+
// Required for JaCoCo + Robolectric
278+
// https://github.com/robolectric/robolectric/issues/2230
279+
// Consider removing if not we don't add Robolectric
280+
jacocoTaskExtension.setIncludeNoLocationClasses(true);
281+
282+
// Required for JDK 11 with the above
283+
// https://github.com/gradle/gradle/issues/5184#issuecomment-391982009
284+
jacocoTaskExtension.setExcludes(Collections.singletonList("jdk.internal.*"));
285+
});
286+
}
214287
}

0 commit comments

Comments
 (0)