Skip to content

Commit 29b4834

Browse files
authored
Merge pull request #804 from icerockdev/develop
Develop 0.24.5
2 parents 7d894f0 + 9704ff3 commit 29b4834

File tree

81 files changed

+2234
-46
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

81 files changed

+2234
-46
lines changed

.github/compilation-check-source.yml

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,49 @@ jobs:
290290
- *publish_test_report
291291
- *upload_reports
292292

293+
check-kotlin-2-dynamic-sample:
294+
runs-on: ${{ matrix.os }}
295+
strategy:
296+
matrix:
297+
<<: *runner_matrix
298+
needs: build-library
299+
300+
steps:
301+
- *checkout
302+
- *setup_jdk
303+
- *setup_gradle
304+
- *cache_konan
305+
- *download_maven
306+
307+
- name: Sample - kotlin-2-dynamic-sample
308+
run: cd samples/kotlin-2-dynamic-sample && ./local-check.sh
309+
shell: bash
310+
311+
- *publish_test_report
312+
- *upload_reports
313+
314+
check-kotlin-2-tests:
315+
runs-on: ${{ matrix.os }}
316+
strategy:
317+
matrix:
318+
<<: *runner_matrix
319+
needs: build-library
320+
321+
steps:
322+
- *checkout
323+
- *setup_jdk
324+
- *setup_gradle
325+
- uses: browser-actions/setup-chrome@v1
326+
- *cache_konan
327+
- *download_maven
328+
329+
- name: Sample - kotlin-2-tests
330+
run: cd samples/kotlin-2-tests && ./local-check.sh
331+
shell: bash
332+
333+
- *publish_test_report
334+
- *upload_reports
335+
293336
check-cm-resources-sample:
294337
runs-on: ${{ matrix.os }}
295338
strategy:

.github/workflows/compilation-check.yml

Lines changed: 94 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -498,6 +498,99 @@ jobs:
498498
with:
499499
name: code-coverage-report-${{ github.job }}-${{ matrix.os }}
500500
path: "**/build/reports/**/*"
501+
check-kotlin-2-dynamic-sample:
502+
runs-on: ${{ matrix.os }}
503+
strategy:
504+
matrix:
505+
os:
506+
- macOS-latest
507+
- windows-latest
508+
- ubuntu-latest
509+
needs: build-library
510+
steps:
511+
- uses: actions/checkout@v4
512+
- name: Set up JDK 17
513+
uses: actions/setup-java@v4
514+
with:
515+
java-version: 17
516+
distribution: zulu
517+
- name: Setup Gradle
518+
uses: gradle/gradle-build-action@v3
519+
with:
520+
cache-read-only: ${{ github.ref != 'refs/heads/master' && github.ref !=
521+
'refs/heads/develop' }}
522+
- name: Cache .konan
523+
uses: actions/cache@v4
524+
with:
525+
path: ~/.konan
526+
key: ${{ matrix.os }}-konan-${{ hashFiles('**/*.gradle*', 'gradle/**/*') }}
527+
- name: Download maven artifacts
528+
uses: actions/download-artifact@v4
529+
with:
530+
name: maven
531+
path: ~/.m2/repository/dev/icerock
532+
- name: Sample - kotlin-2-dynamic-sample
533+
run: cd samples/kotlin-2-dynamic-sample && ./local-check.sh
534+
shell: bash
535+
- name: Publish Test Report
536+
uses: mikepenz/action-junit-report@v4
537+
if: ${{ always() }}
538+
with:
539+
report_paths: "**/build/test-results/**/TEST-*.xml"
540+
github_token: ${{ secrets.GITHUB_TOKEN }}
541+
- name: Archive reports
542+
uses: actions/upload-artifact@v4
543+
if: ${{ always() }}
544+
with:
545+
name: code-coverage-report-${{ github.job }}-${{ matrix.os }}
546+
path: "**/build/reports/**/*"
547+
check-kotlin-2-tests:
548+
runs-on: ${{ matrix.os }}
549+
strategy:
550+
matrix:
551+
os:
552+
- macOS-latest
553+
- windows-latest
554+
- ubuntu-latest
555+
needs: build-library
556+
steps:
557+
- uses: actions/checkout@v4
558+
- name: Set up JDK 17
559+
uses: actions/setup-java@v4
560+
with:
561+
java-version: 17
562+
distribution: zulu
563+
- name: Setup Gradle
564+
uses: gradle/gradle-build-action@v3
565+
with:
566+
cache-read-only: ${{ github.ref != 'refs/heads/master' && github.ref !=
567+
'refs/heads/develop' }}
568+
- uses: browser-actions/setup-chrome@v1
569+
- name: Cache .konan
570+
uses: actions/cache@v4
571+
with:
572+
path: ~/.konan
573+
key: ${{ matrix.os }}-konan-${{ hashFiles('**/*.gradle*', 'gradle/**/*') }}
574+
- name: Download maven artifacts
575+
uses: actions/download-artifact@v4
576+
with:
577+
name: maven
578+
path: ~/.m2/repository/dev/icerock
579+
- name: Sample - kotlin-2-tests
580+
run: cd samples/kotlin-2-tests && ./local-check.sh
581+
shell: bash
582+
- name: Publish Test Report
583+
uses: mikepenz/action-junit-report@v4
584+
if: ${{ always() }}
585+
with:
586+
report_paths: "**/build/test-results/**/TEST-*.xml"
587+
github_token: ${{ secrets.GITHUB_TOKEN }}
588+
- name: Archive reports
589+
uses: actions/upload-artifact@v4
590+
if: ${{ always() }}
591+
with:
592+
name: code-coverage-report-${{ github.job }}-${{ matrix.os }}
593+
path: "**/build/reports/**/*"
501594
check-cm-resources-sample:
502595
runs-on: ${{ matrix.os }}
503596
strategy:
@@ -543,4 +636,4 @@ jobs:
543636
if: ${{ always() }}
544637
with:
545638
name: code-coverage-report-${{ github.job }}-${{ matrix.os }}
546-
path: "**/build/reports/**/*"
639+
path: "**/build/reports/**/*"

