JetBrains / compose-multiplatform

Compose Multiplatform, a modern UI framework for Kotlin that makes building performant and beautiful user interfaces easy and enjoyable.
https://jetbrains.com/lp/compose-multiplatform
Apache License 2.0
15.3k stars 1.11k forks source link

Allow using Jetpack Compose BOM #2502

Open eygraber opened 1 year ago

eygraber commented 1 year ago

I'm using Jetbrains Compose in a lot of my libraries, but when I consume them in Android I want to use a version of Jetpack Compose that is newer than the ones that Jetbrains re-writes them to.

I've been using this snippet to do that:

configurations.configureEach {
  resolutionStrategy {
    eachDependency {
      val isCompiler = requested.group.endsWith("compiler")
      if(requested.group.startsWith("androidx.compose")) {
        // don't override the compiler
        if(!isCompiler) {
          useVersion(composeVersionOverride)
        }
      }
    }
  }
}  

Now that Jetpack Compose provides a BOM I'd like to use that instead of one version for all androidx compose artifacts (which may not work in the future since the versioning can be independent).

Since Jetbrains Compose rewrites the dependencies in the group:name:version format, it will not work with the BOM which expects the dependencies to be written in the group:name format. I've borrowed a trick from the Jetbrains Compose plugin to achieve this:

android {
      dependencies {
        // jetbrains compose plugin rewrites compose dependencies for android to point to androidx
        // if we want to use the compose BOM we need to rewrite the rewritten dependencies to not include a version
        components {
          all {
            val isCompiler = id.group.endsWith("compiler")
            val isCompose = id.group.startsWith("androidx.compose")
            val isBom = id.name == "compose-bom"

            val override = isCompose && !isCompiler && !isBom
            if(override) {
              // copied from Jetbrains Compose RedirectAndroidVariants
              // https://github.com/JetBrains/compose-jb/blob/612fab6099aa93a6f6d440350c905d948b6f5999/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/ComposePlugin.kt#L85
              listOf(
                "debugApiElements-published",
                "debugRuntimeElements-published",
                "releaseApiElements-published",
                "releaseRuntimeElements-published"
              ).forEach { variantNameToAlter ->
                withVariant(variantNameToAlter) {
                  withDependencies {
                    removeAll { true } // remove androidx artifact with version
                    add("${id.group}:${id.name}") // add androidx artifact without version
                  }
                }
              }
            }
          }
        }
      }
    }

Would you be open to a PR that will natively support the BOM through the Jetbrains Compose plugin?

My thought is to add a flag to the AndroidExtension for setting a BOM version, and if it is present, the plugin will add a dependency to the BOM, and rewrite the androidx dependencies using group:name. An alternative is to have a boolean saying to rewrite the dependencies using the group:name format, and let the consumer be responsible for adding the BOM dependency themselves.

eygraber commented 11 months ago

It looks like the compose plugin no longer does the rewriting of the dependencies, and I can't find where it's actually happening. Any pointers?

dima-avdeev-jb commented 11 months ago

It looks like the compose plugin no longer does the rewriting of the dependencies, and I can't find where it's actually happening. Any pointers?

https://github.com/JetBrains/compose-multiplatform/tree/master/gradle-plugins

eygraber commented 11 months ago

It used to happen in https://github.com/JetBrains/compose-jb/blob/612fab6099aa93a6f6d440350c905d948b6f5999/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/ComposePlugin.kt#L85 but it doesn't look like there's anything in the plugin that does that anymore.

dima-avdeev-jb commented 11 months ago

It looks like the compose plugin no longer does the rewriting of the dependencies

What version of Compose Multiplatform are you checked?

eygraber commented 11 months ago

1.5.0-beta01

The behavior is still there, but what I meant was that there doesn't seem to be code in the plugin that does it anymore.