How to exclude explicitApi warnings for test classes in Kotlin? - android

I have Android library module with enabled explicitApi kotlin feature in gradle
android {
kotlinOptions {
freeCompilerArgs += '-Xexplicit-api=warning'
}
}
Everything is fine, but the problem is that warnings are also reported for test classes in packages src/test and src/androidTest.
How to exclude test classes from explicit-api control?
Thanks

As far as I know, you can't! I was thinking of opening a bug report just this week but never got to it. In the meantime, I suggest you add something like this to your build script, which will at least fix it for the Kotlin compiler (but you'll still see the IDE warnings):
tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile) {
if (!it.name.contains("Test")) {
kotlinOptions.freeCompilerArgs += "-Xexplicit-api=strict"
}
}
If you're using Gradle Kotlin DSL:
tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile> {
if ("UnitTest" !in name) {
kotlinOptions.freeCompilerArgs += "-Xexplicit-api=strict"
}
}
And don't set the compiler argument in android.kotlinOptions, only in that block, so that it is applied only to the non-test source sets.
EDIT: I just checked and the warnings bug was fixed in IntelliJ, so it should be fixed in Android Studio in a few months to a year.

Related

Enable compose metrics in android application

I want to enable compose metrics by this official docs.
In root gradle I added this:
subprojects {
tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile> {
kotlinOptions {
if (project.findProperty("composeCompilerReports") == "true") {
kotlinOptions.freeCompilerArgs = kotlinOptions.freeCompilerArgs + listOf(
"-P",
"plugin:androidx.compose.compiler.plugins.kotlin:reportsDestination=" +
project.buildDir.absolutePath + "/compose_reports"
)
kotlinOptions.freeCompilerArgs = kotlinOptions.freeCompilerArgs + listOf(
"-P",
"plugin:androidx.compose.compiler.plugins.kotlin:metricsDestination=" +
project.buildDir.absolutePath + "/compose_metrics"
)
}
}
}
}
and start the building by this command:
./gradlew assembleRelease -PcomposeCompilerReports=true --rerun-tasks
the building starts and even one report for one application module in its build folder created. But as I understand the further process stuck with an error:
> Task :core-common-feature-utils:kaptGenerateStubsReleaseKotlin FAILED
e: Multiple values are not allowed for plugin option androidx.compose.compiler.plugins.kotlin:metricsDestination
Plugin "androidx.compose.compiler.plugins.kotlin" usage:
liveLiterals <true|false> Enable Live Literals code generation
liveLiteralsEnabled <true|false>
Enable Live Literals code generation (with per-file enabled flags)
generateFunctionKeyMetaClasses <true|false>
Generate function key meta classes with annotations indicating the functions and their group keys. Generally used for tooling.
sourceInformation <true|false>
Include source information in generated code
metricsDestination <path> Save compose build metrics to this folder
reportsDestination <path> Save compose build reports to this folder
intrinsicRemember <true|false>
Include source information in generated code
suppressKotlinVersionCompatibilityCheck <true|false>
Suppress Kotlin version compatibility check
generateDecoys <true|false>
Generate decoy methods in IR transform
FAILURE: Build completed with 2 failures.
Also, I noticed that every time the process give the error with different module after one successful and can give my 2 same errors or three - and finally stackoverflow error.
please, help with idea how to overcome this
gradle plugin ver 7.4.1
P.S. As I understand from investigations, the modules without in their gradle
kotlin("kapt")
id("dagger.hilt.android.plugin")
creates the report. The using of kotlin("kapt") gives that error. But I do not know how to compile the project without it, because I am using hilt.
P.P.S. As I am trying more, I have managed to make reports after deleting hilt from build.gradle in modules. In this case the command runs till 100%. But application will not run of course. This is a little "inconvenient" to make report in such a way.
Please, if you have an idea..
Do not add it to root gradle file. You may add this code to module gradle file with compose:
android {
kotlinOptions {
if (project.findProperty("enableComposeReports") == "true") {
val outputDir = project.buildDir.path + "/compose-reports"
freeCompilerArgs = freeCompilerArgs + listOf(
"-P",
"plugin:androidx.compose.compiler.plugins.kotlin:reportsDestination=$outputDir",
"-P",
"plugin:androidx.compose.compiler.plugins.kotlin:metricsDestination=$outputDir"
)
}
}
}
or use buildSrc scripts to prevent code duplication. See this repo for example https://github.com/olshevski/compose-navigation-reimagined/blob/main/buildSrc/src/main/kotlin/compose-compiler-reports.gradle.kts

