detekt: Tasks `detektAndroidDebugUnitTest` `detektAndroidReleaseUnitTest` and `detektAndroidDebugAndroidTest` fail to run in a KMM project

Expected Behavior

Able to run these tasks and gradle will run

Observed Behavior

An exception is thrown and no tasks are run

Could not determine the dependencies of task ':pangea-core:detektAndroidReleaseUnitTest'.
> Could not resolve all task dependencies for configuration ':pangea-core:releaseUnitTestCompileClasspath'.
   > The consumer was configured to find an API of a component, as well as attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'release', attribute 'org.jetbrains.kotlin.platform.type' with value 'androidJvm'. However we cannot choose between the following variants of project :pangea-core:
       - Configuration ':pangea-core:releaseApiElements' variant android-aidl declares an API of a component, as well as attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'release', attribute 'org.jetbrains.kotlin.platform.type' with value 'androidJvm':
           - Unmatched attributes:
               - Provides attribute 'artifactType' with value 'android-aidl' but the consumer didn't ask for it
               - Provides attribute 'com.android.build.api.attributes.VariantAttr' with value 'release' but the consumer didn't ask for it
       - Configuration ':pangea-core:releaseApiElements' variant android-manifest declares an API of a component, as well as attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'release', attribute 'org.jetbrains.kotlin.platform.type' with value 'androidJvm':
           - Unmatched attributes:
               - Provides attribute 'artifactType' with value 'android-manifest' but the consumer didn't ask for it
               - Provides attribute 'com.android.build.api.attributes.VariantAttr' with value 'release' but the consumer didn't ask for it
       - Configuration ':pangea-core:releaseApiElements' variant android-renderscript declares an API of a component, as well as attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'release', attribute 'org.jetbrains.kotlin.platform.type' with value 'androidJvm':
           - Unmatched attributes:
               - Provides attribute 'artifactType' with value 'android-renderscript' but the consumer didn't ask for it
               - Provides attribute 'com.android.build.api.attributes.VariantAttr' with value 'release' but the consumer didn't ask for it
       - Configuration ':pangea-core:releaseApiElements' variant android-symbol-with-package-name declares an API of a component, as well as attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'release', attribute 'org.jetbrains.kotlin.platform.type' with value 'androidJvm':
           - Unmatched attributes:
               - Provides attribute 'artifactType' with value 'android-symbol-with-package-name' but the consumer didn't ask for it
               - Provides attribute 'com.android.build.api.attributes.VariantAttr' with value 'release' but the consumer didn't ask for it

Steps to Reproduce

Context

Since these tasks are part of the check task, that task cannot be run. This can be worked around by disabling the tasks.

The project has Kotlin targets for iOS, JVM, and Android.

kotlin {
    ios()
    jvm()
    android()
   
    more configuration
}

Your Environment

  • Version of detekt used: 1.16.0 and 1.71.2
  • Version of Gradle used (if applicable): 6.7.1
  • Gradle scan link (add --scan option when running the gradle task):
  • Operating System and version: MacOS 11.3.1
  • Link to your project (if it’s a public repository):
  • AGP 4.2.1

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Comments: 19 (10 by maintainers)

Commits related to this issue

Most upvoted comments

Thank you all for the support. It took me quite some time to debug/fix this, but I believe this will do the job: #4026.

I’ve updated the KMP detekt support to delegate to AGP for resolving classpath (as we’re already doing for pure Android projects).

As a side note, I haven’t really found what was the root cause of the failure to resolve the releaseUnitTestCompileClasspath due to attribute mismatch (I haven’t found any relevant issue or discussion on any public forum).

The following temporary workaround worked for me:

    gradle.startParameter.excludedTaskNames.addAll(
            "detektAndroidDebugAndroidTest",
            "detektAndroidDebugUnitTest",
            "detektAndroidReleaseUnitTest",
            "detektAndroidDebug",
            "detektAndroidRelease"
    )

I could make it work by adding this to build.gradle.kts:

val artifactType = Attribute.of("artifactType", String::class.java)

class DisambiguationRule: AttributeDisambiguationRule<String> {
    override fun execute(t: MultipleCandidatesDetails<String>) {
        /**
         * The default disambiguation rules exclude the jar variants because they define the `org.gradle.libraryelements`
         *
         * See https://github.com/gradle/gradle/blob/master/subprojects/dependency-management/src/main/java/org/gradle/internal/component/model/MultipleCandidateMatcher.java#L221
         *
         * Not 100% sure why this happens but forcing to use the jar in this specific case fixes the issue
         */
        val jar = t.candidateValues.firstOrNull { it == "jar" }
        if (jar != null) {
            t.closestMatch(jar)
        }
    }

}

dependencies.attributesSchema.attribute(artifactType).disambiguationRules.add(DisambiguationRule::class.java

I tried this after putting a breakpoint in the Gradle resolution code on this line but TBH, I’m not 100% sure if that’s a good solution

State when the breakpoint is reached for the record:

Screenshot 2021-05-27 at 16 33 33

I was able to reproduce (thanks for the sample project). Sadly I could not come up with a solution, but it seems like with KMM, the test and androidTest build types fails to fallback to “debug” for the sake of configuration resolution.

I’ve cleaned your project and came up with a version that contains only the bare minimum detekt setup, but that it’s still failing:

detekt-sample-cleaned.zip

So far the issue seems to be really similar to https://github.com/apollographql/apollo-android/issues/2401. I’ve asked @martinbonnin some help, maybe he can give us some hint 😃

Will keep on investigating in the next days. If you do some findings, please post them here.

Still broken with gradle 7.0.2.

Will try to create a reproduction case.