Browse Source

Register all hierarchical compose resources in android compilation (#4274)

pull/4284/head
Konstantin 5 months ago committed by GitHub
parent
commit
a0601c3024
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 1
      components/resources/demo/shared/src/androidMain/composeResources/files/platform-text.txt
  2. 49
      components/resources/demo/shared/src/commonMain/kotlin/org/jetbrains/compose/resources/demo/shared/FileRes.kt
  3. 1
      components/resources/demo/shared/src/desktopMain/composeResources/files/platform-text.txt
  4. 1
      components/resources/demo/shared/src/iosMain/composeResources/files/platform-text.txt
  5. 1
      components/resources/demo/shared/src/jsMain/composeResources/files/platform-text.txt
  6. 1
      components/resources/demo/shared/src/macosMain/composeResources/files/platform-text.txt
  7. 1
      components/resources/demo/shared/src/wasmJsMain/composeResources/files/platform-text.txt
  8. 1
      gradle-plugins/compose/build.gradle.kts
  9. 52
      gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/resources/AndroidTargetConfiguration.kt
  10. 112
      gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/resources/ResourcesGenerator.kt
  11. 158
      gradle-plugins/compose/src/test/kotlin/org/jetbrains/compose/test/tests/integration/ResourcesTest.kt
  12. 2
      gradle-plugins/compose/src/test/test-projects/misc/commonResources/build.gradle.kts
  13. 3
      gradle-plugins/compose/src/test/test-projects/misc/commonResources/gradle.properties

1
components/resources/demo/shared/src/androidMain/composeResources/files/platform-text.txt

@ -0,0 +1 @@
Android platform

49
components/resources/demo/shared/src/commonMain/kotlin/org/jetbrains/compose/resources/demo/shared/FileRes.kt

@ -1,22 +1,11 @@
package org.jetbrains.compose.resources.demo.shared package org.jetbrains.compose.resources.demo.shared
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.*
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.verticalScroll import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.CardDefaults import androidx.compose.material3.*
import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.*
import androidx.compose.material3.OutlinedCard
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import components.resources.demo.shared.generated.resources.Res import components.resources.demo.shared.generated.resources.Res
@ -59,5 +48,37 @@ fun FileRes(paddingValues: PaddingValues) {
Text(bytes.decodeToString()) Text(bytes.decodeToString())
""".trimIndent() """.trimIndent()
) )
Text(
modifier = Modifier.padding(16.dp),
text = "File: 'files/platform-text.txt'",
style = MaterialTheme.typography.titleLarge
)
OutlinedCard(
modifier = Modifier.padding(horizontal = 16.dp),
shape = RoundedCornerShape(4.dp),
colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.primaryContainer)
) {
var bytes by remember { mutableStateOf(ByteArray(0)) }
LaunchedEffect(Unit) {
bytes = Res.readBytes("files/platform-text.txt")
}
Text(
modifier = Modifier.padding(8.dp),
text = bytes.decodeToString(),
color = MaterialTheme.colorScheme.onPrimaryContainer
)
}
Text(
modifier = Modifier.padding(16.dp),
text = """
var bytes by remember {
mutableStateOf(ByteArray(0))
}
LaunchedEffect(Unit) {
bytes = Res.readFileBytes("files/platform-text.txt")
}
Text(bytes.decodeToString())
""".trimIndent()
)
} }
} }

1
components/resources/demo/shared/src/desktopMain/composeResources/files/platform-text.txt

@ -0,0 +1 @@
Desktop platform

1
components/resources/demo/shared/src/iosMain/composeResources/files/platform-text.txt

@ -0,0 +1 @@
iOS platform

1
components/resources/demo/shared/src/jsMain/composeResources/files/platform-text.txt

@ -0,0 +1 @@
JS platform

1
components/resources/demo/shared/src/macosMain/composeResources/files/platform-text.txt

@ -0,0 +1 @@
macOS platform

1
components/resources/demo/shared/src/wasmJsMain/composeResources/files/platform-text.txt

@ -0,0 +1 @@
WasmJS platform

1
gradle-plugins/compose/build.gradle.kts

