CycloneDX / cyclonedx-gradle-plugin

Creates CycloneDX Software Bill of Materials (SBOM) from Gradle projects
https://cyclonedx.org/
Apache License 2.0
145 stars 72 forks source link

Kotlin Script, Android Support? #341

Open mandrachek opened 9 months ago

mandrachek commented 9 months ago

I'm attempting to use this plugin on an Android project, running Android Gradle Plugin and Gradle versions 8.1.1, kotlin script based build.

I've added the plugin with apply false in my top level project, and include it my app module. However when I attempt to configure it with

cyclonedxBom {
    includeConfigs = configurations.mapNotNull {
        if (
            it.name.contains("implementation", true)
            || it.name.contains("runtimeonly", true)
            || it.name.contains("api", true)
        ) {
            it.name
        } else {
            null
        }
    }
}

I get an a couple of exceptions:

Expression 'cyclonedxBom' cannot be invoked as a function. The function 'invoke()' is not found

Unresolved reference. None of the following candidates is applicable because of receiver type mismatch: 
public val TaskContainer.cyclonedxBom: TaskProvider<CycloneDxTask> defined in org.gradle.kotlin.dsl

Unresolved reference: includeConfigs

The first exception is thrown even with just an empty cyclonedxBom {}. It appears the configuration does not work with Kotlin script (build.gradle.kts).

If I attempt to run the task without the configuration I get a whole bunch of errors.

