From 48b64fdece44931b6e7c07cbf3773d6977aa2fd3 Mon Sep 17 00:00:00 2001 From: Konstantin Date: Wed, 14 Aug 2024 14:24:44 +0200 Subject: [PATCH] [gradle] Restore correct android assets registration after AGP fix. (#5118) After the fix there will be a correct configuration cache usage. Fixes https://youtrack.jetbrains.com/issue/CMP-5674 ## Release Notes ### Fixes - Gradle Plugin - _(prerelease fix)_ Fix broken configuration cache due Android Studio + AGP issues. Now Android Studio previews require latest AGP versions (8.5.2, 8.6.0-rc01, 8.7.0-alpha04): https://issuetracker.google.com/issues/348208777 --- .../compose/resources/AndroidResources.kt | 90 ++++++++++++------- .../compose/resources/ComposeResources.kt | 12 +-- 2 files changed, 58 insertions(+), 44 deletions(-) diff --git a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/resources/AndroidResources.kt b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/resources/AndroidResources.kt index 6bec880943..5b66539d01 100644 --- a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/resources/AndroidResources.kt +++ b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/resources/AndroidResources.kt @@ -4,15 +4,23 @@ import com.android.build.api.variant.AndroidComponentsExtension import com.android.build.api.variant.Variant import com.android.build.gradle.internal.lint.AndroidLintAnalysisTask import com.android.build.gradle.internal.lint.LintModelWriterTask +import org.gradle.api.DefaultTask import org.gradle.api.Project +import org.gradle.api.file.DirectoryProperty import org.gradle.api.file.FileCollection -import org.gradle.api.tasks.Copy -import org.jetbrains.compose.internal.utils.dir +import org.gradle.api.file.FileSystemOperations +import org.gradle.api.provider.Property +import org.gradle.api.tasks.IgnoreEmptyDirectories +import org.gradle.api.tasks.InputFiles +import org.gradle.api.tasks.OutputDirectory +import org.gradle.api.tasks.TaskAction +import org.jetbrains.compose.internal.utils.registerTask import org.jetbrains.compose.internal.utils.uppercaseFirstChar import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinAndroidTarget +import javax.inject.Inject -internal fun Project.getAndroidVariantComposeResources( +private fun Project.getAndroidVariantComposeResources( kotlinExtension: KotlinMultiplatformExtension, variant: Variant ): FileCollection = project.files({ @@ -27,46 +35,27 @@ internal fun Project.getAndroidVariantComposeResources( } }) -internal fun Project.getKgpAndroidVariantComposeResources( - variant: Variant -): FileCollection = project.files({ - val taskName = "${variant.name}AssetsCopyForAGP" - if (tasks.names.contains(taskName)) tasks.named(taskName).map { it.outputs.files } - else files() -}) - -internal fun Project.configureAndroidComposeResources( - getVariantComposeResources: (Variant) -> FileCollection -) { +internal fun Project.configureAndroidComposeResources() { //copy all compose resources to android assets val androidComponents = project.extensions.findByType(AndroidComponentsExtension::class.java) ?: return + val kotlinExtension = project.extensions.findByType(KotlinMultiplatformExtension::class.java) ?: return androidComponents.onVariants { variant -> val camelVariantName = variant.name.uppercaseFirstChar() - val variantAssets = getVariantComposeResources(variant) - val variantAssetsDir = layout.buildDirectory.dir(RES_GEN_DIR).dir(variant.name + "AndroidAssets") + val variantAssets = getAndroidVariantComposeResources(kotlinExtension, variant) - val copyVariantAssets = tasks.register( - "copy${camelVariantName}ComposeResourcesToAndroidAssets", - Copy::class.java - ) { task -> - task.from(variantAssets) - task.into(variantAssetsDir) + val copyVariantAssets = registerTask( + "copy${camelVariantName}ComposeResourcesToAndroidAssets" + ) { + from.set(variantAssets) } - //https://issuetracker.google.com/348208777 - val staticDir = variantAssetsDir.get().asFile - staticDir.mkdirs() - variant.sources.assets?.addStaticSourceDirectory(staticDir.path) - - val agpTaskNames = listOf( - //fix agp task dependencies for build and allTests tasks - "merge${camelVariantName}Assets", - "package${camelVariantName}Assets", - //fix agp task dependencies for AndroidStudio preview - "compile${camelVariantName}Sources", + variant.sources.assets?.addGeneratedSourceDirectory( + copyVariantAssets, + CopyResourcesToAndroidAssetsTask::outputDirectory ) tasks.configureEach { task -> - if (task.name in agpTaskNames) { + //fix agp task dependencies for AndroidStudio preview + if (task.name == "compile${camelVariantName}Sources") { task.dependsOn(copyVariantAssets) } //fix linter task dependencies for `build` task @@ -77,6 +66,28 @@ internal fun Project.configureAndroidComposeResources( } } +//Copy task doesn't work with 'variant.sources?.assets?.addGeneratedSourceDirectory' API +internal abstract class CopyResourcesToAndroidAssetsTask : DefaultTask() { + @get:Inject + abstract val fileSystem: FileSystemOperations + + @get:InputFiles + @get:IgnoreEmptyDirectories + abstract val from: Property + + @get:OutputDirectory + abstract val outputDirectory: DirectoryProperty + + @TaskAction + fun action() { + fileSystem.copy { + it.includeEmptyDirs = false + it.from(from) + it.into(outputDirectory) + } + } +} + /* There is a dirty fix for the problem: @@ -93,4 +104,15 @@ internal fun Project.fixAndroidLintTaskDependencies() { }.configureEach { it.mustRunAfter(tasks.withType(GenerateResourceAccessorsTask::class.java)) } +} + +internal fun Project.fixKgpAndroidPreviewTaskDependencies() { + val androidComponents = project.extensions.findByType(AndroidComponentsExtension::class.java) ?: return + androidComponents.onVariants { variant -> + tasks.configureEach { task -> + if (task.name == "compile${variant.name.uppercaseFirstChar()}Sources") { + task.dependsOn("${variant.name}AssetsCopyForAGP") + } + } + } } \ No newline at end of file diff --git a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/resources/ComposeResources.kt b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/resources/ComposeResources.kt index 2a85d3e2bd..13255a7e06 100644 --- a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/resources/ComposeResources.kt +++ b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/resources/ComposeResources.kt @@ -40,13 +40,7 @@ private fun Project.onKgpApplied(config: Provider, kgp: Kotl if (kmpResourcesAreAvailable) { configureKmpResources(kotlinExtension, extraProperties.get(KMP_RES_EXT)!!, config) onAgpApplied { - //workaround to fix AndroidStudio preview works with compose resources: - //it copies android assets and mark it as a static assets dir - //yes, the same resources will be registered in AGP twice: from KGP and here as static dirs - //but it works fine and there are no problems during merge android assets - configureAndroidComposeResources { variant -> - getKgpAndroidVariantComposeResources(variant) - } + fixKgpAndroidPreviewTaskDependencies() fixAndroidLintTaskDependencies() } } else { @@ -69,9 +63,7 @@ private fun Project.onKgpApplied(config: Provider, kgp: Kotl configureComposeResources(kotlinExtension, commonMain, config) onAgpApplied { - configureAndroidComposeResources { variant -> - getAndroidVariantComposeResources(kotlinExtension, variant) - } + configureAndroidComposeResources() fixAndroidLintTaskDependencies() } }