Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/jb-main' into igor.demin/materia…
Browse files Browse the repository at this point in the history
…l3-1.2.0

# Conflicts:
#	gradle.properties
  • Loading branch information
igordmn committed Feb 8, 2024
2 parents 81dcc07 + 73cfb2e commit 2458969
Show file tree
Hide file tree
Showing 28 changed files with 751 additions and 301 deletions.
7 changes: 4 additions & 3 deletions annotation/annotation/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,16 @@ plugins {
AndroidXComposePlugin.applyAndConfigureKotlinPlugin(project)

androidXComposeMultiplatform {
desktop()
js()
wasm()
darwin()

linuxX64()
linuxArm64()
}

kotlin {
jvm()
// Not all modules can have these targets, so declare them here instead of androidXComposeMultiplatform.
// We can support the kotlin-native targets supported by kotlin coroutines:
// https://github.com/Kotlin/kotlinx.coroutines/blob/master/gradle/compile-native-multiplatform.gradle
Expand All @@ -32,8 +35,6 @@ kotlin {
tvosX64()
tvosSimulatorArm64()
mingwX64()
linuxArm64()
linuxX64()

sourceSets {
commonMain {
Expand Down
18 changes: 18 additions & 0 deletions annotation/annotation/gradle.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#
# Copyright 2024 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

artifactRedirecting.publication.targetNames=jvm,macosX64,macosArm64,uikitX64,uikitArm64,uikitSimArm64,linuxX64
artifactRedirecting.androidx.groupId=androidx.annotation
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ package androidx.annotation
* ```
* public @CheckResult String trim(String s) { return s.trim(); }
* ...
* trim(s); // this is probably an error
* s = trim(s); // ok
* s.trim(); // this is probably an error
* s = s.trim(); // ok
* ```
*/
@MustBeDocumented
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,9 @@ import java.lang.annotation.ElementType.TYPE
// https://youtrack.jetbrains.com/issue/KT-45921
@Suppress("DEPRECATED_JAVA_ANNOTATION", "SupportAnnotationUsage")
@java.lang.annotation.Target(TYPE, METHOD, CONSTRUCTOR, FIELD, PACKAGE)
public actual annotation class RequiresApi(
public annotation class RequiresApi(
/** The API level to require. Alias for [.api] which allows you to leave out the `api=` part. */
@IntRange(from = 1) actual val value: Int = 1,
@IntRange(from = 1) val value: Int = 1,
/** The API level to require */
@IntRange(from = 1) actual val api: Int = 1
@IntRange(from = 1) val api: Int = 1
)
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ class AndroidXComposeImplPlugin : Plugin<Project> {

if (plugin is KotlinMultiplatformPluginWrapper) {
project.configureForMultiplatform()
enableOELPublishing(project)
enableArtifactRedirectingPublishing(project)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,31 +21,16 @@ import org.gradle.api.Project
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
import org.jetbrains.kotlin.gradle.plugin.KotlinJsCompilerType
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
import org.jetbrains.kotlin.gradle.plugin.*
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinAndroidTarget
import org.gradle.api.Action
import org.jetbrains.kotlin.gradle.plugin.mpp.*
import org.gradle.api.publish.PublishingExtension
import org.gradle.api.publish.maven.internal.publication.DefaultMavenPublication
import org.gradle.api.attributes.Usage
import org.gradle.api.tasks.Copy
import org.gradle.kotlin.dsl.creating
import org.gradle.kotlin.dsl.dependencies
import org.gradle.kotlin.dsl.getValue
import org.jetbrains.kotlin.konan.target.KonanTarget
import org.gradle.api.artifacts.Configuration
import org.gradle.api.artifacts.DependencyConstraint
import org.gradle.api.artifacts.ExcludeRule
import org.gradle.api.artifacts.ModuleDependency
import org.gradle.api.artifacts.ModuleVersionIdentifier
import org.gradle.api.artifacts.PublishArtifact
import org.gradle.api.attributes.AttributeContainer
import org.gradle.api.capabilities.Capability
import org.gradle.api.component.ComponentWithCoordinates
import org.gradle.api.component.ComponentWithVariants
import org.gradle.api.component.SoftwareComponent
import org.gradle.api.internal.component.SoftwareComponentInternal
import org.gradle.api.internal.component.UsageContext
import org.gradle.api.publish.maven.MavenPublication
import org.gradle.api.publish.maven.tasks.AbstractPublishToMaven
import org.gradle.kotlin.dsl.create
Expand Down Expand Up @@ -169,11 +154,21 @@ open class AndroidXComposeMultiplatformExtensionImpl @Inject constructor(
}

override fun darwin(): Unit = multiplatformExtension.run {
macosX64()
macosArm64()
iosX64("uikitX64")
iosArm64("uikitArm64")
iosSimulatorArm64("uikitSimArm64")
macosX64() {
substituteForOelPublishedDependencies()
}
macosArm64() {
substituteForOelPublishedDependencies()
}
iosX64("uikitX64") {
substituteForOelPublishedDependencies()
}
iosArm64("uikitArm64") {
substituteForOelPublishedDependencies()
}
iosSimulatorArm64("uikitSimArm64") {
substituteForOelPublishedDependencies()
}

val commonMain = sourceSets.getByName("commonMain")
val nativeMain = sourceSets.create("nativeMain")
Expand Down Expand Up @@ -216,6 +211,16 @@ open class AndroidXComposeMultiplatformExtensionImpl @Inject constructor(
uikitSimArm64Test.dependsOn(uikitTest)
}

override fun linuxX64(): Unit = multiplatformExtension.run {
linuxX64 {
substituteForOelPublishedDependencies()
}
}

override fun linuxArm64(): Unit = multiplatformExtension.run {
linuxArm64()
}

private fun getOrCreateJvmMain(): KotlinSourceSet =
getOrCreateSourceSet("jvmMain", "commonMain")

Expand Down Expand Up @@ -273,46 +278,52 @@ open class AndroidXComposeMultiplatformExtensionImpl @Inject constructor(
}
}

fun Project.experimentalOELPublication() : Boolean = findProperty("oel.publication") == "true"
fun Project.oelAndroidxVersion() : String? = findProperty("oel.androidx.version") as String?
fun Project.oelAndroidxFoundationVersion() : String? = findProperty("oel.androidx.foundation.version") as String?
fun Project.oelAndroidxMaterial3Version() : String? = findProperty("oel.androidx.material3.version") as String?
fun Project.oelAndroidxMaterialVersion() : String? = findProperty("oel.androidx.material.version") as String?
fun Project.experimentalArtifactRedirectingPublication() : Boolean = findProperty("artifactRedirecting.publication") == "true"
fun Project.artifactRedirectingAndroidxVersion() : String? = findProperty("artifactRedirecting.androidx.version") as String?
fun Project.artifactRedirectingAndroidxFoundationVersion() : String? = findProperty("artifactRedirecting.androidx.foundation.version") as String?
fun Project.artifactRedirectingAndroidxMaterial3Version() : String? = findProperty("artifactRedirecting.androidx.material3.version") as String?
fun Project.artifactRedirectingAndroidxMaterialVersion() : String? = findProperty("artifactRedirecting.androidx.material.version") as String?

fun enableOELPublishing(project: Project) {
if (!project.experimentalOELPublication()) return
fun enableArtifactRedirectingPublishing(project: Project) {
if (!project.experimentalArtifactRedirectingPublication()) return

if (project.experimentalOELPublication() && (project.oelAndroidxVersion() == null)) {
if (project.experimentalArtifactRedirectingPublication() && (project.artifactRedirectingAndroidxVersion() == null)) {
error("androidx version should be specified for OEL publications")
}

val ext = project.multiplatformExtension ?: error("expected a multiplatform project")

ext.targets.all { target ->
if (target is KotlinAndroidTarget) {
project.publishAndroidxReference(target)
val oelGroupId = project.findProperty("artifactRedirecting.androidx.groupId") as? String

val newRootComponent: CustomRootComponent? = if (oelGroupId != null) {
val oelVersion = project.findProperty("artifactRedirecting.androidx.${project.name}.version") as? String
requireNotNull(oelVersion) {
"Please specify artifactRedirecting.androidx.${project.name}.version property"
}

val rootComponent = project
.components
.withType(KotlinSoftwareComponentWithCoordinatesAndPublication::class.java)
.getByName("kotlin")

val newDependency = project.dependencies.create(oelGroupId, project.name, oelVersion)
CustomRootComponent(rootComponent, newDependency)
} else {
null
}
}

val oelTargetNames = (project.findProperty("artifactRedirecting.publication.targetNames") as? String ?: "")
.split(",").toSet()

/**
* Usage that should be added to rootSoftwareComponent to represent android-specific variants
* It will be serialized to *.module in "variants" collection.
*/
private class CustomAndroidUsage(
private val name: String,
private val attributes: AttributeContainer,
private val dependencies: Set<ModuleDependency>
) : UsageContext {
override fun getName(): String = name
override fun getArtifacts(): Set<PublishArtifact> = emptySet()
override fun getAttributes(): AttributeContainer = attributes
override fun getCapabilities(): Set<Capability> = emptySet()
override fun getDependencies(): Set<ModuleDependency> = dependencies
override fun getDependencyConstraints(): Set<DependencyConstraint> = emptySet()
override fun getGlobalExcludes(): Set<ExcludeRule> = emptySet()
override fun getUsage(): Usage = error("Should not be accessed!")
ext.targets.all { target ->
// TODO (o.k): support projects where oel publication is required for both android and native
if (target.name in oelTargetNames) {
project.publishAndroidxReference(target as KotlinOnlyTarget<*>, newRootComponent!!)
} else if (target is KotlinAndroidTarget) {
// TODO (o.k): try to get rid of this and reuse the same logic as above
project.publishAndroidxReference(target)
}
}
}

private fun Project.publishAndroidxReference(target: KotlinAndroidTarget) {
Expand All @@ -325,17 +336,17 @@ private fun Project.publishAndroidxReference(target: KotlinAndroidTarget) {
.withType(KotlinSoftwareComponentWithCoordinatesAndPublication::class.java)
.getByName("kotlin")

val composeVersion = requireNotNull(target.project.oelAndroidxVersion()) {
"Please specify oel.androidx.version property"
val composeVersion = requireNotNull(target.project.artifactRedirectingAndroidxVersion()) {
"Please specify artifactRedirecting.androidx.version property"
}
val material3Version =
requireNotNull(target.project.oelAndroidxMaterial3Version()) {
"Please specify oel.androidx.material3.version property"
requireNotNull(target.project.artifactRedirectingAndroidxMaterial3Version()) {
"Please specify artifactRedirecting.androidx.material3.version property"
}
val foundationVersion =
target.project.oelAndroidxFoundationVersion() ?: composeVersion
target.project.artifactRedirectingAndroidxFoundationVersion() ?: composeVersion
val materialVersion =
target.project.oelAndroidxMaterialVersion() ?: composeVersion
target.project.artifactRedirectingAndroidxMaterialVersion() ?: composeVersion

val groupId = target.project.group.toString()
val version = if (groupId.contains("org.jetbrains.compose.material3")) {
Expand All @@ -355,29 +366,7 @@ private fun Project.publishAndroidxReference(target: KotlinAndroidTarget) {


// We can't add more usages to rootComponent, so we must decorate it
val newRootComponent = object :
SoftwareComponentInternal,
ComponentWithVariants,
ComponentWithCoordinates {
override fun getName(): String = "kotlinDecoratedRootComponent"
override fun getVariants(): Set<SoftwareComponent> = rootComponent.variants
override fun getCoordinates(): ModuleVersionIdentifier =
rootComponent.coordinates

override fun getUsages(): Set<UsageContext> = rootComponent.usages + extraUsages

private val extraUsages = mutableSetOf<UsageContext>()

fun addUsageFromConfiguration(configuration: Configuration) {
extraUsages.add(
CustomAndroidUsage(
name = configuration.name,
attributes = configuration.attributes,
dependencies = setOf(newDependency)
)
)
}
}
val newRootComponent = CustomRootComponent(rootComponent, newDependency)

extensions.getByType(PublishingExtension::class.java).apply {
val kotlinMultiplatform = publications
Expand Down Expand Up @@ -433,4 +422,41 @@ private fun Project.publishAndroidxReference(target: KotlinAndroidTarget) {
}
}
}
}
}

/**
* K/Native stores the dependencies in klib manifest and tries to resolve them during compilation.
* Since we use project dependency - implementation(project(...)), the klib manifest will reference
* our groupId (for example org.jetbrains.compose.collection-internal instead of androidx.collection).
* Therefore, the dependency can't be resolved since we don't publish libs for some k/native targets.
*
* To fix that, we need to make sure
* that the project dependency is substituted by a module dependency (from androidx).
* We do this here. It should be called only for appropriate k/native targets.
*
* For available androidx targets see:
* https://maven.google.com/web/index.html#androidx.annotation
* https://maven.google.com/web/index.html#androidx.collection
*/
private fun KotlinNativeTarget.substituteForOelPublishedDependencies() {
val comp = compilations.getByName("main")
val androidAnnotationVersion = project.findProperty("artifactRedirecting.androidx.annotation.version")!!
val androidCollectionVersion = project.findProperty("artifactRedirecting.androidx.collection.version")!!
listOf(
comp.configurations.compileDependencyConfiguration,
comp.configurations.runtimeDependencyConfiguration,
comp.configurations.apiConfiguration,
comp.configurations.implementationConfiguration,
comp.configurations.runtimeOnlyConfiguration,
comp.configurations.compileOnlyConfiguration,
).forEach {
it?.resolutionStrategy {
it.dependencySubstitution {
it.substitute(it.project(":annotation:annotation"))
.using(it.module("androidx.annotation:annotation:$androidAnnotationVersion"))
it.substitute(it.project(":collection:collection"))
.using(it.module("androidx.collection:collection:$androidCollectionVersion"))
}
}
}
}
Loading

0 comments on commit 2458969

Please sign in to comment.