@ -63,6 +63,7 @@ dependencies {
compileOnly(libs.plugin.android) compileOnly(libs.plugin.android)
compileOnly(libs.plugin.android.api) compileOnly(libs.plugin.android.api)
testImplementation(kotlin("test"))
testImplementation(gradleTestKit()) testImplementation(gradleTestKit())
testImplementation(kotlin("gradle-plugin-api")) testImplementation(kotlin("gradle-plugin-api"))

52
gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/resources/AndroidTargetConfiguration.kt

@ -1,52 +0,0 @@
package org.jetbrains.compose.resources
import com.android.build.api.variant.AndroidComponentsExtension
import com.android.build.gradle.BaseExtension
import org.gradle.api.Project
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.provider.Provider
import org.gradle.api.tasks.*
import org.jetbrains.compose.internal.utils.registerTask
import org.jetbrains.compose.internal.utils.uppercaseFirstChar
import java.io.File
internal fun Project.configureAndroidResources(
commonResourcesDir: Provider<File>,
androidFontsDir: Provider<File>,
onlyIfProvider: Provider<Boolean>
) {
val androidExtension = project.extensions.findByName("android") as? BaseExtension ?: return
val androidComponents = project.extensions.findByType(AndroidComponentsExtension::class.java) ?: return
val androidMainSourceSet = androidExtension.sourceSets.getByName(SourceSet.MAIN_SOURCE_SET_NAME)
androidMainSourceSet.resources.srcDir(commonResourcesDir)
androidMainSourceSet.assets.srcDir(androidFontsDir)
androidComponents.onVariants { variant ->
val copyFonts = registerTask<CopyAndroidAssetsTask>(
"copy${variant.name.uppercaseFirstChar()}FontsToAndroidAssets"
) {
includeEmptyDirs = false
from(commonResourcesDir)
include("**/font*/*")
onlyIf { onlyIfProvider.get() }
}
variant.sources?.assets?.addGeneratedSourceDirectory(
taskProvider = copyFonts,
wiredWith = CopyAndroidAssetsTask::outputDirectory
)
}
}
//https://github.com/JetBrains/compose-multiplatform/issues/4085
private abstract class CopyAndroidAssetsTask : Copy() {
@get:OutputDirectory
abstract val outputDirectory: DirectoryProperty
override fun getDestinationDir(): File =
outputDirectory.get().asFile
override fun setDestinationDir(destination: File) {
outputDirectory.set(destination)
}
}

112
gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/resources/ResourcesGenerator.kt

@ -1,18 +1,35 @@
package org.jetbrains.compose.resources package org.jetbrains.compose.resources
import com.android.build.api.variant.AndroidComponentsExtension
import com.android.build.gradle.BaseExtension
import com.android.build.gradle.internal.tasks.ProcessJavaResTask
import org.gradle.api.DefaultTask
import org.gradle.api.Project import org.gradle.api.Project
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.file.FileSystemOperations
import org.gradle.api.provider.Property
import org.gradle.api.provider.Provider import org.gradle.api.provider.Provider
import org.gradle.api.tasks.SourceSet import org.gradle.api.tasks.*
import org.jetbrains.compose.ComposePlugin import org.jetbrains.compose.ComposePlugin
import org.jetbrains.compose.desktop.application.internal.ComposeProperties 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.compose.internal.utils.*
import org.jetbrains.compose.internal.utils.dependsOn
import org.jetbrains.compose.internal.utils.registerTask
import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
import org.jetbrains.kotlin.gradle.dsl.KotlinProjectExtension import org.jetbrains.kotlin.gradle.dsl.KotlinProjectExtension
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinAndroidTarget
import org.jetbrains.kotlin.gradle.plugin.sources.android.androidSourceSetInfoOrNull
import org.jetbrains.kotlin.gradle.utils.ObservableSet
import java.io.File import java.io.File
import javax.inject.Inject
internal const val COMPOSE_RESOURCES_DIR = "composeResources" internal const val COMPOSE_RESOURCES_DIR = "composeResources"
private const val RES_GEN_DIR = "generated/compose/resourceGenerator" internal const val RES_GEN_DIR = "generated/compose/resourceGenerator"
private val androidPluginIds = listOf( private val androidPluginIds = listOf(
"com.android.application", "com.android.application",
"com.android.library" "com.android.library"
@ -20,27 +37,77 @@ private val androidPluginIds = listOf(
internal fun Project.configureComposeResources() { internal fun Project.configureComposeResources() {
plugins.withId(KOTLIN_MPP_PLUGIN_ID) { plugins.withId(KOTLIN_MPP_PLUGIN_ID) {
configureComposeResources(KotlinSourceSet.COMMON_MAIN_SOURCE_SET_NAME) val kotlinExtension = project.extensions.getByType(KotlinMultiplatformExtension::class.java)
configureComposeResources(kotlinExtension, KotlinSourceSet.COMMON_MAIN_SOURCE_SET_NAME)
//when applied AGP then configure android resources
androidPluginIds.forEach { pluginId ->
plugins.withId(pluginId) {
val androidExtension = project.extensions.getByType(BaseExtension::class.java)
configureAndroidComposeResources(kotlinExtension, androidExtension)
}
}
} }
plugins.withId(KOTLIN_JVM_PLUGIN_ID) { plugins.withId(KOTLIN_JVM_PLUGIN_ID) {
configureComposeResources(SourceSet.MAIN_SOURCE_SET_NAME) val kotlinExtension = project.extensions.getByType(KotlinProjectExtension::class.java)
configureComposeResources(kotlinExtension, SourceSet.MAIN_SOURCE_SET_NAME)
} }
} }
private fun Project.configureComposeResources(commonSourceSetName: String) { private fun Project.configureComposeResources(kotlinExtension: KotlinProjectExtension, commonSourceSetName: String) {
val kotlinExtension = project.extensions.getByType(KotlinProjectExtension::class.java)
kotlinExtension.sourceSets.all { sourceSet -> kotlinExtension.sourceSets.all { sourceSet ->
val sourceSetName = sourceSet.name val sourceSetName = sourceSet.name
val composeResourcesPath = project.projectDir.resolve("src/$sourceSetName/$COMPOSE_RESOURCES_DIR") val composeResourcesPath = project.projectDir.resolve("src/$sourceSetName/$COMPOSE_RESOURCES_DIR")
//To compose resources will be packed to a final artefact we need to mark them as resources
//sourceSet.resources works for all targets except ANDROID!
sourceSet.resources.srcDirs(composeResourcesPath) sourceSet.resources.srcDirs(composeResourcesPath)
if (sourceSetName == commonSourceSetName) { if (sourceSetName == commonSourceSetName) {
configureResourceGenerator(composeResourcesPath, sourceSet) configureResourceGenerator(composeResourcesPath, sourceSet)
} }
} }
} }
@OptIn(ExperimentalKotlinGradlePluginApi::class)
private fun Project.configureAndroidComposeResources(
kotlinExtension: KotlinMultiplatformExtension,
androidExtension: BaseExtension
) {
//mark all composeResources as Android resources
kotlinExtension.targets.matching { it is KotlinAndroidTarget }.all { androidTarget ->
androidTarget.compilations.all { compilation: KotlinCompilation<*> ->
compilation.defaultSourceSet.androidSourceSetInfoOrNull?.let { kotlinAndroidSourceSet ->
androidExtension.sourceSets
.matching { it.name == kotlinAndroidSourceSet.androidSourceSetName }
.all { androidSourceSet ->
(compilation.allKotlinSourceSets as ObservableSet<KotlinSourceSet>).forAll { kotlinSourceSet ->
androidSourceSet.resources.srcDir(
projectDir.resolve("src/${kotlinSourceSet.name}/$COMPOSE_RESOURCES_DIR")
)
}
}
}
}
}
//copy fonts from the compose resources dir to android assets
val androidComponents = project.extensions.findByType(AndroidComponentsExtension::class.java) ?: return
val commonResourcesDir = projectDir.resolve("src/${KotlinSourceSet.COMMON_MAIN_SOURCE_SET_NAME}/$COMPOSE_RESOURCES_DIR")
androidComponents.onVariants { variant ->
val copyFonts = registerTask<CopyAndroidFontsToAssetsTask>(
"copy${variant.name.uppercaseFirstChar()}FontsToAndroidAssets"
) {
from.set(commonResourcesDir)
}
variant.sources?.assets?.addGeneratedSourceDirectory(
taskProvider = copyFonts,
wiredWith = CopyAndroidFontsToAssetsTask::outputDirectory
)
}
}
private fun Project.configureResourceGenerator(commonComposeResourcesDir: File, commonSourceSet: KotlinSourceSet) { private fun Project.configureResourceGenerator(commonComposeResourcesDir: File, commonSourceSet: KotlinSourceSet) {
val commonComposeResources = provider { commonComposeResourcesDir }
val packageName = provider { val packageName = provider {
buildString { buildString {
val group = project.group.toString().lowercase().asUnderscoredIdentifier() val group = project.group.toString().lowercase().asUnderscoredIdentifier()
@ -73,7 +140,7 @@ private fun Project.configureResourceGenerator(commonComposeResourcesDir: File,
) { ) {
it.packageName.set(packageName) it.packageName.set(packageName)
it.shouldGenerateResClass.set(shouldGenerateResClass) it.shouldGenerateResClass.set(shouldGenerateResClass)
it.resDir.set(commonComposeResources) it.resDir.set(commonComposeResourcesDir)
it.codeDir.set(buildDir("$RES_GEN_DIR/kotlin")) it.codeDir.set(buildDir("$RES_GEN_DIR/kotlin"))
} }
@ -86,15 +153,26 @@ private fun Project.configureResourceGenerator(commonComposeResourcesDir: File,
it.dependsOn(genTask) it.dependsOn(genTask)
} }
} }
}
//when applied AGP then configure android resources //Copy task doesn't work with 'variant.sources?.assets?.addGeneratedSourceDirectory' API
androidPluginIds.forEach { pluginId -> internal abstract class CopyAndroidFontsToAssetsTask : DefaultTask() {
plugins.withId(pluginId) { @get:Inject
configureAndroidResources( abstract val fileSystem: FileSystemOperations
commonComposeResources,
buildDir("$RES_GEN_DIR/androidFonts").map { it.asFile }, @get:Input
shouldGenerateResClass abstract val from: Property<File>
)
@get:OutputDirectory
abstract val outputDirectory: DirectoryProperty
@TaskAction
fun action() {
fileSystem.copy {
it.includeEmptyDirs = false
it.from(from)
it.include("**/font*/*")
it.into(outputDirectory)
} }
} }
} }

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

@ -1,11 +1,10 @@
package org.jetbrains.compose.test.tests.integration package org.jetbrains.compose.test.tests.integration
import org.jetbrains.compose.test.utils.GradlePluginTestBase import org.jetbrains.compose.test.utils.*
import org.jetbrains.compose.test.utils.assertEqualTextFiles
import org.jetbrains.compose.test.utils.assertNotEqualTextFiles
import org.jetbrains.compose.test.utils.checks
import org.junit.jupiter.api.Test import org.junit.jupiter.api.Test
import kotlin.io.path.Path import java.io.File
import java.util.zip.ZipFile
import kotlin.test.*
class ResourcesTest : GradlePluginTestBase() { class ResourcesTest : GradlePluginTestBase() {
@Test @Test
@ -33,72 +32,88 @@ class ResourcesTest : GradlePluginTestBase() {
file("src/commonMain/composeResources/drawable-ren") file("src/commonMain/composeResources/drawable-ren")
) )
gradle("generateComposeResClass").checks { gradle("generateComposeResClass").checks {
check.logContains(""" check.logContains(
"""
contains unknown qualifier: 'ren'. contains unknown qualifier: 'ren'.
""".trimIndent()) """.trimIndent()
)
} }
file("src/commonMain/composeResources/drawable-ren").renameTo( file("src/commonMain/composeResources/drawable-ren").renameTo(
file("src/commonMain/composeResources/drawable-rUS-en") file("src/commonMain/composeResources/drawable-rUS-en")
) )
gradle("generateComposeResClass").checks { gradle("generateComposeResClass").checks {
check.logContains(""" check.logContains(
"""
Region qualifier must be declared after language: 'en-rUS'. Region qualifier must be declared after language: 'en-rUS'.
""".trimIndent()) """.trimIndent()
)
} }
file("src/commonMain/composeResources/drawable-rUS-en").renameTo( file("src/commonMain/composeResources/drawable-rUS-en").renameTo(
file("src/commonMain/composeResources/drawable-rUS") file("src/commonMain/composeResources/drawable-rUS")
) )
gradle("generateComposeResClass").checks { gradle("generateComposeResClass").checks {
check.logContains(""" check.logContains(
"""
Region qualifier must be used only with language. Region qualifier must be used only with language.
""".trimIndent()) """.trimIndent()
)
} }
file("src/commonMain/composeResources/drawable-rUS").renameTo( file("src/commonMain/composeResources/drawable-rUS").renameTo(
file("src/commonMain/composeResources/drawable-en-fr") file("src/commonMain/composeResources/drawable-en-fr")
) )
gradle("generateComposeResClass").checks { gradle("generateComposeResClass").checks {
check.logContains(""" check.logContains(
"""
contains repetitive qualifiers: 'en' and 'fr'. contains repetitive qualifiers: 'en' and 'fr'.
""".trimIndent()) """.trimIndent()
)
} }
file("src/commonMain/composeResources/drawable-en-fr").renameTo( file("src/commonMain/composeResources/drawable-en-fr").renameTo(
file("src/commonMain/composeResources/image") file("src/commonMain/composeResources/image")
) )
gradle("generateComposeResClass").checks { gradle("generateComposeResClass").checks {
check.logContains(""" check.logContains(
"""
Unknown resource type: 'image' Unknown resource type: 'image'
""".trimIndent()) """.trimIndent()
)
} }
file("src/commonMain/composeResources/image").renameTo( file("src/commonMain/composeResources/image").renameTo(
file("src/commonMain/composeResources/files-de") file("src/commonMain/composeResources/files-de")
) )
gradle("generateComposeResClass").checks { gradle("generateComposeResClass").checks {
check.logContains(""" check.logContains(
"""
The 'files' directory doesn't support qualifiers: 'files-de'. The 'files' directory doesn't support qualifiers: 'files-de'.
""".trimIndent()) """.trimIndent()
)
} }
file("src/commonMain/composeResources/files-de").renameTo( file("src/commonMain/composeResources/files-de").renameTo(
file("src/commonMain/composeResources/strings") file("src/commonMain/composeResources/strings")
) )
gradle("generateComposeResClass").checks { gradle("generateComposeResClass").checks {
check.logContains(""" check.logContains(
"""
Unknown resource type: 'strings'. Unknown resource type: 'strings'.
""".trimIndent()) """.trimIndent()
)
} }
file("src/commonMain/composeResources/strings").renameTo( file("src/commonMain/composeResources/strings").renameTo(
file("src/commonMain/composeResources/string-us") file("src/commonMain/composeResources/string-us")
) )
gradle("generateComposeResClass").checks { gradle("generateComposeResClass").checks {
check.logContains(""" check.logContains(
"""
Forbidden directory name 'string-us'! String resources should be declared in 'values/strings.xml'. Forbidden directory name 'string-us'! String resources should be declared in 'values/strings.xml'.
""".trimIndent()) """.trimIndent()
)
} }
//restore defaults //restore defaults
@ -111,10 +126,91 @@ class ResourcesTest : GradlePluginTestBase() {
} }
@Test @Test
fun testCopyFontsInAndroidApp(): Unit = with(testProject("misc/commonResources")) { fun testFinalArtefacts(): Unit = with(testProject("misc/commonResources")) {
//https://developer.android.com/build/build-variants?utm_source=android-studio#product-flavors
file("build.gradle.kts").appendText("""
kotlin {
js {
browser {
testTask(Action {
enabled = false
})
}
binaries.executable()
}
}
android {
flavorDimensions += "version"
productFlavors {
create("demo")
create("full")
}
}
""".trimIndent())
file("src/androidDemoDebug/composeResources/files/platform.txt").writeNewFile("android demo-debug")
file("src/androidDemoRelease/composeResources/files/platform.txt").writeNewFile("android demo-release")
file("src/androidFullDebug/composeResources/files/platform.txt").writeNewFile("android full-debug")
file("src/androidFullRelease/composeResources/files/platform.txt").writeNewFile("android full-release")
file("src/desktopMain/composeResources/files/platform.txt").writeNewFile("desktop")
file("src/jsMain/composeResources/files/platform.txt").writeNewFile("js")
val commonResourcesDir = file("src/commonMain/composeResources")
val commonResourcesFiles = commonResourcesDir.walkTopDown()
.filter { !it.isDirectory && !it.isHidden }
.map { it.relativeTo(commonResourcesDir).invariantSeparatorsPath }
gradle("build").checks { gradle("build").checks {
check.taskSuccessful(":copyDebugFontsToAndroidAssets") check.taskSuccessful(":copyDemoDebugFontsToAndroidAssets")
check.taskSuccessful(":copyReleaseFontsToAndroidAssets") check.taskSuccessful(":copyDemoReleaseFontsToAndroidAssets")
check.taskSuccessful(":copyFullDebugFontsToAndroidAssets")
check.taskSuccessful(":copyFullReleaseFontsToAndroidAssets")
checkAndroidApk("demo", "debug", commonResourcesFiles)
checkAndroidApk("demo", "release", commonResourcesFiles)
checkAndroidApk("full", "debug", commonResourcesFiles)
checkAndroidApk("full", "release", commonResourcesFiles)
val desktopJar = file("build/libs/resources_test-desktop.jar")
assertTrue(desktopJar.exists())
ZipFile(desktopJar).use { zip ->
commonResourcesFiles.forEach { res ->
assertNotNull(zip.getEntry(res))
}
val platformTxt = zip.getEntry("files/platform.txt")
assertNotNull(platformTxt)
val text = zip.getInputStream(platformTxt).readBytes().decodeToString()
assertEquals("desktop", text)
}
val jsBuildDir = file("build/dist/js/productionExecutable")
commonResourcesFiles.forEach { res ->
assertTrue(jsBuildDir.resolve(res).exists())
}
assertEquals("js", jsBuildDir.resolve("files/platform.txt").readText())
}
}
private fun File.writeNewFile(text: String) {
parentFile.mkdirs()
createNewFile()
writeText(text)
}
private fun TestProject.checkAndroidApk(flavor: String, type: String, commonResourcesFiles: Sequence<String>) {
val apk = file("build/outputs/apk/$flavor/$type/resources_test-$flavor-$type.apk")
assertTrue(apk.exists())
ZipFile(apk).use { zip ->
commonResourcesFiles.forEach { res ->
assertNotNull(zip.getEntry(res))
//todo fix duplicate fonts
}
assertNotNull(zip.getEntry("assets/font/emptyFont.otf"))
val platformTxt = zip.getEntry("files/platform.txt")
assertNotNull(platformTxt)
val text = zip.getInputStream(platformTxt).readBytes().decodeToString()
assertEquals("android $flavor-$type", text)
} }
} }
@ -122,7 +218,7 @@ class ResourcesTest : GradlePluginTestBase() {
fun testUpToDateChecks(): Unit = with(testProject("misc/commonResources")) { fun testUpToDateChecks(): Unit = with(testProject("misc/commonResources")) {
gradle("prepareKotlinIdeaImport").checks { gradle("prepareKotlinIdeaImport").checks {
check.taskSuccessful(":generateComposeResClass") check.taskSuccessful(":generateComposeResClass")
assert(file("build/generated/compose/resourceGenerator/kotlin/app/group/resources_test/generated/resources/Res.kt").exists()) assertTrue(file("build/generated/compose/resourceGenerator/kotlin/app/group/resources_test/generated/resources/Res.kt").exists())
} }
gradle("prepareKotlinIdeaImport").checks { gradle("prepareKotlinIdeaImport").checks {
check.taskUpToDate(":generateComposeResClass") check.taskUpToDate(":generateComposeResClass")
@ -136,12 +232,12 @@ class ResourcesTest : GradlePluginTestBase() {
} }
gradle("prepareKotlinIdeaImport").checks { gradle("prepareKotlinIdeaImport").checks {
check.taskSuccessful(":generateComposeResClass") check.taskSuccessful(":generateComposeResClass")
assert(!file("build/generated/compose/resourceGenerator/kotlin/app/group/resources_test/generated/resources/Res.kt").exists()) assertFalse(file("build/generated/compose/resourceGenerator/kotlin/app/group/resources_test/generated/resources/Res.kt").exists())
} }
gradle("prepareKotlinIdeaImport", "-Pcompose.resources.always.generate.accessors=true").checks { gradle("prepareKotlinIdeaImport", "-Pcompose.resources.always.generate.accessors=true").checks {
check.taskSuccessful(":generateComposeResClass") check.taskSuccessful(":generateComposeResClass")
assert(file("build/generated/compose/resourceGenerator/kotlin/app/group/resources_test/generated/resources/Res.kt").exists()) assertTrue(file("build/generated/compose/resourceGenerator/kotlin/app/group/resources_test/generated/resources/Res.kt").exists())
} }
modifyText("build.gradle.kts") { str -> modifyText("build.gradle.kts") { str ->
@ -152,7 +248,7 @@ class ResourcesTest : GradlePluginTestBase() {
} }
gradle("prepareKotlinIdeaImport").checks { gradle("prepareKotlinIdeaImport").checks {
check.taskUpToDate(":generateComposeResClass") check.taskUpToDate(":generateComposeResClass")
assert(file("build/generated/compose/resourceGenerator/kotlin/app/group/resources_test/generated/resources/Res.kt").exists()) assertTrue(file("build/generated/compose/resourceGenerator/kotlin/app/group/resources_test/generated/resources/Res.kt").exists())
} }
modifyText("build.gradle.kts") { str -> modifyText("build.gradle.kts") { str ->
@ -163,8 +259,8 @@ class ResourcesTest : GradlePluginTestBase() {
} }
gradle("prepareKotlinIdeaImport").checks { gradle("prepareKotlinIdeaImport").checks {
check.taskSuccessful(":generateComposeResClass") check.taskSuccessful(":generateComposeResClass")
assert(!file("build/generated/compose/resourceGenerator/kotlin/app/group/resources_test/generated/resources/Res.kt").exists()) assertFalse(file("build/generated/compose/resourceGenerator/kotlin/app/group/resources_test/generated/resources/Res.kt").exists())
assert(file("build/generated/compose/resourceGenerator/kotlin/io/company/resources_test/generated/resources/Res.kt").exists()) assertTrue(file("build/generated/compose/resourceGenerator/kotlin/io/company/resources_test/generated/resources/Res.kt").exists())
} }
} }
@ -270,7 +366,7 @@ class ResourcesTest : GradlePluginTestBase() {
gradle("desktopJar").checks { gradle("desktopJar").checks {
check.taskSuccessful(":generateStringFiles") check.taskSuccessful(":generateStringFiles")
check.taskSuccessful(":generateComposeResClass") check.taskSuccessful(":generateComposeResClass")
assert(file("src/commonMain/composeResources/values/strings.xml").readLines().size == 513) assertEquals(513, file("src/commonMain/composeResources/values/strings.xml").readLines().size)
} }
} }

2
gradle-plugins/compose/src/test/test-projects/misc/commonResources/build.gradle.kts

@ -40,7 +40,7 @@ android {
} }
buildTypes { buildTypes {
getByName("release") { getByName("release") {
isMinifyEnabled = false initWith(getByName("debug"))
} }
} }
compileOptions { compileOptions {

3
gradle-plugins/compose/src/test/test-projects/misc/commonResources/gradle.properties

@ -1,2 +1,3 @@
org.gradle.jvmargs=-Xmx8096M org.gradle.jvmargs=-Xmx8096M
android.useAndroidX=true android.useAndroidX=true
org.jetbrains.compose.experimental.jscanvas.enabled=true
Loading…
Cancel
Save