The consumer was configured to find a component for use during runtime, preferably optimized for Android, as well as attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'release', attribute 'com.android.build.api.attributes.ProductFlavor:default' with value 'qa', attribute 'com.android.build.api.attributes.AgpVersionAttr' with value '8.1.1', attribute 'org.jetbrains.kotlin.platform.type' with value 'androidJvm'. However we cannot choose between the following variants of project :mymodule:
    - Configuration ':mymodule:releaseRuntimeElements' variant android-aar-metadata declares a component for use during runtime, preferably optimized for Android, as well as attribute 'com.android.build.api.attributes.AgpVersionAttr' with value '8.1.1', 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-aar-metadata' but the consumer didn't ask for it
            - Doesn't say anything about com.android.build.api.attributes.ProductFlavor:default (required 'qa')
            - Provides attribute 'com.android.build.gradle.internal.attributes.VariantAttr' with value 'release' but the consumer didn't ask for it
            - Provides a library but the consumer didn't ask for it
    - Configuration ':mymodule:releaseRuntimeElements' variant android-art-profile declares a component for use during runtime, preferably optimized for Android, as well as attribute 'com.android.build.api.attributes.AgpVersionAttr' with value '8.1.1', 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-art-profile' but the consumer didn't ask for it
            - Doesn't say anything about com.android.build.api.attributes.ProductFlavor:default (required 'qa')
            - Provides attribute 'com.android.build.gradle.internal.attributes.VariantAttr' with value 'release' but the consumer didn't ask for it
            - Provides a library but the consumer didn't ask for it
    - Configuration ':mymodule:releaseRuntimeElements' variant android-assets declares a component for use during runtime, preferably optimized for Android, as well as attribute 'com.android.build.api.attributes.AgpVersionAttr' with value '8.1.1', 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-assets' but the consumer didn't ask for it
            - Doesn't say anything about com.android.build.api.attributes.ProductFlavor:default (required 'qa')
            - Provides attribute 'com.android.build.gradle.internal.attributes.VariantAttr' with value 'release' but the consumer didn't ask for it
            - Provides a library but the consumer didn't ask for it
    - Configuration ':mymodule:releaseRuntimeElements' variant android-classes-directory-Aorg.gradle.libraryelements=classes declares a component for use during runtime, preferably optimized for Android, as well as attribute 'com.android.build.api.attributes.AgpVersionAttr' with value '8.1.1', 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-classes-directory' but the consumer didn't ask for it
            - Doesn't say anything about com.android.build.api.attributes.ProductFlavor:default (required 'qa')
            - Provides attribute 'com.android.build.gradle.internal.attributes.VariantAttr' with value 'release' but the consumer didn't ask for it
            - Provides a library but the consumer didn't ask for it
            - Provides its elements preferably in the form of class files but the consumer didn't ask for it
    - Configuration ':mymodule:releaseRuntimeElements' variant android-classes-jar declares a component for use during runtime, preferably optimized for Android, as well as attribute 'com.android.build.api.attributes.AgpVersionAttr' with value '8.1.1', 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-classes-jar' but the consumer didn't ask for it
            - Doesn't say anything about com.android.build.api.attributes.ProductFlavor:default (required 'qa')
            - Provides attribute 'com.android.build.gradle.internal.attributes.VariantAttr' with value 'release' but the consumer didn't ask for it
            - Provides a library but the consumer didn't ask for it
            - Provides its elements packaged as a jar but the consumer didn't ask for it
    - Configuration ':mymodule:releaseRuntimeElements' variant android-compiled-dependencies-resources declares a component for use during runtime, preferably optimized for Android, as well as attribute 'com.android.build.api.attributes.AgpVersionAttr' with value '8.1.1', 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-compiled-dependencies-resources' but the consumer didn't ask for it
            - Doesn't say anything about com.android.build.api.attributes.ProductFlavor:default (required 'qa')
            - Provides attribute 'com.android.build.gradle.internal.attributes.VariantAttr' with value 'release' but the consumer didn't ask for it
            - Provides a library but the consumer didn't ask for it
    - Configuration ':mymodule:releaseRuntimeElements' variant android-consumer-proguard-rules declares a component for use during runtime, preferably optimized for Android, as well as attribute 'com.android.build.api.attributes.AgpVersionAttr' with value '8.1.1', 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-consumer-proguard-rules' but the consumer didn't ask for it
            - Doesn't say anything about com.android.build.api.attributes.ProductFlavor:default (required 'qa')
            - Provides attribute 'com.android.build.gradle.internal.attributes.VariantAttr' with value 'release' but the consumer didn't ask for it
            - Provides a library but the consumer didn't ask for it
    - Configuration ':mymodule:releaseRuntimeElements' variant android-java-res declares a component for use during runtime, preferably optimized for Android, as well as attribute 'com.android.build.api.attributes.AgpVersionAttr' with value '8.1.1', 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-java-res' but the consumer didn't ask for it
            - Doesn't say anything about com.android.build.api.attributes.ProductFlavor:default (required 'qa')
            - Provides attribute 'com.android.build.gradle.internal.attributes.VariantAttr' with value 'release' but the consumer didn't ask for it
            - Provides a library but the consumer didn't ask for it
    - Configuration ':mymodule:releaseRuntimeElements' variant android-jni declares a component for use during runtime, preferably optimized for Android, as well as attribute 'com.android.build.api.attributes.AgpVersionAttr' with value '8.1.1', 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-jni' but the consumer didn't ask for it
            - Doesn't say anything about com.android.build.api.attributes.ProductFlavor:default (required 'qa')
            - Provides attribute 'com.android.build.gradle.internal.attributes.VariantAttr' with value 'release' but the consumer didn't ask for it
            - Provides a library but the consumer didn't ask for it
    - Configuration ':mymodule:releaseRuntimeElements' variant android-lint declares a component for use during runtime, preferably optimized for Android, as well as attribute 'com.android.build.api.attributes.AgpVersionAttr' with value '8.1.1', 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-lint' but the consumer didn't ask for it
            - Doesn't say anything about com.android.build.api.attributes.ProductFlavor:default (required 'qa')
            - Provides attribute 'com.android.build.gradle.internal.attributes.VariantAttr' with value 'release' but the consumer didn't ask for it
            - Provides a library but the consumer didn't ask for it
            - Provides its elements packaged as a jar but the consumer didn't ask for it
    - Configuration ':mymodule:releaseRuntimeElements' variant android-lint-local-aar declares a component for use during runtime, preferably optimized for Android, as well as attribute 'com.android.build.api.attributes.AgpVersionAttr' with value '8.1.1', 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-lint-local-aar' but the consumer didn't ask for it
            - Doesn't say anything about com.android.build.api.attributes.ProductFlavor:default (required 'qa')
            - Provides attribute 'com.android.build.gradle.internal.attributes.VariantAttr' with value 'release' but the consumer didn't ask for it
            - Provides a library but the consumer didn't ask for it
    - Configuration ':mymodule:releaseRuntimeElements' variant android-lint-model-metadata declares a component for use during runtime, preferably optimized for Android, as well as attribute 'com.android.build.api.attributes.AgpVersionAttr' with value '8.1.1', 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-lint-model-metadata' but the consumer didn't ask for it
            - Doesn't say anything about com.android.build.api.attributes.ProductFlavor:default (required 'qa')
            - Provides attribute 'com.android.build.gradle.internal.attributes.VariantAttr' with value 'release' but the consumer didn't ask for it
            - Provides a library but the consumer didn't ask for it
    - Configuration ':mymodule:releaseRuntimeElements' variant android-lint-variant-dependencies-model declares a component for use during runtime, preferably optimized for Android, as well as attribute 'com.android.build.api.attributes.AgpVersionAttr' with value '8.1.1', 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-lint-variant-dependencies-model' but the consumer didn't ask for it
            - Doesn't say anything about com.android.build.api.attributes.ProductFlavor:default (required 'qa')
            - Provides attribute 'com.android.build.gradle.internal.attributes.VariantAttr' with value 'release' but the consumer didn't ask for it
            - Provides a library but the consumer didn't ask for it
    - Configuration ':mymodule:releaseRuntimeElements' variant android-lint-variant-dependencies-partial-results declares a component for use during runtime, preferably optimized for Android, as well as attribute 'com.android.build.api.attributes.AgpVersionAttr' with value '8.1.1', 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-lint-variant-dependencies-partial-results' but the consumer didn't ask for it
            - Doesn't say anything about com.android.build.api.attributes.ProductFlavor:default (required 'qa')
            - Provides attribute 'com.android.build.gradle.internal.attributes.VariantAttr' with value 'release' but the consumer didn't ask for it
            - Provides a library but the consumer didn't ask for it
    - Configuration ':mymodule:releaseRuntimeElements' variant android-manifest declares a component for use during runtime, preferably optimized for Android, as well as attribute 'com.android.build.api.attributes.AgpVersionAttr' with value '8.1.1', 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
            - Doesn't say anything about com.android.build.api.attributes.ProductFlavor:default (required 'qa')
            - Provides attribute 'com.android.build.gradle.internal.attributes.VariantAttr' with value 'release' but the consumer didn't ask for it
            - Provides a library but the consumer didn't ask for it
    - Configuration ':mymodule:releaseRuntimeElements' variant android-navigation-json declares a component for use during runtime, preferably optimized for Android, as well as attribute 'com.android.build.api.attributes.AgpVersionAttr' with value '8.1.1', 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-navigation-json' but the consumer didn't ask for it
            - Doesn't say anything about com.android.build.api.attributes.ProductFlavor:default (required 'qa')
            - Provides attribute 'com.android.build.gradle.internal.attributes.VariantAttr' with value 'release' but the consumer didn't ask for it
            - Provides a library but the consumer didn't ask for it
    - Configuration ':mymodule:releaseRuntimeElements' variant android-public-res declares a component for use during runtime, preferably optimized for Android, as well as attribute 'com.android.build.api.attributes.AgpVersionAttr' with value '8.1.1', 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-public-res' but the consumer didn't ask for it
            - Doesn't say anything about com.android.build.api.attributes.ProductFlavor:default (required 'qa')
            - Provides attribute 'com.android.build.gradle.internal.attributes.VariantAttr' with value 'release' but the consumer didn't ask for it
            - Provides a library but the consumer didn't ask for it
    - Configuration ':mymodule:releaseRuntimeElements' variant android-res declares a component for use during runtime, preferably optimized for Android, as well as attribute 'com.android.build.api.attributes.AgpVersionAttr' with value '8.1.1', 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-res' but the consumer didn't ask for it
            - Doesn't say anything about com.android.build.api.attributes.ProductFlavor:default (required 'qa')
            - Provides attribute 'com.android.build.gradle.internal.attributes.VariantAttr' with value 'release' but the consumer didn't ask for it
            - Provides a library but the consumer didn't ask for it
    - Configuration ':mymodule:releaseRuntimeElements' variant android-symbol declares a component for use during runtime, preferably optimized for Android, as well as attribute 'com.android.build.api.attributes.AgpVersionAttr' with value '8.1.1', 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' but the consumer didn't ask for it
            - Doesn't say anything about com.android.build.api.attributes.ProductFlavor:default (required 'qa')
            - Provides attribute 'com.android.build.gradle.internal.attributes.VariantAttr' with value 'release' but the consumer didn't ask for it
            - Provides a library but the consumer didn't ask for it
    - Configuration ':mymodule:releaseRuntimeElements' variant android-symbol-with-package-name declares a component for use during runtime, preferably optimized for Android, as well as attribute 'com.android.build.api.attributes.AgpVersionAttr' with value '8.1.1', 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
            - Doesn't say anything about com.android.build.api.attributes.ProductFlavor:default (required 'qa')
            - Provides attribute 'com.android.build.gradle.internal.attributes.VariantAttr' with value 'release' but the consumer didn't ask for it
            - Provides a library but the consumer didn't ask for it
    - Configuration ':mymodule:releaseRuntimeElements' variant jar declares a component for use during runtime, preferably optimized for Android, as well as attribute 'com.android.build.api.attributes.AgpVersionAttr' with value '8.1.1', 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 'jar' but the consumer didn't ask for it
            - Doesn't say anything about com.android.build.api.attributes.ProductFlavor:default (required 'qa')
            - Provides attribute 'com.android.build.gradle.internal.attributes.VariantAttr' with value 'release' but the consumer didn't ask for it
            - Provides a library but the consumer didn't ask for it
            - Provides its elements packaged as a jar but the consumer didn't ask for it
    - Configuration ':mymodule:releaseRuntimeElements' variant supported-locale-list declares a component for use during runtime, preferably optimized for Android, as well as attribute 'com.android.build.api.attributes.AgpVersionAttr' with value '8.1.1', 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 'supported-locale-list' but the consumer didn't ask for it
            - Doesn't say anything about com.android.build.api.attributes.ProductFlavor:default (required 'qa')
            - Provides attribute 'com.android.build.gradle.internal.attributes.VariantAttr' with value 'release' but the consumer didn't ask for it
            - Provides a library but the consumer didn't ask for it