Sonar Jacoco not considering Kotlin androidTest (integration test case) in coverage

I have local and integrated test cases written for my android project. Using Kotlin(1.4.21) Robolectric(4.5.1), sonar(2.7.1), Jacoco(maven plugin 0.8.2)
The problem is that the Sonar and Jacoco is not considering androidTest(integration test case) written in Kotlin for code coverage
However sonar is showing correct coverage for other test cases like-
java unit test cases -> working
koltin unit test case -> working
java integrated test cases -> working
kotlin integrated test cases -> NOT WORKING
Although I have checked the paths I have set for sonar and it's all correct.
properties['sonar.java.binaries'] = files("${buildDir}/intermediates/javac/universalDebug/classes")
properties["sonar.java.binaries"] += files("${buildDir}/tmp/kotlin-classes/universalDebug/")
properties['sonar.java.test.binaries'] = files("${buildDir}/intermediates/javac/universalDebugAndroidTest/classes")
properties['sonar.java.test.binaries'] += files("${buildDir}/tmp/kotlin-classes/universalDebugAndroidTest/")
I have gone through other stackoverflow questions but didn't find same problem. So, I'm unable to find out the issue why sonar is not showing coverage for my integrated test cases written in Kotlin.
Thanks in Advance
UPDATE
within adroidTest folder > I have further 2 packages.
MyApplicationTest> src> com > pkgA
> pkgB
It's considering the Tests files present in pkgA but not the other. I have recently created this pkgB
What could be the possible reason for this? Do I have update some path somewhere?
You might need to do the following
tasks.withType(Test) {
jacoco.includeNoLocationClasses = true
}
Note that there are some issues with Java 11 that might fail your tests so you might want to also exclude jdk.internal as follows
tasks.withType(Test) {
jacoco.includeNoLocationClasses = true
excludes = ['jdk.internal.*']
}
Or a little bit verbose option but works:
subprojects {
pluginManager.withPlugin("com.android.library"){
android.testOptions.unitTests.all {
jacoco {
includeNoLocationClasses = true
excludes = ['jdk.internal.*']
}
}
}
pluginManager.withPlugin("com.android.application"){
android.testOptions.unitTests.all {
jacoco {
includeNoLocationClasses = true
excludes = ['jdk.internal.*']
}
}
}
apply plugin: 'jacoco'
}
I suggest you also upgrade your jacoco and sonar plugin versions if possible

Use Kotlin compiler options for test sources in Android Studio

In my test sources I want to use some experimental Kotlin compiler feature to not see the lint warnings and errors for them in Android Studio. For example, I want to apply the following Kotlin options to all test sources.
compileTestKotlin {
kotlinOptions {
freeCompilerArgs += [
'-Xopt-in=kotlin.time.ExperimentalTime',
'-Xopt-in=kotlinx.coroutines.ExperimentalCoroutinesApi',
]
}
}
(source)
Out of the box this doesn't work in an Android project, because there is no compileTestKotlin method. According to the kotlin-android Gradle plugin docs, it should be possible to do this for compileVariantNameKotlin in an afterEvaluate block, e.g.:
afterEvaluate {
compileDebugUnitTestKotlin {
kotlinOptions {
freeCompilerArgs += [
'-Xopt-in=kotlin.time.ExperimentalTime',
'-Xopt-in=kotlinx.coroutines.ExperimentalCoroutinesApi',
]
}
}
}
(and similar for compileReleaseUnitTestKotlin)
Although this works (builds and test run and pass just fine), there seems to be no effect in Android Studio: usages of the experimental compiler features are still marked with warnings/errors.
How do I enable these compiler features for my test sources in such a way that AS recognizes and uses them?
This worked for me on Android Studio 4.2.2, AGP version 4.2.0, Kotlin version 1.5.10:
android {
testOptions {
kotlinOptions {
freeCompilerArgs += [
'-Xopt-in=kotlin.time.ExperimentalTime',
'-Xopt-in=kotlinx.coroutines.ExperimentalCoroutinesApi',
]
}
}
}

