Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions .github/compilation-check-source.yml
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,49 @@ jobs:
- *publish_test_report
- *upload_reports

check-kotlin-2-dynamic-sample:
runs-on: ${{ matrix.os }}
strategy:
matrix:
<<: *runner_matrix
needs: build-library

steps:
- *checkout
- *setup_jdk
- *setup_gradle
- *cache_konan
- *download_maven

- name: Sample - kotlin-2-dynamic-sample
run: cd samples/kotlin-2-dynamic-sample && ./local-check.sh
shell: bash

- *publish_test_report
- *upload_reports

check-kotlin-2-tests:
runs-on: ${{ matrix.os }}
strategy:
matrix:
<<: *runner_matrix
needs: build-library

steps:
- *checkout
- *setup_jdk
- *setup_gradle
- uses: browser-actions/setup-chrome@v1
- *cache_konan
- *download_maven

- name: Sample - kotlin-2-tests
run: cd samples/kotlin-2-tests && ./local-check.sh
shell: bash

- *publish_test_report
- *upload_reports

check-cm-resources-sample:
runs-on: ${{ matrix.os }}
strategy:
Expand Down
95 changes: 94 additions & 1 deletion .github/workflows/compilation-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -498,6 +498,99 @@ jobs:
with:
name: code-coverage-report-${{ github.job }}-${{ matrix.os }}
path: "**/build/reports/**/*"
check-kotlin-2-dynamic-sample:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os:
- macOS-latest
- windows-latest
- ubuntu-latest
needs: build-library
steps:
- uses: actions/checkout@v4
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: 17
distribution: zulu
- name: Setup Gradle
uses: gradle/gradle-build-action@v3
with:
cache-read-only: ${{ github.ref != 'refs/heads/master' && github.ref !=
'refs/heads/develop' }}
- name: Cache .konan
uses: actions/cache@v4
with:
path: ~/.konan
key: ${{ matrix.os }}-konan-${{ hashFiles('**/*.gradle*', 'gradle/**/*') }}
- name: Download maven artifacts
uses: actions/download-artifact@v4
with:
name: maven
path: ~/.m2/repository/dev/icerock
- name: Sample - kotlin-2-dynamic-sample
run: cd samples/kotlin-2-dynamic-sample && ./local-check.sh
shell: bash
- name: Publish Test Report
uses: mikepenz/action-junit-report@v4
if: ${{ always() }}
with:
report_paths: "**/build/test-results/**/TEST-*.xml"
github_token: ${{ secrets.GITHUB_TOKEN }}
- name: Archive reports
uses: actions/upload-artifact@v4
if: ${{ always() }}
with:
name: code-coverage-report-${{ github.job }}-${{ matrix.os }}
path: "**/build/reports/**/*"
check-kotlin-2-tests:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os:
- macOS-latest
- windows-latest
- ubuntu-latest
needs: build-library
steps:
- uses: actions/checkout@v4
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: 17
distribution: zulu
- name: Setup Gradle
uses: gradle/gradle-build-action@v3
with:
cache-read-only: ${{ github.ref != 'refs/heads/master' && github.ref !=
'refs/heads/develop' }}
- uses: browser-actions/setup-chrome@v1
- name: Cache .konan
uses: actions/cache@v4
with:
path: ~/.konan
key: ${{ matrix.os }}-konan-${{ hashFiles('**/*.gradle*', 'gradle/**/*') }}
- name: Download maven artifacts
uses: actions/download-artifact@v4
with:
name: maven
path: ~/.m2/repository/dev/icerock
- name: Sample - kotlin-2-tests
run: cd samples/kotlin-2-tests && ./local-check.sh
shell: bash
- name: Publish Test Report
uses: mikepenz/action-junit-report@v4
if: ${{ always() }}
with:
report_paths: "**/build/test-results/**/TEST-*.xml"
github_token: ${{ secrets.GITHUB_TOKEN }}
- name: Archive reports
uses: actions/upload-artifact@v4
if: ${{ always() }}
with:
name: code-coverage-report-${{ github.job }}-${{ matrix.os }}
path: "**/build/reports/**/*"
check-cm-resources-sample:
runs-on: ${{ matrix.os }}
strategy:
Expand Down Expand Up @@ -543,4 +636,4 @@ jobs:
if: ${{ always() }}
with:
name: code-coverage-report-${{ github.job }}-${{ matrix.os }}
path: "**/build/reports/**/*"
path: "**/build/reports/**/*"
2 changes: 1 addition & 1 deletion gradle/moko.versions.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[versions]
resourcesVersion = "0.24.4"
resourcesVersion = "0.24.5"

[libraries]
resources = { module = "dev.icerock.moko:resources", version.ref = "resourcesVersion" }
Expand Down
2 changes: 2 additions & 0 deletions local-samples-check.sh
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,6 @@ set -e
(cd samples/compose-resources-gallery && ./local-check.sh)
(cd samples/default-hierarchy-gallery-mobile && ./local-check.sh)
(cd samples/kotlin-2-sample && ./local-check.sh)
(cd samples/kotlin-2-dynamic-sample && ./local-check.sh)
(cd samples/kotlin-2-tests && ./local-check.sh)
(cd samples/cm-resources-sample && ./local-check.sh)
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import org.gradle.api.logging.Logger
import org.jetbrains.kotlin.gradle.tasks.KotlinNativeLink
import org.jetbrains.kotlin.library.KotlinLibraryLayout
import org.jetbrains.kotlin.library.impl.KotlinLibraryLayoutImpl
import org.jetbrains.kotlin.library.impl.javaFile
import java.io.File