It would appear that the plugin is not android friendly (hence attempting to control the included configurations).

mandrachek commented 9 months ago

I was able to almost get this working, by configuring like this:

tasks.withType<CycloneDxTask>().configureEach {
   setIncludedConfigs(listOf("${variant}CompileClasspath", "${variant}RuntimeClasspath"))
}

per https://github.com/CycloneDX/cyclonedx-gradle-plugin/issues/299#issuecomment-1618072286 instead of using cyclonedxBom {}

However, my project depends on many modules (android library projects), which in turn have their own dependencies. As soon as I hit the first library project I get the same errors.

fnxpt commented 8 months ago

instead of implementation project(':sub-project') use implementation project(path:':sub-project', configuration: "default")

xcarlitos commented 7 months ago

@mandrachek were you able to resolve the issue? I am facing exactly the same problem...

mandrachek commented 7 months ago

No. adding configuration: "default" to every dependency isn't realistic for the size of my project, so no luck. I wound up using the com.jaredsburrows.licenseReport plugin instead.

benjoseph commented 6 months ago

I was able to use the workaround mentioned at https://github.com/jk1/Gradle-License-Report/issues/199#issuecomment-1276371430

allprojects {
    // UNCOMMENT THIS BEFORE RUNNING cyclonedxBom
    // def artifactType = Attribute.of('artifactType', String)
    // dependencies.attributesSchema {
    //     attribute(artifactType)
    // }
    // configurations {
    //     releaseRuntimeClasspath {
    //         attributes {
    //             // help gradle choose a variant:
    //             attribute(artifactType, 'android-classes-jar')
    //         }
    //     }
    // }
}

Relevant docs:

https://docs.gradle.org/current/userguide/variant_attributes.html https://docs.gradle.org/current/userguide/variant_model.html

Cassio90 commented 2 weeks ago

The hack does not work for me 🤔

Even with a fresh android project or with this example project https://github.com/android/nowinandroid I could not get it to run and create a sbom with contents.

Is there any plan to make this plugin work with Android at all?