How to configure Firebase Performance Monitoring plugin extension in Gradle Kotlin DSL

I have an Android app using Gradle with Kotlin DSL. I'm adding Firebase Performance Monitoring, but I would like for it to be enabled only for a specific build type.
I've been following the instructions provided at Firebase - Disable Firebase Performance Monitoring. Unfortunately the provided snippets are in Groovy.
I've tried to get a reference to the Firebase Performance Monitoring extension in my app level Gradle script by doing the following:
plugins {
...
id("com.google.firebase.firebase-perf")
kotlin("android")
kotlin("android.extensions")
kotlin("kapt")
}
buildTypes {
getByName(BuildTypes.DEBUG) {
configure<com.google.firebase.perf.plugin.FirebasePerfExtension> {
setInstrumentationEnabled(false)
}
}
...
}
...
dependencies {
val firebaseVersion = "17.2.1"
implementation("com.google.firebase:firebase-core:$firebaseVersion")
implementation("com.google.firebase:firebase-analytics:$firebaseVersion")
implementation("com.google.firebase:firebase-perf:19.0.5")
}
Android Studio doesn't see any problem in this and auto-completes FirebasePerfExtension.
Unfortunately upon running a Gradle sync I get the following:
Extension of type 'FirebasePerfExtension' does not exist.
Currently registered extension types: [ExtraPropertiesExtension, DefaultArtifactPublicationSet, ReportingExtension, SourceSetContainer, JavaPluginExtension, NamedDomainObjectContainer<BaseVariantOutput>, BaseAppModuleExtension, CrashlyticsExtension, KotlinAndroidProjectExtension, KotlinTestsRegistry, AndroidExtensionsExtension, KaptExtension]
There's no plugin extension related to Firebase Performance Monitoring.
This is in my project level build.gradle file dependencies block:
classpath("com.google.firebase:perf-plugin:1.3.1")
Any help is appreciated!
Update 1
As recommended on the Gradle - Migrating build logic from Groovy to Kotlin guide at "Knowing what plugin-provided extensions are available" I've ran the kotlinDslAccessorsReport task. None of the resulting extensions seems to be related to Firebase.
Had the same issue and was going to apply from groovy file, but seems i found the solution in here: https://docs.gradle.org/5.0/userguide/kotlin_dsl.html#sec:interoperability
withGroovyBuilder {
"FirebasePerformance" {
invokeMethod("setInstrumentationEnabled", false)
}
}
We used this answer, util we discovered a better working way in the team
check(this is ExtensionAware)
configure<com.google.firebase.perf.plugin.FirebasePerfExtension> { setInstrumentationEnabled(false) }

how to get Dagger2 Compiler Options working?

I'm trying to use 3 of the dagger2 compiler options in my android project.
but it seems none of them actually work.
I have pasted the code from here to my gradle.properties and even compiler options of AS settings.
the 3 that I'm interested in are:
-Adagger.fastInit=enabled
-Adagger.formatGeneratedSource=disabled
-Adagger.gradle.incremental
the fastinit and codeformatting just don't work (judging by the code that is generated) but the incremental cause a compile error saying:
no compiler option found.
the versions that I'm using are:
dagger : 2.18
gradle : 5.2.1
kotlin : 1.3.21
androidPlugin : 3.3.1
For projects with multiple modules, the top build.gradle can be updated with this
allprojects {
repositories {
...
}
afterEvaluate {
extensions.findByName('kapt')?.arguments {
arg( "dagger.formatGeneratedSource", "disabled" )
}
}
}
Perhaps you should try without "A"
dagger.fastInit=enabled
dagger.formatGeneratedSource=disabled
dagger.gradle.incremental=enabled
Also can try directly in build.gradle, but this should be done for each project.
kapt {
arguments {
arg('dagger.fastInit', 'enabled')
arg('dagger.formatGeneratedSource', 'disabled')
arg('dagger.gradle.incremental', 'enabled')
}
}

Categories

Resources