@ -1,8 +1,10 @@
package org.jetbrains.compose.resources
import com.android.build.api.dsl.KotlinMultiplatformAndroidTarget
import com.android.build.api.variant.AndroidComponentsExtension
import com.android.build.api.variant.Component
import com.android.build.api.variant.HasAndroidTest
import com.android.build.api.variant.KotlinMultiplatformAndroidComponentsExtension
import com.android.build.api.variant.Sources
import com.android.build.gradle.internal.lint.AndroidLintAnalysisTask
import com.android.build.gradle.internal.lint.LintModelWriterTask
import org.gradle.api.DefaultTask
@ -25,29 +27,122 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinAndroidTarget
import java.io.File
import javax.inject.Inject
internal fun Project . configureAndroidComposeResources ( moduleResourceDir : Provider < File > ? = null ) {
//copy all compose resources to android assets
val androidComponents = project . extensions . findByType ( AndroidComponentsExtension :: class . java ) ?: return
//copy all compose resources to android assets
internal fun Project . configureAndroidComposeResources (
agpPluginId : String ,
moduleResourceDir : Provider < File > ? = null
) {
val kotlinExtension = extensions . findByType ( KotlinMultiplatformExtension :: class . java ) ?: return
if ( agpPluginId != AGP _KMP _LIB _ID ) {
extensions . findByType ( AndroidComponentsExtension :: class . java ) ?. let { androidComponents ->
configureAndroidComposeResources ( kotlinExtension , androidComponents , moduleResourceDir )
}
} else {
@Suppress ( " UnstableApiUsage " )
extensions . findByType ( KotlinMultiplatformAndroidComponentsExtension :: class . java ) ?. let { androidComponents ->
configureAndroidComposeResources ( kotlinExtension , androidComponents , moduleResourceDir )
}
}
}
private fun Project . configureAndroidComposeResources (
kotlinExtension : KotlinMultiplatformExtension ,
androidComponents : AndroidComponentsExtension < * , * , * > ,
moduleResourceDir : Provider < File > ?
) {
logger . info ( " Configure compose resources with AndroidComponentsExtension " )
androidComponents . onVariants { variant ->
configureGeneratedAndroidComponentAssets ( variant , moduleResourceDir )
val componentAssets = getAndroidComponentComposeResources ( kotlinExtension , variant . name )
configureGeneratedAndroidComponentAssets (
variant . name ,
variant . sources ,
componentAssets ,
moduleResourceDir
)
if ( variant is HasAndroidTest ) {
variant . androidTest ?. let { androidTest ->
configureGeneratedAndroidComponentAssets ( androidTest , moduleResourceDir )
val androidTestAssets = getAndroidComponentComposeResources ( kotlinExtension , androidTest . name )
configureGeneratedAndroidComponentAssets (
androidTest . name ,
androidTest . sources ,
androidTestAssets ,
moduleResourceDir
)
}
}
}
}
private fun Project . getAndroidComponentComposeResources (
kotlinExtension : KotlinMultiplatformExtension ,
componentName : String
) : FileCollection = project . files ( {
kotlinExtension . targets . withType ( KotlinAndroidTarget :: class . java ) . flatMap { androidTarget ->
androidTarget . compilations . flatMap { compilation ->
if ( compilation . androidVariant . name == componentName ) {
compilation . allKotlinSourceSets . map { kotlinSourceSet ->
getPreparedComposeResourcesDir ( kotlinSourceSet )
}
} else emptyList ( )
}
}
} )
@Suppress ( " UnstableApiUsage " )
private fun Project . configureAndroidComposeResources (
kotlinExtension : KotlinMultiplatformExtension ,
androidComponents : KotlinMultiplatformAndroidComponentsExtension ,
moduleResourceDir : Provider < File > ?
) {
logger . info ( " Configure compose resources with KotlinMultiplatformAndroidComponentsExtension " )
androidComponents . onVariant { variant ->
val variantAssets = getAndroidKmpComponentComposeResources ( kotlinExtension , variant . name )
configureGeneratedAndroidComponentAssets (
variant . name ,
variant . sources ,
variantAssets ,
moduleResourceDir
)
variant . androidTest ?. let { androidTest ->
val androidTestAssets = getAndroidKmpComponentComposeResources ( kotlinExtension , androidTest . name )
configureGeneratedAndroidComponentAssets (
androidTest . name ,
androidTest . sources ,
androidTestAssets ,
moduleResourceDir
)
}
}
}
@Suppress ( " UnstableApiUsage " )
private fun Project . getAndroidKmpComponentComposeResources (
kotlinExtension : KotlinMultiplatformExtension ,
componentName : String
) : FileCollection = project . files ( {
kotlinExtension . targets . withType ( KotlinMultiplatformAndroidTarget :: class . java ) . flatMap { androidTarget ->
androidTarget . compilations . flatMap { compilation ->
if ( compilation . componentName == componentName ) {
compilation . allKotlinSourceSets . map { kotlinSourceSet ->
getPreparedComposeResourcesDir ( kotlinSourceSet )
}
} else emptyList ( )
}
}
} )
private fun Project . configureGeneratedAndroidComponentAssets (
component : Component ,
componentName : String ,
componentSources : Sources ,
componentAssets : FileCollection ,
moduleResourceDir : Provider < File > ?
) {
val kotlinExtension = project . extensions . findByType ( KotlinMultiplatformExtension :: class . java ) ?: return
val camelComponentName = component . name . uppercaseFirstChar ( )
val componentAssets = getAndroidComponentComposeResources ( kotlinExtension , component . name )
logger . info ( " Configure ${component.name} resources for 'android' target " )
logger . info ( " Configure $componentName resources for 'android' target " )
val camelComponentName = componentName . uppercaseFirstChar ( )
val copyComponentAssets = registerTask < CopyResourcesToAndroidAssetsTask > (
" copy ${camelComponentName} ComposeResourcesToAndroidAssets "
) {
@ -55,7 +150,7 @@ private fun Project.configureGeneratedAndroidComponentAssets(
moduleResourceDir ?. let { relativeResourcePlacement . set ( it ) }
}
component . s ources. assets ?. addGeneratedSourceDirectory (
componentS ources . assets ?. addGeneratedSourceDirectory (
copyComponentAssets ,
CopyResourcesToAndroidAssetsTask :: outputDirectory
)
@ -71,21 +166,6 @@ private fun Project.configureGeneratedAndroidComponentAssets(
}
}
private fun Project . getAndroidComponentComposeResources (
kotlinExtension : KotlinMultiplatformExtension ,
componentName : String
) : FileCollection = project . files ( {
kotlinExtension . targets . withType ( KotlinAndroidTarget :: class . java ) . flatMap { androidTarget ->
androidTarget . compilations . flatMap { compilation ->
if ( compilation . androidVariant . name == componentName ) {
compilation . allKotlinSourceSets . map { kotlinSourceSet ->
getPreparedComposeResourcesDir ( kotlinSourceSet )
}
} else emptyList ( )
}
}
} )
//Copy task doesn't work with 'variant.sources?.assets?.addGeneratedSourceDirectory' API
internal abstract class CopyResourcesToAndroidAssetsTask : DefaultTask ( ) {
@get : Inject