From c86df6118324aa93fbc715c179ea6ceb704d72df Mon Sep 17 00:00:00 2001 From: Konstantin Date: Tue, 25 Jun 2024 10:57:03 +0200 Subject: [PATCH] [gradle] Add a customization for resources directories. (#5016) With the new API it is possible to customize compose resources directories. For example: ```kotlin abstract class GenerateAndroidRes : DefaultTask() { @get:Inject abstract val layout: ProjectLayout @get:OutputDirectory val outputDir = layout.buildDirectory.dir("generatedAndroidResources") @TaskAction fun run() {...} } compose.resources { customDirectory( sourceSetName = "androidMain", directoryProvider = tasks.register("generateAndroidRes").map { it.outputDir.get() } ) customDirectory( sourceSetName = "desktopMain", directoryProvider = provider { layout.projectDirectory.dir("desktopResources") } ) } ``` Fixes https://github.com/JetBrains/compose-multiplatform/issues/4718 Fixes https://github.com/JetBrains/compose-multiplatform/issues/4564 ## Release Notes ### Features - Resources - Add a customization for resources directories. Now it is possible to use e.g downloaded resources. --- .../resources/ComposeResourcesGeneration.kt | 2 +- .../resources/PrepareComposeResources.kt | 27 ++++++++++++------ .../compose/resources/ResourcesDSL.kt | 13 +++++++++ .../misc/commonResources/build.gradle.kts | 28 +++++++++++++++++++ .../composeResources/values/strings.xml | 3 -- 5 files changed, 60 insertions(+), 13 deletions(-) delete mode 100644 gradle-plugins/compose/src/test/test-projects/misc/commonResources/src/androidMain/composeResources/values/strings.xml diff --git a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/resources/ComposeResourcesGeneration.kt b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/resources/ComposeResourcesGeneration.kt index 8c28fa4f04..33cf4fa8ce 100644 --- a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/resources/ComposeResourcesGeneration.kt +++ b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/resources/ComposeResourcesGeneration.kt @@ -54,7 +54,7 @@ internal fun Project.configureComposeResourcesGeneration( } //common resources must be converted (XML -> CVR) - val preparedResourcesTask = registerPrepareComposeResourcesTask(sourceSet) + val preparedResourcesTask = registerPrepareComposeResourcesTask(sourceSet, config) val preparedResources = preparedResourcesTask.flatMap { it.outputDir.asFile } configureResourceAccessorsGeneration( sourceSet, diff --git a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/resources/PrepareComposeResources.kt b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/resources/PrepareComposeResources.kt index 11131350fe..0d447b6a3c 100644 --- a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/resources/PrepareComposeResources.kt +++ b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/resources/PrepareComposeResources.kt @@ -1,6 +1,7 @@ package org.jetbrains.compose.resources import org.gradle.api.Project +import org.gradle.api.file.Directory import org.gradle.api.file.DirectoryProperty import org.gradle.api.file.FileSystemOperations import org.gradle.api.file.FileTree @@ -25,11 +26,19 @@ import javax.inject.Inject import javax.xml.parsers.DocumentBuilderFactory internal fun Project.registerPrepareComposeResourcesTask( - sourceSet: KotlinSourceSet + sourceSet: KotlinSourceSet, + config: Provider ): TaskProvider { - val resDir = "${sourceSet.name}/$COMPOSE_RESOURCES_DIR" - val userComposeResourcesDir = project.projectDir.resolve("src/$resDir") - val preparedComposeResourcesDir = layout.buildDirectory.dir("$RES_GEN_DIR/preparedResources/$resDir") + val userComposeResourcesDir: Provider = config.flatMap { ext -> + ext.customResourceDirectories[sourceSet.name] ?: provider { + //default path + layout.projectDirectory.dir("src/${sourceSet.name}/$COMPOSE_RESOURCES_DIR") + } + } + + val preparedComposeResourcesDir = layout.buildDirectory.dir( + "$RES_GEN_DIR/preparedResources/${sourceSet.name}/$COMPOSE_RESOURCES_DIR" + ) val convertXmlValueResources = tasks.register( "convertXmlValueResourcesFor${sourceSet.name.uppercaseFirstChar()}", @@ -61,11 +70,11 @@ internal fun Project.registerPrepareComposeResourcesTask( } internal fun Project.getPreparedComposeResourcesDir(sourceSet: KotlinSourceSet): Provider = tasks - .named( - getPrepareComposeResourcesTaskName(sourceSet), - PrepareComposeResourcesTask::class.java - ) - .flatMap { it.outputDir.asFile } + .named( + getPrepareComposeResourcesTaskName(sourceSet), + PrepareComposeResourcesTask::class.java + ) + .flatMap { it.outputDir.asFile } private fun getPrepareComposeResourcesTaskName(sourceSet: KotlinSourceSet) = "prepareComposeResourcesTaskFor${sourceSet.name.uppercaseFirstChar()}" diff --git a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/resources/ResourcesDSL.kt b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/resources/ResourcesDSL.kt index 17abaf96ff..88406e1125 100644 --- a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/resources/ResourcesDSL.kt +++ b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/resources/ResourcesDSL.kt @@ -1,6 +1,7 @@ package org.jetbrains.compose.resources import org.gradle.api.Project +import org.gradle.api.file.Directory import org.gradle.api.provider.Provider import java.io.File @@ -36,6 +37,18 @@ abstract class ResourcesExtension { * - `never`: Never generate the Res class. */ var generateResClass: ResourceClassGeneration = auto + + internal val customResourceDirectories: MutableMap> = mutableMapOf() + + /** + * Associates a custom resource directory with a specific source set. + * + * @param sourceSetName the name of the source set to associate the custom resource directory with + * @param directoryProvider the provider that provides the custom directory + */ + fun customDirectory(sourceSetName: String, directoryProvider: Provider) { + customResourceDirectories[sourceSetName] = directoryProvider + } } internal fun Provider.getResourcePackage(project: Project) = map { config -> diff --git a/gradle-plugins/compose/src/test/test-projects/misc/commonResources/build.gradle.kts b/gradle-plugins/compose/src/test/test-projects/misc/commonResources/build.gradle.kts index beda4225bf..aeafd38a84 100644 --- a/gradle-plugins/compose/src/test/test-projects/misc/commonResources/build.gradle.kts +++ b/gradle-plugins/compose/src/test/test-projects/misc/commonResources/build.gradle.kts @@ -62,3 +62,31 @@ android { targetCompatibility = JavaVersion.VERSION_11 } } + +abstract class GenerateAndroidRes : DefaultTask() { + @get:Inject + abstract val layout: ProjectLayout + + @get:OutputDirectory + val outputDir = layout.buildDirectory.dir("generatedAndroidResources") + + @TaskAction + fun run() { + val dir = outputDir.get().asFile + dir.deleteRecursively() + File(dir, "values/strings.xml").apply { + parentFile.mkdirs() + writeText( + """ + + Android string + + """.trimIndent() + ) + } + } +} +compose.resources.customDirectory( + sourceSetName = "androidMain", + directoryProvider = tasks.register("generateAndroidRes").map { it.outputDir.get() } +) diff --git a/gradle-plugins/compose/src/test/test-projects/misc/commonResources/src/androidMain/composeResources/values/strings.xml b/gradle-plugins/compose/src/test/test-projects/misc/commonResources/src/androidMain/composeResources/values/strings.xml deleted file mode 100644 index 4855fd3e03..0000000000 --- a/gradle-plugins/compose/src/test/test-projects/misc/commonResources/src/androidMain/composeResources/values/strings.xml +++ /dev/null @@ -1,3 +0,0 @@ - - Android string - \ No newline at end of file