README.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ buildscript {
6464
}
6565
6666
dependencies {
67-
classpath "dev.icerock.moko:resources-generator:0.24.4"
67+
classpath "dev.icerock.moko:resources-generator:0.24.5"
6868
}
6969
}
7070
@@ -82,10 +82,10 @@ project build.gradle
8282
apply plugin: "dev.icerock.mobile.multiplatform-resources"
8383
8484
dependencies {
85-
commonMainApi("dev.icerock.moko:resources:0.24.4")
86-
commonMainApi("dev.icerock.moko:resources-compose:0.24.4") // for compose multiplatform
85+
commonMainApi("dev.icerock.moko:resources:0.24.5")
86+
commonMainApi("dev.icerock.moko:resources-compose:0.24.5") // for compose multiplatform
8787
88-
commonTestImplementation("dev.icerock.moko:resources-test:0.24.4")
88+
commonTestImplementation("dev.icerock.moko:resources-test:0.24.5")
8989
}
9090
9191
multiplatformResources {
@@ -132,7 +132,7 @@ should [add `export` declarations](https://kotlinlang.org/docs/multiplatform-bui
132132

133133
```
134134
framework {
135-
export("dev.icerock.moko:resources:0.24.4")
135+
export("dev.icerock.moko:resources:0.24.5")
136136
export("dev.icerock.moko:graphics:0.9.0") // toUIColor here
137137
}
138138
```

gradle/moko.versions.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[versions]
2-
resourcesVersion = "0.24.4"
2+
resourcesVersion = "0.24.5"
33

44
[libraries]
55
resources = { module = "dev.icerock.moko:resources", version.ref = "resourcesVersion" }

local-samples-check.sh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,6 @@ set -e
1414
(cd samples/compose-resources-gallery && ./local-check.sh)
1515
(cd samples/default-hierarchy-gallery-mobile && ./local-check.sh)
1616
(cd samples/kotlin-2-sample && ./local-check.sh)
17+
(cd samples/kotlin-2-dynamic-sample && ./local-check.sh)
18+
(cd samples/kotlin-2-tests && ./local-check.sh)
1719
(cd samples/cm-resources-sample && ./local-check.sh)

resources-generator/src/main/kotlin/dev/icerock/gradle/actions/apple/CopyResourcesFromKLibsAction.kt

Lines changed: 52 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import org.gradle.api.logging.Logger
1111
import org.jetbrains.kotlin.gradle.tasks.KotlinNativeLink
1212
import org.jetbrains.kotlin.library.KotlinLibraryLayout
1313
import org.jetbrains.kotlin.library.impl.KotlinLibraryLayoutImpl
14+
import org.jetbrains.kotlin.library.impl.javaFile
1415
import java.io.File
1516

1617
internal abstract class CopyResourcesFromKLibsAction : Action<Task> {
@@ -19,50 +20,69 @@ internal abstract class CopyResourcesFromKLibsAction : Action<Task> {
1920
linkTask: KotlinNativeLink,
2021
outputDir: File
2122
) {
22-
val packedKlibs: List<File> = linkTask.klibs
23-
.filter { it.exists() }
24-
.filter { it.extension == "klib" }
25-
.map { it }
26-
val unpackedKlibs: List<File> = linkTask.klibs
27-
.filter { it.exists() }
28-
// we need only unpacked klibs
29-
.filter { it.name == "manifest" && it.parentFile.name == "default" }
30-
// manifest stored in klib inside directory default
31-
.map { it.parentFile.parentFile }
23+
val logger: Logger = linkTask.logger
3224

33-
(packedKlibs + unpackedKlibs)
34-
.forEach { inputFile ->
35-
linkTask.logger.info("found dependency $inputFile, try to copy resources")
36-
37-
val layout: KotlinLibraryLayout = getKotlinLibraryLayout(inputFile)
38-
39-
copyResourcesFromKlib(
40-
logger = linkTask.logger,
41-
layout = layout,
42-
outputDir = outputDir,
43-
)
25+
linkTask.klibs
26+
.onEach { logger.debug("found klib dependency {}", it) }
27+
.flatMap { getBundlesFromSources(sourceFile = it, logger = logger) }
28+
.forEach { bundle ->
29+
logger.info("copy $bundle to $outputDir")
30+
bundle.copyRecursively(File(outputDir, bundle.name), overwrite = true)
4431
}
4532
}
4633

47-
private fun copyResourcesFromKlib(logger: Logger, layout: KotlinLibraryLayout, outputDir: File) {
48-
logger.info("copy resources from $layout into $outputDir")
34+
/**
35+
* Search bundles in klib different types.
36+
*
37+
* We know about 3 types of klib in filesystem:
38+
* 1. packed klib - single file with .klib extension
39+
* 2. unpacked klib directory - root directory with klib content (used for local project
40+
* dependencies)
41+
* 3. unpacked klib content - all files inside klib directory (used for current project
42+
* compilation results)
43+
*
44+
* @param sourceFile file from linking task dependencies and sources list
45+
* @param logger gradle logger
46+
*
47+
* @return list of .bundle directories founded in klibs
48+
*/
49+
private fun getBundlesFromSources(sourceFile: File, logger: Logger): List<File> {
50+
val isPackedKlib = sourceFile.isFile && sourceFile.extension == "klib"
51+
val isUnpackedKlib = sourceFile.isDirectory
4952

50-
try {
51-
File(layout.resourcesDir.path).copyRecursively(
52-
target = outputDir,
53-
overwrite = true
54-
)
55-
} catch (@Suppress("SwallowedException") exc: NoSuchFileException) {
56-
logger.info("resources in $layout not found")
57-
} catch (@Suppress("SwallowedException") exc: java.nio.file.NoSuchFileException) {
58-
logger.info("resources in $layout not found (empty lib)")
53+
return if (isPackedKlib || isUnpackedKlib) {
54+
logger.info("found klib {}", sourceFile)
55+
getBundlesFromKotlinLibrary(sourceFile)
56+
} else if (sourceFile.name == "manifest" && sourceFile.parentFile.name == "default") {
57+
// for unpacked klibs we can see content files instead of klib directory.
58+
// try to check this case
59+
logger.info("found manifest of klib {}", sourceFile)
60+
val unpackedKlibRoot: File = sourceFile.parentFile.parentFile
61+
getBundlesFromKotlinLibrary(unpackedKlibRoot)
62+
} else {
63+
logger.debug("found some file {}", sourceFile)
64+
emptyList()
5965
}
6066
}
6167

68+
private fun getBundlesFromKotlinLibrary(
69+
klibFile: File
70+
): List<File> {
71+
val layout: KotlinLibraryLayout = getKotlinLibraryLayout(klibFile)
72+
return layout.resourcesDir.listFilesOrEmpty
73+
.filter { it.isDirectory && it.extension == "bundle" }
74+
.map { it.javaFile() }
75+
}
76+
6277
private fun getKotlinLibraryLayout(file: File): KotlinLibraryLayout {
6378
val klibKonan = org.jetbrains.kotlin.konan.file.File(file.path)
6479
val klib = KotlinLibraryLayoutImpl(klib = klibKonan, component = "default")
6580

81+
// while klib zipped we can't check resources directory, so we should unpack all klibs :(
82+
// maybe will be better if we will write some state in cache as build result file with
83+
// klib path, hash, resources count. to not extract klibs that we already know that not
84+
// contains any resources. BUT maybe extraction will be faster then hashing for this logic.
85+
// so this improvement should be checked in future
6686
return if (klib.isZipped) klib.extractingToTemp else klib
6787
}
6888
}

resources/src/jsMain/kotlin/dev/icerock/moko/resources/desc/PluralFormattedStringDesc.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,13 @@ actual data class PluralFormattedStringDesc actual constructor(
1616
override suspend fun toLocalizedString(): String =
1717
toLocalizedString(pluralsRes.loader.getOrLoad())
1818

19+
@Suppress("SpreadOperator")
1920
override fun toLocalizedString(provider: JsStringProvider): String {
2021
return pluralsRes.localized(
2122
provider = provider,
2223
locale = StringDesc.localeType.locale,
2324
quantity = number,
24-
args = args.toTypedArray()
25+
*Utils.processArgs(args, provider)
2526
)
2627
}
2728
}

resources/src/jsMain/kotlin/dev/icerock/moko/resources/desc/ResourceFormattedStringDesc.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,12 @@ actual data class ResourceFormattedStringDesc actual constructor(
1414
override suspend fun toLocalizedString(): String =
1515
toLocalizedString(stringRes.loader.getOrLoad())
1616

17+
@Suppress("SpreadOperator")
1718
override fun toLocalizedString(provider: JsStringProvider): String {
1819
return stringRes.localized(
1920
provider = provider,
2021
locale = StringDesc.localeType.locale,
21-
args = args.toTypedArray()
22+
*Utils.processArgs(args, provider)
2223
)
2324
}
2425
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
/*
2+
* Copyright 2025 IceRock MAG Inc. Use of this source code is governed by the Apache 2.0 license.
3+
*/
4+
5+
package dev.icerock.moko.resources.desc
6+
7+
import dev.icerock.moko.resources.provider.JsStringProvider
8+
9+
object Utils {
10+
fun processArgs(
11+
args: List<Any>,
12+
provider: JsStringProvider
13+
): Array<out Any> {
14+
return args.map { (it as? StringDesc)?.toLocalizedString(provider) ?: it }.toTypedArray()
15+
}
16+
}

resources/src/jvmMain/kotlin/dev/icerock/moko/resources/desc/PluralFormattedStringDesc.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@ actual data class PluralFormattedStringDesc actual constructor(
1111
val number: Int,
1212
val args: List<Any>
1313
) : StringDesc {
14-
14+
@Suppress("SpreadOperator")
1515
override fun localized() = pluralsRes.localized(
1616
locale = StringDesc.localeType.currentLocale,
1717
quantity = number,
18-
*(args.toTypedArray())
18+
*Utils.processArgs(args)
1919
)
2020
}

0 commit comments

Comments
 (0)