moko-resources
moko-resources copied to clipboard
#535 kotlin 1.9.0, compose multiplatform 1.5.0 support
Include changes from:
- #565
- #561
- #547
- #541
plugin reworked to Provider gradle's api to support dynamic changes of projects configuration.
If you have some not standard usecase - send PR with new sample project please. every sample project is our test case
This request contains breaking changes to better support dynamic changes of configurations and support new features in future (for example - configuration cache #311 ).
At first - resources directory moved from src/<resourceSourceSetName>/resources/MR to src/<sourceSetName>/moko-resources. I have multiple reasons for this:
- Kotlin improve own resources directory management and Compose Multiplatform at now use content of
resourcesdirectory. Our resources inMRdirectory was not ready for directly usage as resource - our resources if "source" for generation of platform resources. For example - for iOS all resources should be packed inbundle, for androidsvgshould be converted tovector-xml. inresourcessource set in future we can put output of our generators, but "source" resources should not be copied into result app. - at gradle configuration stage we can't correctly decide what source set should be used for generation with current logic
resourceSourceSetNamethat configured in plugin's extension - source sets can change at any time, andresourceSourceSetNamein plugin extension can be changed in any time. So we should generate MR tasks for all sourcesets and decide what to do at EXECUTION stage. Also it allow to put resources in any sourceSet in hierarchy. For example incommonMainwill be common resources and iniosMainwill be ios specific resources added. It's was requested in #357
Second - MR object will be generated not only expect + actuals, but also for middle layer expects in different source sets. For example if we have next sourceSets hierarchy:
commonMain // here we have string common_hello
- androidMain // here no any additional strings
- appleMain // here we have string apple_hello
-- iosMain // here we have string ios_hello
--- iosX64Main // here we have string iosx64_hello
--- iosSimulatorArm64Main // here no any additional strings
--- iosArm64Main // here no any additional strings
We can put resources in each source set. And as result we got this sources:
commonMain/MR.common.kt:
expect object MR {
object strings: AppleMainStrings, IosMainStrings {
val commonHello: StringResource
}
}
expect interface AppleMainStrings // this naming not final. if you have idea about better name - please write comment
expect interface IosMainStrings // this naming not final. if you have idea about better name - please write comment
androidMain/MR.android.kt:
actual interface AppleMainStrings
actual interface IosMainStrings
actual object MR {
actual object strings : AppleMainStrings, IosMainStrings {
actual val commonHello: StringResource get() = TODO()
}
}
appleMain/MR.apple.kt:
actual interface AppleMainStrings {
val appleHello: StringResource
}
iosMain/MR.ios.kt:
actual interface IosMainStrings {
val iosHello: StringResource
}
iosX64Main/MR.iosX64.kt:
actual object MR {
actual object strings : AppleMainStrings, IosMainStrings {
actual val commonHello: StringResource get() = TODO()
override val appleHello: StringResource get() = TODO()
override val iosHello: StringResource get() = TODO()
val iosX64Hello: StringResource get() = TODO()
}
}
iosArm64Main/MR.iosArm64.kt, iosSimulatorArm64Main/MR.iosSimulatorArm64.kt:
actual object MR {
actual object strings : AppleMainStrings, IosMainStrings {
actual val commonHello: StringResource get() = TODO()
override val appleHello: StringResource get() = TODO()
override val iosHello: StringResource get() = TODO()
}
}
To decide what exactly should be generated each generateMR task will check own moko-resources directory and dependencies.
expect object MR will be located at lowest level of hierarchy (for example if we have not resources in commonMain but have in iosMain - expect will be in iosMain and commonMain will be empty. With this change we can remove resourcesSourceSet property from extension.
Current progress:
- [x] Common generator
- [x] Target generator
- [x] Android MR generator
- [x] JVM MR generator
- [x] JS MR generator
- [x] Apple MR generator
- [x] Define generated resources as sourceSet, assets, resources**
- [x] Copy resources of Apple and JS targets in KLibs**
- [x] Metadata:
- [x] Base
- [x] All generators work with metadata
- [x] Move resources from
resources/MRtomoko-resources - [x] Strings generator: - Success run on sample
- [x] Common target
- [x] Android target
- [x] Jvm target
- [x] Js target
- [x] Apple target
- [x] Plurals generator: - Success run on sample
- [x] Common target
- [x] Android target
- [x] Jvm target
- [x] Js target
- [x] Apple target
- [x] Files generator:
- [x] Common target
- [x] Android target
- [x] Jvm target
- [x] Js target
- [x] Apple target
- [x] Fonts generator:
- [x] Common target
- [x] Android target
- [x] Jvm target
- [x] Js target
- [x] Apple target
- [x] Assets generator:
- [x] Common target
- [x] Android target
- [x] Jvm target
- [x] Js target
- [x] Apple target
- [x] Colors generator:
- [x] Common target
- [x] Android target
- [x] Jvm target
- [x] Js target
- [x] Apple target
- [x] Images generator:
- [x] Common target
- [x] Android target
- [x] Jvm target
- [x] Js target
- [x] Apple target
- [x] Testing on samples
- [ ] Testing on real IceRock projects
known issues:
- [ ] gradle task cache not invalidates when add resources in target sourceset, when project already compiled with resources exist on lower levels (when have resources in commonMain, compile, then create resources in desktopMain)
- [ ] fonts generated object is changed (in past we have additional object with font family name and inside have properties with styles. now we have only properties like
fontfamily-style) - i think we can not fix this at all - [ ] assets generated object is changed (in past was generated also inner objects like directory tree. now generated only flat properties and you can't see directory structure) - want to fix, but can't decide how (when we should generate interface for intermediate resources - we can't generated inner objects)
- [x] in some cases actual for iOS target not generated
todo:
- [x] research usage of Android Gradle Plugin Variants API to fix issues like #628
- [ ] try to implement integrational junit tests with testrun various kotlin, android gradle plugin versions - help required here
- [ ] check Action implementations - move all that can be moved to separated gradle tasks
- [ ] remove expect/actual interfaces at all (Parcelable usage, ResourceContainer, generated interfaces) - https://youtrack.jetbrains.com/issue/KT-59739
- [ ] fix assets bug - https://github.com/icerockdev/moko-resources/pull/575#issuecomment-1928053225
- [ ] build failed with mockmp - https://github.com/icerockdev/moko-resources/pull/575#issuecomment-1927402089
- [ ] js build failed - https://github.com/icerockdev/moko-resources/discussions/625#discussioncomment-8130422
- [ ] copyFrameworkResourcesToApp missed (when framework prefix is empty) - https://github.com/icerockdev/moko-resources/discussions/625#discussioncomment-8424427
- [ ] android R class missed - https://github.com/icerockdev/moko-resources/discussions/625#discussioncomment-8390982
- [ ] fix compatibility with compose resources - https://kotlinlang.slack.com/archives/CMC5LN42W/p1707978856036959?thread_ts=1705913203.842639&cid=CMC5LN42W
- [ ] check assets changes - https://kotlinlang.slack.com/archives/CMC5LN42W/p1707653155054129
@Pschsch hi. can you also test your project with this branch?
and if you got some issues - please submit small test project for samples directory, i use samples as test cases for plugin
@illarionov hi. can you also test your project with this branch?
and if you got some issues - please submit small test project for samples directory, i use samples as test cases for plugin
@Pschsch hi. can you also test your project with this branch? and if you got some issues - please submit small test project for
samplesdirectory, i use samples as test cases for plugin
Hi @Alex009, i ll try to test today. Wait for feedback)
@illarionov hi. can you also test your project with this branch? and if you got some issues - please submit small test project for
samplesdirectory, i use samples as test cases for plugin
I don't have my own project yet, just checking if I can use this library in the future. I used samples from this repository for my own testing.
This branch still has issue with implicit task dependencies. Shouldn't it be resolved here?
Task 'kspKotlinIosArm64' uses this output of task 'generateMRiosArm64Main' without declaring an explicit or implicit dependency. This can lead to incorrect results being produced, depending on what order the tasks are **executed.**
In Gradle 8, this leads to build failure
In total, this branch breaks the main functional - resources generating. MR objects generating with no resources fields
But there must be tons of strings, colors and images
Assume that it's because of new lazy plugin configuration
Reverting branch to my commit with hash 316f2a66559e510f2be8302a87331437bc9238b5 fixes the issue with generation. So suppose that plugin has broken after this commit
@Pschsch did you move all the resources from resources/MR/* to moko-resources/*?
@illarionov i've cloned my project from scratch for test. Why i should manually move resources? Plugin's tasks should generate resources in appropriate way as they do it on 316f2a66559e510f2be8302a87331437bc9238b5 commit and before)
As I've already said, the problem exists on commits after 316f2a66559e510f2be8302a87331437bc9238b5
@Pschsch no. With this release we move resources to moko-resources from resources/MR to prevent conflicts with kotlin own resources management
Oh, sorry, my fail, i got it. No, I've not done it
I'll test today one more time and will give a fedback
Tried to move res in one module from resources/MR to moko-resources. Got:
Replaced mkdir() to mkdirs(), the problem has disappeared. The new problem - images not generating. Strings, plurals and colors exist
Any news here? Eagerly waiting for the next update with this fix to be finally able to update to Kotlin 1.9. 😅
any news?
When can we expect this to be merged ? @Alex009 @illarionov @Pschsch
When can we expect this to be merged ? @Alex009 @illarionov @Pschsch
here not completed changes. at first i should complete all changes in plugin and then we can merge and publish
For those waiting for this pr. You can update to kotlin 1.9 and use the code below:
sourceSets {
//val commonMain by getting
androidMain {
dependsOn(commonMain.get())
}
iosMain {
dependsOn(commonMain.get())
}
}
It will avoid the new default hierarchy, BUT you can update to Kotlin 1.9.20 It can be removed after this PR is merged.
For those waiting for this pr. You can update to kotlin 1.9 and use the code below:
sourceSets { //val commonMain by getting androidMain { dependsOn(commonMain.get()) } iosMain { dependsOn(commonMain.get()) } }It will avoid the new default hierarchy, BUT you can update to Kotlin 1.9.20 It can be removed after this PR is merged.
I have a question, I need to use the current version or compile in maven local this PR and put this changes ?
I have a question, I need to use the current version or compile in maven local this PR and put this changes ?
I did it using the 0.23.0 version and it worked. My config is something like this:
fun Project.setupKMP() {
plugins.withType<org.jetbrains.kotlin.gradle.plugin.KotlinBasePluginWrapper> {
extensions.configure<KotlinMultiplatformExtension> {
explicitApi()
//https://kotlinlang.org/docs/whatsnew-eap.html#see-the-full-hierarchy-template
androidTarget()
iosArm64()
iosSimulatorArm64()
// Apply the default hierarchy explicitly. It'll create, for example, the iosMain source set:
applyDefaultHierarchyTemplate()
sourceSets {
androidMain {
dependsOn(commonMain.get())
}
}
}
findAndroidExtension().apply {
setupAndroid()
sourceSets["main"].apply {
res.srcDirs("src/androidMain/resources")
manifest.srcFile("src/androidMain/AndroidManifest.xml")
}
}
}
configure<KotlinMultiplatformExtension> {
jvmToolchain(17)
}
configure<JavaPluginExtension> {
toolchain {
languageVersion.set(JavaLanguageVersion.of(17))
}
}
}
I have a question, I need to use the current version or compile in maven local this PR and put this changes ?
I did it using the 0.23.0 version and it worked. My config is something like this:
fun Project.setupKMP() { plugins.withType<org.jetbrains.kotlin.gradle.plugin.KotlinBasePluginWrapper> { extensions.configure<KotlinMultiplatformExtension> { explicitApi() //https://kotlinlang.org/docs/whatsnew-eap.html#see-the-full-hierarchy-template androidTarget() iosArm64() iosSimulatorArm64() // Apply the default hierarchy explicitly. It'll create, for example, the iosMain source set: applyDefaultHierarchyTemplate() sourceSets { androidMain { dependsOn(commonMain.get()) } } } findAndroidExtension().apply { setupAndroid() sourceSets["main"].apply { res.srcDirs("src/androidMain/resources") manifest.srcFile("src/androidMain/AndroidManifest.xml") } } } configure<KotlinMultiplatformExtension> { jvmToolchain(17) } configure<JavaPluginExtension> { toolchain { languageVersion.set(JavaLanguageVersion.of(17)) } } }
Thanks, I will try to try this because my problem was in the iOS side :D
What is the status of this pull request? @Alex009
@Alex009 ok I see that you sent me two issues, effectively those are already closed? if you need any help, let me know
Any update folks?
At bow my colleague @ExNDY continue work on this changes
@Alex009 was it not supported until 1.9.20?
Any estimate on when this will be done? This is a major blocker for the migration to Compose 1.5 (which was released 3 months ago) and Kotlin 1.9. For now, I don't see any other solution other than to write a custom solution for string localization.
Any estimate on when this will be done? This is a major blocker for the migration to Compose 1.5 (which was released 3 months ago) and Kotlin 1.9. For now, I don't see any other solution other than to write a custom solution for string localization.
It is true, they are hindering a lot to make this migration are launching many changes I would say, and would have done the main thing that was the version upgrade