Browse Source

[gradle] Add a flag to disable multimodule resources. (#4771)

The Compose Multiplatform Resources with the mulimodule.publication
support is a new feature and may have some not found problems. The PR
introduces a gradle property to switch back to the previous behavior:
`org.jetbrains.compose.resources.multimodule.disable=true`

## Testing
After update to Kotlin 2.0.0 and CMP 1.6.10 all projects will be
switched to the new logic with the multimodule support.
Gradle info output should contain a message:
```
Configure KMP resources
```

If the new feature breaks user's projects they may add
`org.jetbrains.compose.resources.multimodule.disable=true` to the
`gradle.properties` to disable it. After that Gradle info output will
contain:
```
Configure compose resources
```

## Release Notes
### Resources
To disable the Compose Resources publication and the multimodule support
in cases of problems add
`org.jetbrains.compose.resources.multimodule.disable=true` to the root
`gradle.properties`.

(cherry picked from commit bf6142ddf5)
shish/stableprop
Konstantin 7 months ago committed by Konstantin Tskhovrebov
parent
commit
6f07e8c6a3
  1. 5
      gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/desktop/application/internal/ComposeProjectProperties.kt
  2. 6
      gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/resources/ComposeResources.kt
  3. 45
      gradle-plugins/compose/src/test/kotlin/org/jetbrains/compose/test/tests/integration/ResourcesTest.kt
  4. 1
      gradle-plugins/compose/src/test/test-projects/misc/kmpResourcePublication/appModule/build.gradle.kts
  5. 1
      gradle-plugins/compose/src/test/test-projects/misc/kmpResourcePublication/build.gradle.kts
  6. 1
      gradle-plugins/compose/src/test/test-projects/misc/kmpResourcePublication/cmplib/build.gradle.kts
  7. 1
      gradle-plugins/compose/src/test/test-projects/misc/kmpResourcePublication/featureModule/build.gradle.kts
  8. 1
      gradle-plugins/compose/src/test/test-projects/misc/kmpResourcePublication/settings.gradle.kts

5
gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/desktop/application/internal/ComposeProjectProperties.kt

@ -22,7 +22,7 @@ internal object ComposeProperties {
internal const val MAC_NOTARIZATION_PASSWORD = "compose.desktop.mac.notarization.password" internal const val MAC_NOTARIZATION_PASSWORD = "compose.desktop.mac.notarization.password"
internal const val MAC_NOTARIZATION_TEAM_ID_PROVIDER = "compose.desktop.mac.notarization.teamID" internal const val MAC_NOTARIZATION_TEAM_ID_PROVIDER = "compose.desktop.mac.notarization.teamID"
internal const val CHECK_JDK_VENDOR = "compose.desktop.packaging.checkJdkVendor" internal const val CHECK_JDK_VENDOR = "compose.desktop.packaging.checkJdkVendor"
internal const val ALWAYS_GENERATE_RESOURCE_ACCESSORS = "compose.resources.always.generate.accessors" internal const val DISABLE_MULTIMODULE_RESOURCES = "org.jetbrains.compose.resources.multimodule.disable"
internal const val SYNC_RESOURCES_PROPERTY = "compose.ios.resources.sync" internal const val SYNC_RESOURCES_PROPERTY = "compose.ios.resources.sync"
fun isVerbose(providers: ProviderFactory): Provider<Boolean> = fun isVerbose(providers: ProviderFactory): Provider<Boolean> =
@ -55,6 +55,9 @@ internal object ComposeProperties {
fun checkJdkVendor(providers: ProviderFactory): Provider<Boolean> = fun checkJdkVendor(providers: ProviderFactory): Provider<Boolean> =
providers.valueOrNull(CHECK_JDK_VENDOR).toBooleanProvider(true) providers.valueOrNull(CHECK_JDK_VENDOR).toBooleanProvider(true)
fun disableMultimoduleResources(providers: ProviderFactory): Provider<Boolean> =
providers.valueOrNull(DISABLE_MULTIMODULE_RESOURCES).toBooleanProvider(false)
//providers.valueOrNull works only with root gradle.properties //providers.valueOrNull works only with root gradle.properties
fun dontSyncResources(project: Project): Provider<Boolean> = project.provider { fun dontSyncResources(project: Project): Provider<Boolean> = project.provider {
project.findProperty(SYNC_RESOURCES_PROPERTY)?.toString().equals("false", true) project.findProperty(SYNC_RESOURCES_PROPERTY)?.toString().equals("false", true)

6
gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/resources/ComposeResources.kt

@ -9,6 +9,7 @@ import org.gradle.api.tasks.SourceSet
import org.gradle.api.tasks.TaskProvider import org.gradle.api.tasks.TaskProvider
import org.gradle.util.GradleVersion import org.gradle.util.GradleVersion
import org.jetbrains.compose.ComposePlugin import org.jetbrains.compose.ComposePlugin
import org.jetbrains.compose.desktop.application.internal.ComposeProperties
import org.jetbrains.compose.internal.KOTLIN_JVM_PLUGIN_ID import org.jetbrains.compose.internal.KOTLIN_JVM_PLUGIN_ID
import org.jetbrains.compose.internal.KOTLIN_MPP_PLUGIN_ID import org.jetbrains.compose.internal.KOTLIN_MPP_PLUGIN_ID
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
@ -41,11 +42,13 @@ private fun Project.onKgpApplied(config: Provider<ResourcesExtension>, kgp: Kotl
val hasKmpResources = extraProperties.has(KMP_RES_EXT) val hasKmpResources = extraProperties.has(KMP_RES_EXT)
val currentGradleVersion = GradleVersion.current() val currentGradleVersion = GradleVersion.current()
val minGradleVersion = GradleVersion.version(MIN_GRADLE_VERSION_FOR_KMP_RESOURCES) val minGradleVersion = GradleVersion.version(MIN_GRADLE_VERSION_FOR_KMP_RESOURCES)
val kmpResourcesAreAvailable = hasKmpResources && currentGradleVersion >= minGradleVersion val disableMultimoduleResources = ComposeProperties.disableMultimoduleResources(providers).get()
val kmpResourcesAreAvailable = !disableMultimoduleResources && hasKmpResources && currentGradleVersion >= minGradleVersion
if (kmpResourcesAreAvailable) { if (kmpResourcesAreAvailable) {
configureKmpResources(kotlinExtension, extraProperties.get(KMP_RES_EXT)!!, config) configureKmpResources(kotlinExtension, extraProperties.get(KMP_RES_EXT)!!, config)
} else { } else {
if (!disableMultimoduleResources) {
if (!hasKmpResources) logger.info( if (!hasKmpResources) logger.info(
""" """
Compose resources publication requires Kotlin Gradle Plugin >= 2.0 Compose resources publication requires Kotlin Gradle Plugin >= 2.0
@ -58,6 +61,7 @@ private fun Project.onKgpApplied(config: Provider<ResourcesExtension>, kgp: Kotl
Current Gradle is ${currentGradleVersion.version} Current Gradle is ${currentGradleVersion.version}
""".trimIndent() """.trimIndent()
) )
}
val commonMain = KotlinSourceSet.COMMON_MAIN_SOURCE_SET_NAME val commonMain = KotlinSourceSet.COMMON_MAIN_SOURCE_SET_NAME
configureComposeResources(kotlinExtension, commonMain, config) configureComposeResources(kotlinExtension, commonMain, config)

45
gradle-plugins/compose/src/test/kotlin/org/jetbrains/compose/test/tests/integration/ResourcesTest.kt

@ -1,6 +1,7 @@
package org.jetbrains.compose.test.tests.integration package org.jetbrains.compose.test.tests.integration
import org.gradle.util.GradleVersion import org.gradle.util.GradleVersion
import org.jetbrains.compose.desktop.application.internal.ComposeProperties
import org.jetbrains.compose.internal.utils.* import org.jetbrains.compose.internal.utils.*
import org.jetbrains.compose.resources.XmlValuesConverterTask import org.jetbrains.compose.resources.XmlValuesConverterTask
import org.jetbrains.compose.test.utils.* import org.jetbrains.compose.test.utils.*
@ -158,42 +159,50 @@ class ResourcesTest : GradlePluginTestBase() {
check.logContains("${testXml.name} is not valid. Check the file content.") check.logContains("${testXml.name} is not valid. Check the file content.")
} }
testXml.writeText(""" testXml.writeText(
"""
<resources> <resources>
<aaa name="v">aaa</aaa> <aaa name="v">aaa</aaa>
</resources> </resources>
""".trimIndent()) """.trimIndent()
)
gradleFailure("prepareKotlinIdeaImport").checks { gradleFailure("prepareKotlinIdeaImport").checks {
check.logContains("${testXml.name} is not valid. Unknown resource type: 'aaa'.") check.logContains("${testXml.name} is not valid. Unknown resource type: 'aaa'.")
} }
testXml.writeText(""" testXml.writeText(
"""
<resources> <resources>
<drawable name="v">aaa</drawable> <drawable name="v">aaa</drawable>
</resources> </resources>
""".trimIndent()) """.trimIndent()
)
gradleFailure("prepareKotlinIdeaImport").checks { gradleFailure("prepareKotlinIdeaImport").checks {
check.logContains("${testXml.name} is not valid. Unknown string resource type: 'drawable'.") check.logContains("${testXml.name} is not valid. Unknown string resource type: 'drawable'.")
} }
testXml.writeText(""" testXml.writeText(
"""
<resources> <resources>
<string name="v1">aaa</string> <string name="v1">aaa</string>
<string name="v2">aaa</string> <string name="v2">aaa</string>
<string name="v3">aaa</string> <string name="v3">aaa</string>
<string name="v1">aaa</string> <string name="v1">aaa</string>
</resources> </resources>
""".trimIndent()) """.trimIndent()
)
gradleFailure("prepareKotlinIdeaImport").checks { gradleFailure("prepareKotlinIdeaImport").checks {
check.logContains("${testXml.name} is not valid. Duplicated key 'v1'.") check.logContains("${testXml.name} is not valid. Duplicated key 'v1'.")
} }
testXml.writeText(""" testXml.writeText(
"""
<resources> <resources>
<string name="v1">aaa</string> <string name="v1">aaa</string>
<string foo="v2">aaa</string> <string foo="v2">aaa</string>
</resources> </resources>
""".trimIndent()) """.trimIndent()
)
gradleFailure("prepareKotlinIdeaImport").checks { gradleFailure("prepareKotlinIdeaImport").checks {
check.logContains("${testXml.name} is not valid. Attribute 'name' not found.") check.logContains("${testXml.name} is not valid. Attribute 'name' not found.")
} }
@ -219,7 +228,7 @@ class ResourcesTest : GradlePluginTestBase() {
@Test @Test
fun testMultiModuleResources() { fun testMultiModuleResources() {
val environment = defaultTestEnvironment.copy( val environment = defaultTestEnvironment.copy(
kotlinVersion = "2.0.0-Beta5" kotlinVersion = "2.0.0-RC2"
) )
with( with(
testProject("misc/kmpResourcePublication", environment) testProject("misc/kmpResourcePublication", environment)
@ -232,6 +241,8 @@ class ResourcesTest : GradlePluginTestBase() {
} }
gradle(":cmplib:publishAllPublicationsToMavenRepository").checks { gradle(":cmplib:publishAllPublicationsToMavenRepository").checks {
check.logContains("Configure KMP resources")
val resDir = file("cmplib/src/commonMain/composeResources") val resDir = file("cmplib/src/commonMain/composeResources")
val resourcesFiles = resDir.walkTopDown() val resourcesFiles = resDir.walkTopDown()
.filter { !it.isDirectory && !it.isHidden } .filter { !it.isDirectory && !it.isHidden }
@ -317,6 +328,22 @@ class ResourcesTest : GradlePluginTestBase() {
} }
} }
@Test
fun testDisableMultimoduleResourcesWithNewKotlin() {
val environment = defaultTestEnvironment.copy(
kotlinVersion = "2.0.0-RC2"
)
with(testProject("misc/kmpResourcePublication", environment)) {
file("gradle.properties").modify { content ->
content + "\n" + ComposeProperties.DISABLE_MULTIMODULE_RESOURCES + "=true"
}
gradle(":cmplib:build").checks {
check.logContains("Configure compose resources")
}
}
}
private fun checkResourcesZip(zipFile: File, resourcesFiles: Sequence<String>, subdir: String) { private fun checkResourcesZip(zipFile: File, resourcesFiles: Sequence<String>, subdir: String) {
assertTrue(zipFile.exists(), "File not found: " + zipFile.path) assertTrue(zipFile.exists(), "File not found: " + zipFile.path)
ZipFile(zipFile).use { zip -> ZipFile(zipFile).use { zip ->

1
gradle-plugins/compose/src/test/test-projects/misc/kmpResourcePublication/appModule/build.gradle.kts

@ -3,6 +3,7 @@ import org.jetbrains.compose.ExperimentalComposeLibrary
plugins { plugins {
id("org.jetbrains.compose") id("org.jetbrains.compose")
kotlin("multiplatform") kotlin("multiplatform")
kotlin("plugin.compose")
id("com.android.application") id("com.android.application")
} }

1
gradle-plugins/compose/src/test/test-projects/misc/kmpResourcePublication/build.gradle.kts

@ -1,6 +1,7 @@
plugins { plugins {
id("org.jetbrains.compose").apply(false) id("org.jetbrains.compose").apply(false)
kotlin("multiplatform").apply(false) kotlin("multiplatform").apply(false)
kotlin("plugin.compose").apply(false)
id("com.android.library").apply(false) id("com.android.library").apply(false)
id("com.android.application").apply(false) id("com.android.application").apply(false)
} }

1
gradle-plugins/compose/src/test/test-projects/misc/kmpResourcePublication/cmplib/build.gradle.kts

@ -1,6 +1,7 @@
plugins { plugins {
id("org.jetbrains.compose") id("org.jetbrains.compose")
kotlin("multiplatform") kotlin("multiplatform")
kotlin("plugin.compose")
id("maven-publish") id("maven-publish")
id("com.android.library") id("com.android.library")
} }

1
gradle-plugins/compose/src/test/test-projects/misc/kmpResourcePublication/featureModule/build.gradle.kts

@ -1,6 +1,7 @@
plugins { plugins {
id("org.jetbrains.compose") id("org.jetbrains.compose")
kotlin("multiplatform") kotlin("multiplatform")
kotlin("plugin.compose")
id("com.android.library") id("com.android.library")
} }

1
gradle-plugins/compose/src/test/test-projects/misc/kmpResourcePublication/settings.gradle.kts

@ -15,6 +15,7 @@ pluginManagement {
} }
plugins { plugins {
id("org.jetbrains.kotlin.multiplatform").version("KOTLIN_VERSION_PLACEHOLDER") id("org.jetbrains.kotlin.multiplatform").version("KOTLIN_VERSION_PLACEHOLDER")
id("org.jetbrains.kotlin.plugin.compose").version("KOTLIN_VERSION_PLACEHOLDER")
id("org.jetbrains.compose").version("COMPOSE_GRADLE_PLUGIN_VERSION_PLACEHOLDER") id("org.jetbrains.compose").version("COMPOSE_GRADLE_PLUGIN_VERSION_PLACEHOLDER")
id("com.android.library").version("AGP_VERSION_PLACEHOLDER") id("com.android.library").version("AGP_VERSION_PLACEHOLDER")
id("com.android.application").version("AGP_VERSION_PLACEHOLDER") id("com.android.application").version("AGP_VERSION_PLACEHOLDER")

Loading…
Cancel
Save