internal abstract class CopyResourcesFromKLibsAction : Action<Task> {
Expand All @@ -19,50 +20,69 @@ internal abstract class CopyResourcesFromKLibsAction : Action<Task> {
linkTask: KotlinNativeLink,
outputDir: File
) {
val packedKlibs: List<File> = linkTask.klibs
.filter { it.exists() }
.filter { it.extension == "klib" }
.map { it }
val unpackedKlibs: List<File> = linkTask.klibs
.filter { it.exists() }
// we need only unpacked klibs
.filter { it.name == "manifest" && it.parentFile.name == "default" }
// manifest stored in klib inside directory default
.map { it.parentFile.parentFile }
val logger: Logger = linkTask.logger

(packedKlibs + unpackedKlibs)
.forEach { inputFile ->
linkTask.logger.info("found dependency $inputFile, try to copy resources")

val layout: KotlinLibraryLayout = getKotlinLibraryLayout(inputFile)

copyResourcesFromKlib(
logger = linkTask.logger,
layout = layout,
outputDir = outputDir,
)
linkTask.klibs
.onEach { logger.debug("found klib dependency {}", it) }
.flatMap { getBundlesFromSources(sourceFile = it, logger = logger) }
.forEach { bundle ->
logger.info("copy $bundle to $outputDir")
bundle.copyRecursively(File(outputDir, bundle.name), overwrite = true)
}
}

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

try {
File(layout.resourcesDir.path).copyRecursively(
target = outputDir,
overwrite = true
)
} catch (@Suppress("SwallowedException") exc: NoSuchFileException) {
logger.info("resources in $layout not found")
} catch (@Suppress("SwallowedException") exc: java.nio.file.NoSuchFileException) {
logger.info("resources in $layout not found (empty lib)")
return if (isPackedKlib || isUnpackedKlib) {
logger.info("found klib {}", sourceFile)
getBundlesFromKotlinLibrary(sourceFile)
} else if (sourceFile.name == "manifest" && sourceFile.parentFile.name == "default") {
// for unpacked klibs we can see content files instead of klib directory.
// try to check this case
logger.info("found manifest of klib {}", sourceFile)
val unpackedKlibRoot: File = sourceFile.parentFile.parentFile
getBundlesFromKotlinLibrary(unpackedKlibRoot)
} else {
logger.debug("found some file {}", sourceFile)
emptyList()
}
}

private fun getBundlesFromKotlinLibrary(
klibFile: File
): List<File> {
val layout: KotlinLibraryLayout = getKotlinLibraryLayout(klibFile)
return layout.resourcesDir.listFilesOrEmpty
.filter { it.isDirectory && it.extension == "bundle" }
.map { it.javaFile() }
}

private fun getKotlinLibraryLayout(file: File): KotlinLibraryLayout {
val klibKonan = org.jetbrains.kotlin.konan.file.File(file.path)
val klib = KotlinLibraryLayoutImpl(klib = klibKonan, component = "default")

// while klib zipped we can't check resources directory, so we should unpack all klibs :(
// maybe will be better if we will write some state in cache as build result file with
// klib path, hash, resources count. to not extract klibs that we already know that not
// contains any resources. BUT maybe extraction will be faster then hashing for this logic.
// so this improvement should be checked in future
return if (klib.isZipped) klib.extractingToTemp else klib
}
}
11 changes: 11 additions & 0 deletions samples/kotlin-2-dynamic-sample/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
*.iml
.gradle
.idea
.DS_Store
.kotlin
build
captures
.externalNativeBuild
.cxx
local.properties
xcuserdata
6 changes: 6 additions & 0 deletions samples/kotlin-2-dynamic-sample/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Sample of mobile app with Kotlin 2.1, multimodule and dynamic framework

## Build

1. publish moko-resources to local maven - `./gradlew publishToMavenLocal` in `moko-resources` root
2. build sample (in IDE or by `./gradlew build`)
47 changes: 47 additions & 0 deletions samples/kotlin-2-dynamic-sample/androidApp/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
plugins {
alias(libs.plugins.androidApplication)
alias(libs.plugins.kotlinAndroid)
alias(libs.plugins.compose.compiler)
}

android {
namespace = "app.kotlin2sample.android"
compileSdk = 34
defaultConfig {
applicationId = "app.kotlin2sample.android"
minSdk = 26
targetSdk = 34
versionCode = 1
versionName = "1.0"
}
buildFeatures {
compose = true
}
packaging {
resources {
excludes += "/META-INF/{AL2.0,LGPL2.1}"
}
}
buildTypes {
getByName("release") {
isMinifyEnabled = false
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = "1.8"
}
}

dependencies {
implementation(projects.shared)
implementation(libs.compose.ui)
implementation(libs.compose.ui.tooling.preview)
implementation(libs.compose.material3)
implementation(libs.androidx.activity.compose)
implementation(moko.resourcesCompose)
debugImplementation(libs.compose.ui.tooling)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

<application
android:allowBackup="false"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity
android:name="app.thirtyninth.compose.navigation.kotlin2sample.android.MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Loading
Loading