├── .editorconfig ├── .github └── workflows │ ├── build-linux.yml │ ├── build-macos.yml │ ├── build-windows.yml │ ├── ci.yml │ └── release.yaml ├── .gitignore ├── .idea ├── codeStyles │ ├── Project.xml │ └── codeStyleConfig.xml ├── copyright │ ├── Multiplatform_Paths.xml │ └── profiles_settings.xml ├── inspectionProfiles │ └── Project_Default.xml └── runConfigurations │ ├── IOS_App.xml │ ├── mp_utils_sample_desktopApp__run_.xml │ ├── mp_utils_sample_macosApp__runDebugExecutableMacosArm64_.xml │ ├── mp_utils_sample_nodeApp__jsNodeDevelopmentRun_.xml │ ├── mp_utils_sample_webApp__jsBrowserDevelopmentRun_.xml │ ├── sample_androidApp.xml │ └── sample_wearosApp.xml ├── CHANGELOG.md ├── LICENSE ├── README.md ├── build-logic ├── .gitignore ├── build.gradle.kts ├── settings.gradle.kts └── src │ └── main │ └── kotlin │ ├── AndroidAppConventionPlugin.kt │ ├── ModuleConventionPlugin.kt │ ├── MultiPlatformLibraryConventionPlugin.kt │ ├── PackagingConventionPlugin.kt │ └── me │ └── sujanpoudel │ └── utils │ ├── Artifacts.kt │ ├── KotlinAndroid.kt │ ├── KotlinMultiplatform.kt │ ├── Libs.kt │ └── PluginManager.kt ├── build.gradle.kts ├── config └── detekt │ └── detekt.yml ├── context-provider ├── .gitignore ├── api │ └── context-provider.api ├── build.gradle.kts └── src │ ├── androidMain │ ├── AndroidManifest.xml │ └── kotlin │ │ └── me │ │ └── sujanpoudel │ │ └── utils │ │ └── contextProvider │ │ └── ApplicationContextInitializer.kt │ └── androidUnitTest │ └── kotlin │ └── me │ └── sujanpoudel │ └── utils │ └── contextProvider │ └── ApplicationContextInitializerTest.kt ├── gradle.properties ├── gradle ├── libs.versions.toml └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── kotlin-js-store └── yarn.lock ├── migration-guides.md ├── multiplatform-paths ├── api │ ├── android │ │ └── multiplatform-paths.api │ └── desktop │ │ └── multiplatform-paths.api ├── build.gradle.kts └── src │ ├── androidMain │ └── kotlin │ │ └── me │ │ └── sujanpoudel │ │ └── utils │ │ └── paths │ │ └── directories.android.kt │ ├── androidUnitTest │ └── kotlin │ │ └── me │ │ └── sujanpoudel │ │ └── utils │ │ └── paths │ │ └── AndroidDirectoriesTest.kt │ ├── commonMain │ └── kotlin │ │ └── me │ │ └── sujanpoudel │ │ └── utils │ │ └── paths │ │ ├── directories.kt │ │ └── utils │ │ └── Path.kt │ ├── commonTest │ └── kotlin │ │ └── me │ │ └── sujanpoudel │ │ └── utils │ │ └── paths │ │ └── DirectoriesTest.kt │ ├── darwinMain │ └── kotlin │ │ └── me │ │ └── sujanpoudel │ │ └── utils │ │ └── paths │ │ └── directories.darwin.kt │ ├── desktopCommonMain │ └── kotlin │ │ └── me │ │ └── sujanpoudel │ │ └── utils │ │ └── paths │ │ └── directories.desktopCommon.kt │ ├── desktopMain │ └── kotlin │ │ └── me │ │ └── sujanpoudel │ │ └── utils │ │ └── paths │ │ └── directories.desktop.kt │ ├── desktopTest │ └── kotlin │ │ └── me │ │ └── sujanpoudel │ │ └── utils │ │ └── paths │ │ └── DesktopDirectoriesTest.kt │ ├── iosTest │ └── kotlin │ │ └── me │ │ └── sujanpoudel │ │ └── utils │ │ └── paths │ │ └── IosDirectoriesTest.kt │ ├── jsMain │ └── kotlin │ │ └── me │ │ └── sujanpoudel │ │ └── utils │ │ └── paths │ │ └── directories.js.kt │ ├── jsTest │ └── kotlin │ │ └── me │ │ └── sujanpoudel │ │ └── utils │ │ └── paths │ │ └── NodeDirectoriesTest.kt │ └── macosTest │ └── kotlin │ └── me │ └── sujanpoudel │ └── utils │ └── paths │ └── MacosDirectoriesTest.kt ├── platform-identifier ├── api │ ├── android │ │ └── platform-identifier.api │ └── desktop │ │ └── platform-identifier.api ├── build.gradle.kts └── src │ ├── androidMain │ └── kotlin │ │ └── me │ │ └── sujanpoudel │ │ └── utils │ │ └── platformIdentifier │ │ └── platform.android.kt │ ├── androidNativeMain │ └── kotlin │ │ └── me │ │ └── sujanpoudel │ │ └── utils │ │ └── platformIdentifier │ │ └── platform.androidNative.kt │ ├── androidNativeTest │ └── kotlin │ │ └── me │ │ └── sujanpoudel │ │ └── utils │ │ └── platformIdentifier │ │ └── PlatformTest.kt │ ├── androidUnitTest │ └── kotlin │ │ └── me │ │ └── sujanpoudel │ │ └── utils │ │ └── platformIdentifier │ │ └── PlatformTest.kt │ ├── appleMain │ └── kotlin │ │ └── me │ │ └── sujanpoudel │ │ └── utils │ │ └── platformIdentifier │ │ └── platform.macos.kt │ ├── appleTest │ └── kotlin │ │ └── me │ │ └── sujanpoudel │ │ └── utils │ │ └── platformIdentifier │ │ └── PlatformTest.kt │ ├── commonMain │ └── kotlin │ │ └── me │ │ └── sujanpoudel │ │ └── utils │ │ └── platformIdentifier │ │ └── platform.kt │ ├── desktopCommonMain │ └── kotlin │ │ └── me │ │ └── sujanpoudel │ │ └── utils │ │ └── platformIdentifier │ │ ├── arch.kt │ │ └── os.kt │ ├── desktopMain │ └── kotlin │ │ └── me │ │ └── sujanpoudel │ │ └── utils │ │ └── platformIdentifier │ │ └── platform.desktop.kt │ ├── desktopTest │ └── kotlin │ │ └── me │ │ └── sujanpoudel │ │ └── utils │ │ └── platformIdentifier │ │ └── PlatformTest.kt │ ├── jsMain │ └── kotlin │ │ └── me │ │ └── sujanpoudel │ │ └── utils │ │ └── platformIdentifier │ │ ├── browser.kt │ │ ├── node.kt │ │ └── platform.js.kt │ ├── jsTest │ └── kotlin │ │ └── me │ │ └── sujanpoudel │ │ └── utils │ │ └── platformIdentifier │ │ └── PlatformTest.kt │ ├── mingwMain │ └── kotlin │ │ └── me │ │ └── sujanpoudel │ │ └── utils │ │ └── platformIdentifier │ │ └── platform.mingw.kt │ ├── mingwTest │ └── kotlin │ │ └── me │ │ └── sujanpoudel │ │ └── utils │ │ └── platformIdentifier │ │ └── PlatformTest.kt │ └── nativeMain │ └── kotlin │ └── me │ └── sujanpoudel │ └── utils │ └── platformIdentifier │ └── CpuArchitecture.kt ├── sample ├── .gitignore ├── androidApp │ ├── .gitignore │ ├── build.gradle.kts │ └── src │ │ └── androidMain │ │ ├── AndroidManifest.xml │ │ ├── kotlin │ │ └── me │ │ │ └── sujanpoudel │ │ │ └── utils │ │ │ └── sample │ │ │ └── MainActivity.kt │ │ └── res │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.webp │ │ ├── ic_launcher_foreground.webp │ │ └── ic_launcher_round.webp │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.webp │ │ ├── ic_launcher_foreground.webp │ │ └── ic_launcher_round.webp │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.webp │ │ ├── ic_launcher_foreground.webp │ │ └── ic_launcher_round.webp │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.webp │ │ ├── ic_launcher_foreground.webp │ │ └── ic_launcher_round.webp │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.webp │ │ ├── ic_launcher_foreground.webp │ │ └── ic_launcher_round.webp │ │ ├── values-night │ │ └── styles.xml │ │ └── values │ │ ├── ic_launcher_background.xml │ │ ├── strings.xml │ │ └── styles.xml ├── desktopApp │ ├── .gitignore │ ├── build.gradle.kts │ └── src │ │ └── jvmMain │ │ └── kotlin │ │ └── Main.kt ├── iosApp │ ├── .gitignore │ ├── iosApp.xcodeproj │ │ └── project.pbxproj │ ├── iosApp.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ └── iosApp │ │ ├── Assets.xcassets │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ └── Contents.json │ │ ├── ContentView.swift │ │ ├── Info.plist │ │ ├── Preview Content │ │ └── Preview Assets.xcassets │ │ │ └── Contents.json │ │ └── iOSApp.swift ├── macosApp │ ├── .gitignore │ ├── build.gradle.kts │ └── src │ │ └── macosMain │ │ └── kotlin │ │ └── main.macos.kt ├── nodeApp │ ├── .gitignore │ ├── build.gradle.kts │ └── src │ │ └── jsMain │ │ └── kotlin │ │ └── me │ │ └── sujanpoudel │ │ └── utils │ │ └── sample │ │ └── main.kt ├── shared │ ├── .gitignore │ ├── build.gradle.kts │ └── src │ │ ├── androidMain │ │ ├── AndroidManifest.xml │ │ └── kotlin │ │ │ └── me │ │ │ └── sujanpoudel │ │ │ └── utils │ │ │ └── sample │ │ │ └── common │ │ │ └── App.kt │ │ ├── commonMain │ │ └── kotlin │ │ │ └── me │ │ │ └── sujanpoudel │ │ │ └── utils │ │ │ └── sample │ │ │ └── common │ │ │ ├── Color.kt │ │ │ ├── Constants.kt │ │ │ ├── MainUI.kt │ │ │ └── Theme.kt │ │ ├── desktopMain │ │ └── kotlin │ │ │ └── me │ │ │ └── sujanpoudel │ │ │ └── utils │ │ │ └── sample │ │ │ └── common │ │ │ └── main.desktop.kt │ │ └── iosMain │ │ └── kotlin │ │ └── me │ │ └── sujanpoudel │ │ └── utils │ │ └── sample │ │ └── common │ │ └── main.ios.kt ├── wearosApp │ ├── .gitignore │ ├── build.gradle.kts │ ├── lint.xml │ ├── proguard-rules.pro │ └── src │ │ └── androidMain │ │ ├── AndroidManifest.xml │ │ ├── kotlin │ │ └── me │ │ │ └── sujanpoudel │ │ │ └── utils │ │ │ └── sample │ │ │ └── wearOs │ │ │ └── MainActivity.kt │ │ └── res │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.webp │ │ ├── ic_launcher_foreground.webp │ │ └── ic_launcher_round.webp │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.webp │ │ ├── ic_launcher_foreground.webp │ │ └── ic_launcher_round.webp │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.webp │ │ ├── ic_launcher_foreground.webp │ │ └── ic_launcher_round.webp │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.webp │ │ ├── ic_launcher_foreground.webp │ │ └── ic_launcher_round.webp │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.webp │ │ ├── ic_launcher_foreground.webp │ │ └── ic_launcher_round.webp │ │ └── values │ │ ├── ic_launcher_background.xml │ │ ├── strings.xml │ │ └── styles.xml └── webApp │ ├── .gitignore │ ├── build.gradle.kts │ └── src │ └── jsMain │ ├── kotlin │ └── me │ │ └── sujanpoudel │ │ └── utils │ │ └── sample │ │ └── main.kt │ └── resources │ └── index.html └── settings.gradle.kts /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig is awesome: https://EditorConfig.org 2 | 3 | root = true 4 | 5 | [*] 6 | charset = utf-8 7 | indent_style = space 8 | indent_size = 2 9 | trim_trailing_whitespace = true 10 | end_of_line = lf 11 | insert_final_newline = true 12 | max_line_length = 120 13 | 14 | [*.{java,kt,kts}] 15 | wildcard_import_limit = 99999 16 | ij_kotlin_name_count_to_use_star_import = 99999 17 | ij_kotlin_name_count_to_use_star_import_for_members = 99999 18 | ij_java_names_count_to_use_import_on_demand = 99999 19 | 20 | ktlint_code_style = ktlint_official 21 | ktlint_experimental = disabled 22 | ktlint_standard_filename = disabled 23 | ktlint_standard_annotation = disabled 24 | ktlint_function_naming_ignore_when_annotated_with = Composable 25 | ktlint_function_signature_body_expression_wrapping = default 26 | ktlint_standard_multiline-expression-wrapping = disabled 27 | ktlint_standard_string-template-indent = disabled 28 | ktlint_function_signature_rule_force_multiline_when_parameter_count_greater_or_equal_than = 4 29 | 30 | -------------------------------------------------------------------------------- /.github/workflows/build-linux.yml: -------------------------------------------------------------------------------- 1 | name: Build Linux 2 | 3 | on: 4 | workflow_call: 5 | workflow_dispatch: 6 | 7 | jobs: 8 | build: 9 | runs-on: ubuntu-latest 10 | env: 11 | GRADLE_OPTS: -Dorg.gradle.jvmargs="-Xmx3g" 12 | 13 | steps: 14 | - uses: actions/checkout@v4 15 | 16 | - name: JDK setup 17 | uses: actions/setup-java@v4 18 | with: 19 | java-version: 17 20 | distribution: corretto 21 | 22 | - name: Cache 23 | uses: actions/cache@v4 24 | with: 25 | path: | 26 | ./build 27 | ./.gradle 28 | ~/.gradle/caches 29 | ~/.gradle/wrapper 30 | ~/.m2/repository 31 | ~/.konan 32 | key: ${{ runner.os }}-gradle-${{ hashFiles('*.gradle.kts') }} 33 | restore-keys: | 34 | ${{ runner.os }}-gradle- 35 | 36 | - name: Tests 37 | run: ./gradlew allTest --parallel --no-daemon --stacktrace 38 | 39 | - name: Lint and Static analysis 40 | run: ./gradlew detekt ktlintCheck --no-daemon --stacktrace 41 | 42 | - name: Validate api compatibility 43 | run: ./gradlew apiCheck --no-daemon --stacktrace 44 | 45 | - name: Build Artifacts 46 | run: ./gradlew publishToMavenLocal 47 | 48 | -------------------------------------------------------------------------------- /.github/workflows/build-macos.yml: -------------------------------------------------------------------------------- 1 | name: Build macOS 2 | 3 | on: 4 | workflow_call: 5 | workflow_dispatch: 6 | 7 | jobs: 8 | build: 9 | runs-on: macos-latest 10 | 11 | env: 12 | GRADLE_OPTS: -Dorg.gradle.jvmargs="-Xmx3g" 13 | 14 | steps: 15 | - uses: actions/checkout@v4 16 | 17 | - name: JDK setup 18 | uses: actions/setup-java@v4 19 | with: 20 | java-version: 17 21 | distribution: corretto 22 | 23 | - name: Cache 24 | uses: actions/cache@v4 25 | with: 26 | path: | 27 | ./build 28 | ./.gradle 29 | ~/.gradle/caches 30 | ~/.gradle/wrapper 31 | ~/.m2/repository 32 | ~/.konan 33 | 34 | key: ${{ runner.os }}-gradle-${{ hashFiles('*.gradle.kts') }} 35 | restore-keys: | 36 | ${{ runner.os }}-gradle- 37 | 38 | - name: Tests 39 | run: ./gradlew allTests -x tvosSimulatorArm64Test -x watchosSimulatorArm64Test 40 | 41 | - name: Validate api compatibility 42 | run: ./gradlew apiCheck --no-daemon --stacktrace 43 | 44 | - name: Mac build 45 | run: | 46 | ./gradlew \ 47 | publishIosArm64PublicationToMavenLocal \ 48 | publishIosSimulatorArm64PublicationToMavenLocal \ 49 | publishIosX64PublicationToMavenLocal \ 50 | publishMacosX64PublicationToMavenLocal \ 51 | publishMacosArm64PublicationToMavenLocal \ 52 | publishWatchosArm64PublicationToMavenLocal \ 53 | publishWatchosArm32PublicationToMavenLocal \ 54 | publishWatchosSimulatorArm64PublicationToMavenLocal \ 55 | publishTvosArm64PublicationToMavenLocal \ 56 | publishTvosSimulatorArm64PublicationToMavenLocal \ 57 | publishTvosX64PublicationToMavenLocal \ 58 | --no-daemon --stacktrace 59 | -------------------------------------------------------------------------------- /.github/workflows/build-windows.yml: -------------------------------------------------------------------------------- 1 | name: Build Linux 2 | 3 | on: 4 | workflow_call: 5 | workflow_dispatch: 6 | 7 | jobs: 8 | build: 9 | runs-on: windows-latest 10 | env: 11 | GRADLE_OPTS: -Dorg.gradle.jvmargs="-Xmx3g" 12 | 13 | steps: 14 | - uses: actions/checkout@v4 15 | 16 | - name: JDK setup 17 | uses: actions/setup-java@v4 18 | with: 19 | java-version: | 20 | 11 21 | 17 22 | distribution: corretto 23 | 24 | - name: Cache 25 | uses: actions/cache@v4 26 | with: 27 | path: | 28 | ./build 29 | ./.gradle 30 | ~/.gradle/caches 31 | ~/.gradle/wrapper 32 | ~/.m2/repository 33 | key: ${{ runner.os }}-gradle-${{ hashFiles('*.gradle.kts') }} 34 | restore-keys: | 35 | ${{ runner.os }}-gradle- 36 | 37 | - name: Tests 38 | run: ./gradlew allTest --parallel --no-daemon --stacktrace 39 | 40 | - name: Build Artifacts 41 | run: ./gradlew publishToMavenLocal 42 | 43 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | branches: [ "main", "develop" ] 6 | paths-ignore: 7 | - "**/*.md" 8 | pull_request: 9 | branches: [ "main", "develop" ] 10 | paths-ignore: 11 | - "**/*.md" 12 | workflow_call: 13 | 14 | permissions: 15 | contents: read 16 | 17 | jobs: 18 | build-linux: 19 | name: Build Linux 20 | uses: ./.github/workflows/build-linux.yml 21 | 22 | build-macos: 23 | name: Build macOS 24 | uses: ./.github/workflows/build-macos.yml 25 | 26 | build-windows: 27 | name: Build Windows 28 | uses: ./.github/workflows/build-windows.yml 29 | -------------------------------------------------------------------------------- /.github/workflows/release.yaml: -------------------------------------------------------------------------------- 1 | name: Release 2 | 3 | on: 4 | push: 5 | tags: 6 | - '*.*.*' 7 | jobs: 8 | release_artifacts: 9 | strategy: 10 | matrix: 11 | os: [ 'macos-latest' ] 12 | runs-on: ${{ matrix.os }} 13 | 14 | outputs: 15 | VERSION_NAME: ${{ steps.extract_version_name.outputs.VERSION_NAME }} 16 | 17 | steps: 18 | - uses: actions/checkout@v3 19 | 20 | - name: JDK setup 21 | uses: actions/setup-java@v4 22 | with: 23 | java-version: 17 24 | distribution: corretto 25 | 26 | - name: Setup Gradle 27 | uses: gradle/gradle-build-action@v2.11.1 28 | 29 | - name: Cache 30 | uses: actions/cache@v4 31 | with: 32 | path: | 33 | ./build 34 | ./.gradle 35 | ~/.gradle/caches 36 | ~/.gradle/wrapper 37 | ~/.m2/repository 38 | ~/.konan 39 | 40 | key: ${{ runner.os }}-gradle-${{ hashFiles('*.gradle.kts') }} 41 | restore-keys: | 42 | ${{ runner.os }}-gradle- 43 | 44 | - name: Validate api compatibility 45 | run: ./gradlew apiCheck --no-daemon --stacktrace 46 | 47 | - name: Get version name 48 | id: extract_version_name 49 | run: | 50 | TAG=${{github.ref_name}} 51 | VERSION_NAME="${TAG/v/""}" 52 | echo "VERSION_NAME=$VERSION_NAME" >> $GITHUB_OUTPUT 53 | 54 | - name: Prepare environment 55 | run: echo '${{ secrets.GPG_KEY_CONTENTS }}' | base64 -d > '${{ secrets.SIGNING_SECRET_KEY_RING_FILE }}' 56 | 57 | - name: Release Artifacts 58 | run: | 59 | ./gradlew publishAllPublicationsToMavenCentralRepository \ 60 | -PVERSION_NAME=${{ steps.extract_version_name.outputs.VERSION_NAME }} \ 61 | -PmavenCentralUsername=${{ secrets.OSSRH_USERNAME }} \ 62 | -PmavenCentralPassword=${{ secrets.OSSRH_PASSWORD }} \ 63 | -Psigning.keyId=${{ secrets.SIGNING_KEY_ID }} \ 64 | -Psigning.password=${{ secrets.SIGNING_KEY_PASSWORD }} \ 65 | -Psigning.secretKeyRingFile=$(pwd)/${{ secrets.SIGNING_SECRET_KEY_RING_FILE }} 66 | 67 | github_release: 68 | needs: [ release_artifacts ] 69 | name: Create Release 70 | runs-on: ubuntu-latest 71 | steps: 72 | - uses: actions/checkout@v4 73 | 74 | - name: Extract release notes 75 | id: release_notes 76 | uses: ffurrer2/extract-release-notes@v1 77 | with: 78 | prerelease: ${{ contains(needs.release_artifacts.outputs.VERSION_NAME,'alpha') || contains(needs.release_artifacts.outputs.VERSION_NAME,'beta') }} 79 | 80 | - name: Create release 81 | uses: softprops/action-gh-release@v1 82 | with: 83 | prerelease: ${{ contains(needs.release_artifacts.outputs.VERSION_NAME,'alpha') || contains(needs.release_artifacts.outputs.VERSION_NAME,'beta') }} 84 | body: ${{ steps.release_notes.outputs.release_notes }} 85 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | !.idea/runConfigurations/ 4 | .idea 5 | .DS_Store 6 | build 7 | captures 8 | .externalNativeBuild 9 | .cxx 10 | local.properties 11 | xcuserdata 12 | 13 | -------------------------------------------------------------------------------- /.idea/codeStyles/Project.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 14 | 19 | 20 | 21 | 23 | 24 | 180 | 181 | 183 | 184 | -------------------------------------------------------------------------------- /.idea/codeStyles/codeStyleConfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | -------------------------------------------------------------------------------- /.idea/copyright/Multiplatform_Paths.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | -------------------------------------------------------------------------------- /.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/runConfigurations/IOS_App.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | -------------------------------------------------------------------------------- /.idea/runConfigurations/mp_utils_sample_desktopApp__run_.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 16 | 18 | true 19 | true 20 | false 21 | false 22 | 23 | 24 | -------------------------------------------------------------------------------- /.idea/runConfigurations/mp_utils_sample_macosApp__runDebugExecutableMacosArm64_.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 16 | 18 | true 19 | true 20 | false 21 | false 22 | 23 | 24 | -------------------------------------------------------------------------------- /.idea/runConfigurations/mp_utils_sample_nodeApp__jsNodeDevelopmentRun_.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 16 | 18 | true 19 | true 20 | false 21 | false 22 | 23 | 24 | -------------------------------------------------------------------------------- /.idea/runConfigurations/mp_utils_sample_webApp__jsBrowserDevelopmentRun_.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 16 | 18 | true 19 | true 20 | false 21 | false 22 | 23 | 24 | -------------------------------------------------------------------------------- /.idea/runConfigurations/sample_androidApp.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 69 | -------------------------------------------------------------------------------- /.idea/runConfigurations/sample_wearosApp.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 69 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file. 4 | 5 | ## [Unreleased] 6 | 7 | ### Fixes 8 | 9 | ### Changes 10 | 11 | ## [0.2.2] - 2024-05-13 12 | 13 | ### Fixes 14 | 15 | - [BUG] Wrong os type on Windows #36 16 | 17 | ## [0.2.1] - 2024-04-23 18 | 19 | ### Fixes 20 | 21 | - NSHomeDirectory is only allowed to be written on iOS Simulators, but not on physical devices #33 22 | 23 | ## [0.2.1] - 2024-04-23 24 | 25 | ### Fixes 26 | 27 | - NSHomeDirectory is only allowed to be written on iOS Simulators, but not on physical devices #33 28 | 29 | ## [0.2.0] - 2024-04-21 30 | 31 | This version contains general house keeping, dependencies updates and ci improvement for better maintainability. 32 | 33 | ### Breaking Changes 34 | 35 | - Group name has been updated to `me.sujanpoudel.multiplatform.utils` from `me.sujanpoudel.mputils` 36 | - Artifact `paths` has been renamed to `multiplatform-paths`. 37 | 38 | > [!NOTE] 39 | > Follow [migration guide](https://github.com/psuzn/multiplatform-paths/blob/main/migration-guides.md##v01x-to-v2x) to migrate from v0.1 to v0.2. 40 | 41 | ## [0.1.1] - 2023-12-28 42 | 43 | ### Added 44 | 45 | - Support for `iosX64` target. 46 | 47 | ### Changed 48 | 49 | - Renamed `applicationCacheDir` to `appCacheDirectory`. 50 | - Exposed `kotlinx-io-core` as a transitive dependency. 51 | 52 | ## [0.1.0] - 2023-12-21 53 | 54 | Initial Cut (Get it?). 55 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Multiplatform Paths 2 | 3 | [![Release](https://img.shields.io/github/v/release/psuzn/multiplatform-paths?label=version&color=blue)](https://github.com/psuzn/multiplatform-paths/releases/latest) 4 | [![CI](https://github.com/psuzn/multiplatform-paths/actions/workflows/ci.yml/badge.svg)](https://github.com/psuzn/multiplatform-paths/actions/workflows/ci.yml) 5 | 6 | [![kotlin](https://img.shields.io/badge/kotlin-1.9.23-blue?logo=kotlin)](http://kotlinlang.org) 7 | 8 | ![license](https://img.shields.io/github/license/psuzn/multiplatform-paths?label=License) 9 | 10 | > [!NOTE] 11 | > Follow [migration guide](https://github.com/psuzn/multiplatform-paths/blob/main/migration-guides.md##v01x-to-v2x) to migrate from v0.1 to v0.2. 12 | 13 | Platform-specific application home and cache directories for KMP. 14 | 15 | ![badge-JVM](https://img.shields.io/badge/JVM(desktop)-orange) 16 | ![badge-Android](https://img.shields.io/badge/Android-dodgerblue?logo=android&logoColor=white) 17 | ![badge-iOS](https://img.shields.io/badge/iOS-gray?logo=apple&logoColor=silver) 18 | ![badge-macOS](https://img.shields.io/badge/macOS-gray?logo=apple&logoColor=silver) 19 | ![badge-Js(Node)](https://img.shields.io/badge/Js(Node)-limegreen?logo=nodedotjs&logoColor=white) 20 | 21 | - [Path Mapping](#setup) 22 | - [Setup](#setup) 23 | - [Usage](#usage) 24 | - [App data directory](#app-data-directory) 25 | - [App cache directory](#app-cache-directory) 26 | 27 | ### Path Mapping 28 | 29 | | Platform | Cache Directory | Data Directory | 30 | |-----------------------|--------------------------------------------|--------------------------------------------| 31 | | Android | `context.cacheDir` | `ApplicationInfo.dataDir` | 32 | | IOS/IpadOs/WatchOs | `NSCachesDirectory` | `NSApplicationSupportDirectory` | 33 | | Mac (native/jvm/node) | `~/Library/Caches/` | `~/Library/Application Support/` | 34 | | Windows (jvm/node) | `C:\Users\\AppData/Caches/` | `C:\Users\\AppData/>` | 35 | | Linux (jvm/node) | `~/.cache/` | `~/local/share/` | 36 | 37 | ### Setup 38 | 39 | ```kotlin 40 | repositories { 41 | mavenCentral() 42 | } 43 | 44 | dependencies { 45 | implementation("me.sujanpoudel.multiplatform.utils:multiplatform-paths:0.2.2") 46 | } 47 | ``` 48 | 49 | ### Usage 50 | 51 | #### App data directory 52 | 53 | ```kotlin 54 | import me.sujanpoudel.utils.paths.appDataDirectory 55 | 56 | val packageName = "example.com.app" 57 | 58 | val dataDirectory = appDataDirectory(packageName) 59 | ``` 60 | 61 | This will return `ApplicationInfo.dataDir` on android, `NSApplicationSupportDirectory` on IOS and equivalent platform specific data 62 | directory on other platforms. 63 | 64 | #### App cache directory 65 | 66 | ```kotlin 67 | import me.sujanpoudel.utils.paths.appCacheDirectory 68 | 69 | val packageName = "example.com.app" 70 | 71 | val dataDirectory = appCacheDirectory(packageName) 72 | ``` 73 | 74 | This will return `Context.cacheDir` on android, `NSCachesDirectory` on IOS and equivalent platform specific caches 75 | directory on other platforms 76 | 77 | 78 | ## Other Libraries from this Repository. 79 | - `platform-identifier` : Identify the current platform. 80 | - `context-provider` : Get android context anywhere on your android source set. 81 | 82 | ## Table of content 83 | 84 | - [Platform Identifier](#platform-identifier) 85 | - [Setup](#setup-1) 86 | - [Usage](#usage-1) 87 | - [Get current running platform info](#get-current-running-platform-info) 88 | - [Possible return values](#possible-return-values) 89 | - [Context Provider](#context-provider) 90 | - [Setup](#setup-2) 91 | - [Usage](#usage-2) 92 | - [Get Android Context]() 93 | - [Contributions](#contributions) 94 | - [License](#license) 95 | 96 | 97 | 98 | ## Platform Identifier 99 | 100 | ![JVM(desktop)](https://img.shields.io/badge/JVM_(desktop)-orange?logo=freedesktopdoporg) 101 | ![Android](https://img.shields.io/badge/Android-dodgerblue?logo=android&logoColor=white) 102 | ![Android-native](https://img.shields.io/badge/Native-dodgerblue?logo=android&logoColor=white) 103 | ![iOS](https://img.shields.io/badge/iOS-gray?logo=apple&logoColor=silver) 104 | ![macOS](https://img.shields.io/badge/macOS-gray?logo=apple&logoColor=silver) 105 | ![windows](https://img.shields.io/badge/Windows-deepskyblue?logo=windows&logoColor=white) 106 | ![Js(Node)](https://img.shields.io/badge/Javascript-lightslategrey?logo=javascript&logoColor=white) 107 | 108 | ### Setup 109 | 110 | ```kotlin 111 | repositories { 112 | mavenCentral() 113 | } 114 | 115 | dependencies { 116 | implementation("me.sujanpoudel.multiplatform.utils:platform-identifier:0.2.2") 117 | } 118 | ``` 119 | 120 | ### Usage 121 | 122 | #### Get current running platform info 123 | 124 | ```kotlin 125 | import me.sujanpoudel.multiplatform.utils.platformIdentifier.platform 126 | 127 | val currentPlatform = platform() 128 | 129 | ``` 130 | 131 | #### Possible return values 132 | 133 | It returns `Platform` sealed class: 134 | 135 | ```kotlin 136 | sealed class Platform { 137 | sealed class JS : Platform() { 138 | data class Node(val os: OS, val nodeVersion: String, val v8Version: String) : JS() 139 | data class Browser(val userAgent: String) : JS() 140 | } 141 | 142 | sealed class OS(open val arch: Arch) : Platform() { 143 | data class Unknown(override val arch: Arch, val version: String) : OS(arch) 144 | data class MacOs(override val arch: Arch, val version: String) : OS(arch) 145 | data class IOS(override val arch: Arch, val version: String, val isSimulator: Boolean) : OS(arch) 146 | data class WatchOs(override val arch: Arch, val version: String, val isSimulator: Boolean) : OS(arch) 147 | data class TvOs(override val arch: Arch, val version: String, val isSimulator: Boolean) : OS(arch) 148 | data class Android(override val arch: Arch, val buildNumber: Int, val androidVersion: String, val isWatch: Boolean, val isTv: Boolean) : OS(arch) 149 | 150 | data class Linux(override val arch: Arch, val version: String) : OS(arch) 151 | data class Windows(override val arch: Arch, val version: String) : OS(arch) 152 | } 153 | } 154 | ``` 155 | 156 | where,`Arch` is an enum representing CPU architecture 157 | 158 | ```kotlin 159 | enum class Arch { 160 | UNKNOWN, 161 | X64, 162 | X86, 163 | ARM_X64, 164 | ARM_X32, 165 | } 166 | ``` 167 | 168 | ## Context Provider 169 | 170 | ![Android](https://img.shields.io/badge/Android-dodgerblue?logo=android&logoColor=white) 171 | 172 | ### Setup 173 | 174 | ```kotlin 175 | repositories { 176 | mavenCentral() 177 | } 178 | 179 | dependencies { 180 | implementation("me.sujanpoudel.multiplatform.utils:context-provider:0.2.2") 181 | } 182 | ``` 183 | 184 | ### Usage 185 | 186 | #### Get Android Context 187 | 188 | ```kotlin 189 | import me.sujanpoudel.utils.contextProvider.applicationContext 190 | import android.content.Context 191 | 192 | val context: Context = applicationContext 193 | 194 | ``` 195 | 196 | ### Contributions 197 | 198 | Contributions are always welcome!. If you'd like to contribute, please feel free to create a PR or 199 | open an issue. 200 | 201 | ## License 202 | 203 | ``` 204 | Copyright 2023 Sujan Poudel 205 | 206 | Licensed under the Apache License, Version 2.0 (the "License"); 207 | you may not use this file except in compliance with the License. 208 | You may obtain a copy of the License at 209 | 210 | https://www.apache.org/licenses/LICENSE-2.0 211 | 212 | Unless required by applicable law or agreed to in writing, software 213 | distributed under the License is distributed on an "AS IS" BASIS, 214 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 215 | See the License for the specific language governing permissions and 216 | limitations under the License. 217 | ``` 218 | -------------------------------------------------------------------------------- /build-logic/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /build-logic/build.gradle.kts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Sujan Poudel 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import io.gitlab.arturbosch.detekt.DetektPlugin 18 | import org.jlleitschuh.gradle.ktlint.KtlintPlugin 19 | 20 | plugins { 21 | `kotlin-dsl` 22 | alias(libs.plugins.kotlin.jvm) 23 | alias(libs.plugins.ktlint) 24 | alias(libs.plugins.detekt) 25 | } 26 | 27 | kotlin { 28 | jvmToolchain(11) 29 | } 30 | 31 | repositories { 32 | mavenCentral() 33 | gradlePluginPortal() 34 | google() 35 | } 36 | 37 | dependencies { 38 | compileOnly(libs.plugins.kotlin.jvm.asDependency()) 39 | compileOnly(libs.plugins.kotlin.multiplatform.asDependency()) 40 | compileOnly(libs.plugins.compose.asDependency()) 41 | compileOnly(libs.plugins.android.application.asDependency()) 42 | compileOnly(libs.plugins.android.library.asDependency()) 43 | compileOnly(libs.plugins.ktlint.asDependency()) 44 | compileOnly(libs.plugins.detekt.asDependency()) 45 | compileOnly(libs.plugins.mavenPublish.asDependency()) 46 | 47 | implementation(files(libs.javaClass.superclass.protectionDomain.codeSource.location)) 48 | } 49 | 50 | allprojects { 51 | apply() 52 | apply() 53 | 54 | ktlint { 55 | version = rootProject.libs.versions.ktlint.get() 56 | 57 | filter { 58 | exclude { 59 | it.file.absoluteFile.startsWith(layout.buildDirectory.asFile.get().absolutePath) 60 | } 61 | } 62 | } 63 | 64 | detekt { 65 | config.setFrom(rootProject.files("./../config/detekt/detekt.yml")) 66 | } 67 | } 68 | 69 | gradlePlugin { 70 | plugins { 71 | register("modulePlugin") { 72 | id = "module" 73 | implementationClass = "ModuleConventionPlugin" 74 | } 75 | 76 | register("androidApplication") { 77 | id = "android-application" 78 | implementationClass = "AndroidAppConventionPlugin" 79 | } 80 | 81 | register("multiplatformLibraryPlugin") { 82 | id = "multiplatform-library" 83 | implementationClass = "MultiPlatformLibraryConventionPlugin" 84 | } 85 | 86 | register("packagingPlugin") { 87 | id = "packaging" 88 | implementationClass = "PackagingConventionPlugin" 89 | } 90 | } 91 | } 92 | 93 | fun Provider.asDependency(): Provider = 94 | this.map { "${it.pluginId}:${it.pluginId}.gradle.plugin:${it.version}" } 95 | -------------------------------------------------------------------------------- /build-logic/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Sujan Poudel 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | pluginManagement { 18 | repositories { 19 | google() 20 | gradlePluginPortal() 21 | mavenCentral() 22 | } 23 | } 24 | 25 | dependencyResolutionManagement { 26 | repositories { 27 | google() 28 | gradlePluginPortal() 29 | mavenCentral() 30 | } 31 | 32 | versionCatalogs { 33 | create("libs") { 34 | from(files("../gradle/libs.versions.toml")) 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /build-logic/src/main/kotlin/AndroidAppConventionPlugin.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Sujan Poudel 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import com.android.build.gradle.internal.dsl.BaseAppModuleExtension 18 | import me.sujanpoudel.utils.apply 19 | import me.sujanpoudel.utils.configureKotlinAndroid 20 | import me.sujanpoudel.utils.libs 21 | import org.gradle.api.Plugin 22 | import org.gradle.api.Project 23 | import org.gradle.kotlin.dsl.configure 24 | import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension 25 | 26 | class AndroidAppConventionPlugin : Plugin { 27 | override fun apply(target: Project): Unit = with(target) { 28 | with(pluginManager) { 29 | apply(libs.plugins.android.application) 30 | apply(libs.plugins.kotlin.multiplatform) 31 | apply(libs.plugins.compose) 32 | apply("module") 33 | } 34 | 35 | configure { 36 | configureKotlinAndroid(this) 37 | 38 | defaultConfig { 39 | applicationId = nameSpace() 40 | targetSdk = libs.versions.targetSdk.get().toInt() 41 | versionCode = sampleVersionCode() 42 | versionName = sampleVersionName() 43 | 44 | vectorDrawables { 45 | useSupportLibrary = true 46 | } 47 | 48 | composeOptions { 49 | kotlinCompilerExtensionVersion = libs.versions.composeCompiler.get() 50 | } 51 | 52 | packaging { 53 | resources { 54 | excludes += "/META-INF/{AL2.0,LGPL2.1}" 55 | } 56 | } 57 | } 58 | } 59 | 60 | configure { 61 | androidTarget() 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /build-logic/src/main/kotlin/ModuleConventionPlugin.kt: -------------------------------------------------------------------------------- 1 | import io.gitlab.arturbosch.detekt.extensions.DetektExtension 2 | import me.sujanpoudel.utils.apply 3 | import me.sujanpoudel.utils.libs 4 | import org.gradle.api.Plugin 5 | import org.gradle.api.Project 6 | import org.gradle.kotlin.dsl.assign 7 | import org.gradle.kotlin.dsl.getByType 8 | import org.jlleitschuh.gradle.ktlint.KtlintExtension 9 | 10 | /* 11 | * Copyright 2024 Sujan Poudel 12 | * 13 | * Licensed under the Apache License, Version 2.0 (the "License"); 14 | * you may not use this file except in compliance with the License. 15 | * You may obtain a copy of the License at 16 | * 17 | * http://www.apache.org/licenses/LICENSE-2.0 18 | * 19 | * Unless required by applicable law or agreed to in writing, software 20 | * distributed under the License is distributed on an "AS IS" BASIS, 21 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 22 | * See the License for the specific language governing permissions and 23 | * limitations under the License. 24 | */ 25 | 26 | class ModuleConventionPlugin : Plugin { 27 | override fun apply(target: Project): Unit = with(target) { 28 | group = group() 29 | version = versionName() 30 | 31 | with(target.pluginManager) { 32 | apply(libs.plugins.ktlint) 33 | apply(libs.plugins.detekt) 34 | } 35 | 36 | configureKtLint() 37 | configureDetekt() 38 | } 39 | } 40 | 41 | private fun Project.configureKtLint(): KtlintExtension = extensions.getByType().apply { 42 | version = rootProject.libs.versions.ktlint.get() 43 | 44 | enableExperimentalRules = false 45 | coloredOutput = true 46 | 47 | filter { 48 | exclude { 49 | it.file.absoluteFile.startsWith(layout.buildDirectory.asFile.get().absolutePath) 50 | } 51 | } 52 | } 53 | 54 | private fun Project.configureDetekt(): DetektExtension = extensions.getByType().apply { 55 | config.setFrom(rootProject.files("config/detekt/detekt.yml")) 56 | } 57 | -------------------------------------------------------------------------------- /build-logic/src/main/kotlin/MultiPlatformLibraryConventionPlugin.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Sujan Poudel 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import com.android.build.gradle.LibraryExtension 18 | import me.sujanpoudel.utils.apply 19 | import me.sujanpoudel.utils.configureCommonMultiplatformTargets 20 | import me.sujanpoudel.utils.configureKotlinAndroid 21 | import me.sujanpoudel.utils.libs 22 | import org.gradle.api.Plugin 23 | import org.gradle.api.Project 24 | import org.gradle.kotlin.dsl.configure 25 | import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension 26 | 27 | class MultiPlatformLibraryConventionPlugin : Plugin { 28 | override fun apply(target: Project): Unit = with(target) { 29 | with(pluginManager) { 30 | apply(libs.plugins.android.library) 31 | apply(libs.plugins.kotlin.multiplatform) 32 | apply("module") 33 | } 34 | 35 | configure { 36 | configureKotlinAndroid(this) 37 | } 38 | 39 | configure { 40 | configureCommonMultiplatformTargets() 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /build-logic/src/main/kotlin/PackagingConventionPlugin.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Sujan Poudel 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import com.vanniktech.maven.publish.MavenPublishBaseExtension 18 | import com.vanniktech.maven.publish.SonatypeHost 19 | import me.sujanpoudel.utils.apply 20 | import me.sujanpoudel.utils.libs 21 | import org.gradle.api.Plugin 22 | import org.gradle.api.Project 23 | import org.gradle.api.publish.PublishingExtension 24 | import org.gradle.api.publish.maven.MavenPublication 25 | import org.gradle.kotlin.dsl.getByType 26 | import org.gradle.kotlin.dsl.withType 27 | import org.gradle.plugins.signing.SigningExtension 28 | 29 | class PackagingConventionPlugin : Plugin { 30 | override fun apply(target: Project): Unit = with(target) { 31 | group = group() 32 | version = versionName() 33 | 34 | with(pluginManager) { 35 | apply(libs.plugins.mavenPublish) 36 | apply("signing") 37 | apply(libs.plugins.binaryCompatibilityValidator) 38 | } 39 | 40 | configurePublishingMetadata() 41 | 42 | extensions.getByType().apply { 43 | signAllPublications() 44 | publishToMavenCentral(SonatypeHost.CENTRAL_PORTAL) 45 | } 46 | } 47 | } 48 | 49 | fun Project.configurePublishingMetadata(): PublishingExtension = extensions.getByType().apply { 50 | publications.withType().configureEach { 51 | pom { 52 | url.set("https://github.com/psuzn/multiplatform-paths") 53 | 54 | licenses { 55 | license { 56 | name.set("The Apache License, Version 2.0") 57 | url.set("http://www.apache.org/licenses/LICENSE-2.0.txt") 58 | distribution.set("http://www.apache.org/licenses/LICENSE-2.0.txt") 59 | } 60 | } 61 | 62 | developers { 63 | developer { 64 | id.set("psuzn") 65 | name.set("Sujan Poudel") 66 | url.set("https://github.com/psuzn/") 67 | } 68 | } 69 | 70 | scm { 71 | connection.set("scm:git:https://github.com/psuzn/multiplatform-paths.git") 72 | developerConnection.set("scm:git:ssh://github.com/psuzn/multiplatform-paths.git") 73 | url.set("https://github.com/psuzn/multiplatform-paths/tree/main") 74 | } 75 | } 76 | 77 | repositories { 78 | mavenLocal() 79 | } 80 | } 81 | 82 | extensions.getByType().apply { 83 | isRequired = true 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /build-logic/src/main/kotlin/me/sujanpoudel/utils/Artifacts.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Sujan Poudel 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import org.gradle.api.Project 18 | import org.gradle.kotlin.dsl.support.uppercaseFirstChar 19 | 20 | fun Project.group() = property("GROUP") as String 21 | 22 | fun Project.versionName() = property("VERSION_NAME") as String 23 | 24 | @Suppress("FunctionOnlyReturningConstant") 25 | fun Project.sampleVersionCode() = 1 26 | 27 | @Suppress("FunctionOnlyReturningConstant") 28 | fun Project.sampleVersionName() = "0.0.1" 29 | 30 | private fun Project.nameAsIdentifier() = name 31 | .split("-") 32 | .mapIndexed { index: Int, name: String -> 33 | if (index == 0) { 34 | name 35 | } else { 36 | name.uppercaseFirstChar() 37 | } 38 | }.joinToString("") 39 | 40 | fun Project.nameSpace() = "$group.${nameAsIdentifier()}" 41 | -------------------------------------------------------------------------------- /build-logic/src/main/kotlin/me/sujanpoudel/utils/KotlinAndroid.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Sujan Poudel 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package me.sujanpoudel.utils 18 | 19 | import com.android.build.api.dsl.CommonExtension 20 | import com.android.build.gradle.tasks.factory.AndroidUnitTest 21 | import nameSpace 22 | import org.gradle.api.JavaVersion 23 | import org.gradle.api.Project 24 | import org.gradle.kotlin.dsl.withType 25 | import org.jetbrains.kotlin.gradle.tasks.KotlinCompile 26 | 27 | /** 28 | * Configure base Kotlin with Android options 29 | */ 30 | internal fun Project.configureKotlinAndroid(commonExtension: CommonExtension<*, *, *, *, *>) = with(commonExtension) { 31 | namespace = nameSpace() 32 | compileSdk = libs.versions.compileSdk.get().toInt() 33 | 34 | defaultConfig { 35 | minSdk = libs.versions.minSdk.get().toString().toInt() 36 | } 37 | 38 | lint { 39 | warningsAsErrors = true 40 | abortOnError = true 41 | disable += 42 | listOf( 43 | "GradleDependency", 44 | "AndroidGradlePluginVersion", 45 | ) 46 | } 47 | 48 | compileOptions { 49 | sourceCompatibility = JavaVersion.VERSION_17 50 | targetCompatibility = JavaVersion.VERSION_17 51 | } 52 | 53 | buildFeatures { 54 | buildConfig = true 55 | } 56 | 57 | tasks.withType { 58 | useJUnitPlatform() 59 | } 60 | 61 | testOptions { 62 | unitTests { 63 | isIncludeAndroidResources = true 64 | } 65 | } 66 | 67 | configureKotlin() 68 | } 69 | 70 | /** 71 | * Configure base Kotlin options 72 | */ 73 | fun Project.configureKotlin() { 74 | tasks.withType().configureEach { 75 | kotlinOptions { 76 | jvmTarget = JavaVersion.VERSION_17.toString() 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /build-logic/src/main/kotlin/me/sujanpoudel/utils/KotlinMultiplatform.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Sujan Poudel 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package me.sujanpoudel.utils 18 | 19 | import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension 20 | 21 | internal fun KotlinMultiplatformExtension.configureCommonMultiplatformTargets() { 22 | applyDefaultHierarchyTemplate() 23 | 24 | androidTarget() 25 | 26 | jvm("desktop") 27 | 28 | iosArm64() 29 | iosX64() 30 | iosSimulatorArm64() 31 | 32 | macosX64() 33 | macosArm64() 34 | } 35 | -------------------------------------------------------------------------------- /build-logic/src/main/kotlin/me/sujanpoudel/utils/Libs.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Sujan Poudel 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package me.sujanpoudel.utils 18 | 19 | import org.gradle.accessors.dm.LibrariesForLibs 20 | import org.gradle.api.Project 21 | import org.gradle.kotlin.dsl.the 22 | 23 | val Project.libs: LibrariesForLibs 24 | get() = the() 25 | -------------------------------------------------------------------------------- /build-logic/src/main/kotlin/me/sujanpoudel/utils/PluginManager.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Sujan Poudel 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package me.sujanpoudel.utils 18 | 19 | import org.gradle.api.plugins.PluginManager 20 | import org.gradle.api.provider.Provider 21 | import org.gradle.plugin.use.PluginDependency 22 | 23 | fun PluginManager.apply(provider: Provider) { 24 | apply(provider.get().pluginId) 25 | } 26 | -------------------------------------------------------------------------------- /build.gradle.kts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Sujan Poudel 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import io.gitlab.arturbosch.detekt.Detekt 18 | import org.jlleitschuh.gradle.ktlint.tasks.KtLintCheckTask 19 | import org.jlleitschuh.gradle.ktlint.tasks.KtLintFormatTask 20 | 21 | 22 | plugins { 23 | alias(libs.plugins.kotlin.jvm) apply false 24 | alias(libs.plugins.kotlin.multiplatform) apply false 25 | alias(libs.plugins.kotlin.android) apply false 26 | alias(libs.plugins.android.application) apply false 27 | alias(libs.plugins.android.library) apply false 28 | alias(libs.plugins.compose) apply false 29 | alias(libs.plugins.ktlint) apply false 30 | alias(libs.plugins.detekt) apply false 31 | alias(libs.plugins.mavenPublish) apply false 32 | alias(libs.plugins.binaryCompatibilityValidator) apply false 33 | id("module") 34 | base 35 | } 36 | 37 | tasks.withType { 38 | dependsOn(gradle.includedBuild("build-logic").task(":ktlintFormat")) 39 | } 40 | 41 | tasks.withType { 42 | dependsOn(gradle.includedBuild("build-logic").task(":ktlintCheck")) 43 | } 44 | 45 | tasks.withType { 46 | dependsOn(gradle.includedBuild("build-logic").task(":detekt")) 47 | } 48 | -------------------------------------------------------------------------------- /context-provider/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /context-provider/api/context-provider.api: -------------------------------------------------------------------------------- 1 | public final class me/sujanpoudel/utils/contextProvider/ApplicationContextInitializerKt { 2 | public static final fun getApplicationContext ()Landroid/content/Context; 3 | } 4 | 5 | -------------------------------------------------------------------------------- /context-provider/build.gradle.kts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Sujan Poudel 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | plugins { 18 | id("module") 19 | id("packaging") 20 | alias(libs.plugins.android.library) 21 | alias(libs.plugins.kotlin.multiplatform) 22 | } 23 | 24 | kotlin { 25 | 26 | jvmToolchain(11) 27 | 28 | androidTarget() 29 | 30 | sourceSets { 31 | androidMain { 32 | dependencies { 33 | api(libs.startup.runtime) 34 | } 35 | } 36 | 37 | val androidUnitTest by getting { 38 | dependencies { 39 | implementation(libs.junit) 40 | implementation(libs.ext.junit) 41 | implementation(libs.espresso.core) 42 | implementation(libs.robolectric) 43 | } 44 | } 45 | } 46 | } 47 | 48 | android { 49 | namespace = "${group()}.contextProvider" 50 | compileSdk = libs.versions.compileSdk.get().toInt() 51 | 52 | defaultConfig { 53 | minSdk = libs.versions.minSdk.get().toInt() 54 | } 55 | 56 | testOptions { 57 | unitTests { 58 | isIncludeAndroidResources = true 59 | } 60 | } 61 | } 62 | 63 | mavenPublishing { 64 | pom { 65 | name.set("Platform Identifier") 66 | description.set("Get android context anywhere on your android source-set.") 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /context-provider/src/androidMain/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 11 | 12 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /context-provider/src/androidMain/kotlin/me/sujanpoudel/utils/contextProvider/ApplicationContextInitializer.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Sujan Poudel 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package me.sujanpoudel.utils.contextProvider 18 | 19 | import android.content.Context 20 | import androidx.startup.Initializer 21 | 22 | /** 23 | * Application scoped context for current app session 24 | */ 25 | lateinit var applicationContext: Context 26 | private set 27 | 28 | internal class ApplicationContextInitializer : Initializer { 29 | override fun create(context: Context): Context = context.also { 30 | applicationContext = it.applicationContext 31 | } 32 | 33 | override fun dependencies(): List>> = emptyList() 34 | } 35 | -------------------------------------------------------------------------------- /context-provider/src/androidUnitTest/kotlin/me/sujanpoudel/utils/contextProvider/ApplicationContextInitializerTest.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Sujan Poudel 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package me.sujanpoudel.utils.contextProvider 18 | 19 | import android.app.Application 20 | import android.content.Context 21 | import android.net.Uri 22 | import androidx.test.core.app.ApplicationProvider 23 | import org.junit.Assert.assertEquals 24 | import org.junit.Assert.assertTrue 25 | import org.junit.Test 26 | import org.junit.runner.RunWith 27 | import org.robolectric.RobolectricTestRunner 28 | import org.robolectric.shadows.ShadowContentResolver 29 | 30 | @RunWith(RobolectricTestRunner::class) 31 | class ApplicationContextInitializerTest { 32 | @Test 33 | fun `should initialize application context`() { 34 | val context = ApplicationProvider.getApplicationContext() 35 | 36 | val authority = "${context.packageName}.androidx-startup" 37 | 38 | val uri = Uri.Builder() 39 | .scheme("content") 40 | .authority(authority) 41 | .build() 42 | 43 | ShadowContentResolver.getProvider(uri) 44 | 45 | assertEquals(applicationContext, context) 46 | assertTrue(applicationContext is Application) 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | #Gradle 2 | org.gradle.caching = true 3 | org.gradle.jvmargs=-Xmx4048M -Dfile.encoding=UTF-8 -Dkotlin.daemon.jvm.options\="-Xmx4048M" 4 | 5 | #Kotlin 6 | kotlin.code.style=official 7 | 8 | #Android 9 | android.useAndroidX=true 10 | android.nonTransitiveRClass=true 11 | 12 | #MPP 13 | kotlin.mpp.enableCInteropCommonization=true 14 | kotlin.mpp.androidSourceSetLayoutVersion=2 15 | org.jetbrains.compose.experimental.uikit.enabled=true 16 | org.jetbrains.compose.experimental.macos.enabled=true 17 | org.jetbrains.compose.experimental.jscanvas.enabled=true 18 | 19 | ## Artifacts 20 | VERSION_NAME=0.0.1-SNAPSHOT 21 | GROUP=me.sujanpoudel.multiplatform.utils 22 | 23 | -------------------------------------------------------------------------------- /gradle/libs.versions.toml: -------------------------------------------------------------------------------- 1 | [versions] 2 | 3 | # artifacts 4 | minSdk = "21" 5 | targetSdk = "34" 6 | compileSdk = "34" 7 | 8 | # plugins 9 | kotlin = "1.9.23" 10 | agp = "8.2.2" 11 | compose = "1.6.1" 12 | klint-plugin = "12.0.3" 13 | mavenPublish = "0.28.0" 14 | detekt = "1.23.6" 15 | binaryCompatibilityValidator = "0.15.0-Beta.2" 16 | 17 | # libraries 18 | ktlint = "1.2.1" 19 | startupRuntime = "1.1.1" 20 | kotlinxIoCore = "0.3.0" 21 | composeCompiler = "1.5.11" 22 | activityCompose = "1.8.2" 23 | coreKtx = "1.12.0" 24 | appcompat = "1.6.1" 25 | 26 | espressoCore = "3.5.1" 27 | junitVersion = "1.1.5" 28 | robolectric = "4.11.1" 29 | junit = "4.13.2" 30 | 31 | 32 | [libraries] 33 | espresso-core = { module = "androidx.test.espresso:espresso-core", version.ref = "espressoCore" } 34 | ext-junit = { module = "androidx.test.ext:junit", version.ref = "junitVersion" } 35 | junit = { module = "junit:junit", version.ref = "junit" } 36 | kotlinx-io-core = { module = "org.jetbrains.kotlinx:kotlinx-io-core", version.ref = "kotlinxIoCore" } 37 | robolectric = { module = "org.robolectric:robolectric", version.ref = "robolectric" } 38 | startup-runtime = { module = "androidx.startup:startup-runtime", version.ref = "startupRuntime" } 39 | activity-compose = { module = "androidx.activity:activity-compose", version.ref = "activityCompose" } 40 | core-ktx = { module = "androidx.core:core-ktx", version.ref = "coreKtx" } 41 | appcompat = { module = "androidx.appcompat:appcompat", version.ref = "appcompat" } 42 | 43 | 44 | [plugins] 45 | kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" } 46 | kotlin-multiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" } 47 | kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } 48 | android-application = { id = "com.android.application", version.ref = "agp" } 49 | android-library = { id = "com.android.library", version.ref = "agp" } 50 | compose = { id = "org.jetbrains.compose", version.ref = "compose" } 51 | ktlint = { id = "org.jlleitschuh.gradle.ktlint", version.ref = "klint-plugin" } 52 | mavenPublish = { id = "com.vanniktech.maven.publish", version.ref = "mavenPublish" } 53 | detekt = { id = "io.gitlab.arturbosch.detekt", version.ref = "detekt" } 54 | binaryCompatibilityValidator = { id = "org.jetbrains.kotlinx.binary-compatibility-validator", version.ref = "binaryCompatibilityValidator" } 55 | 56 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/psuzn/multiplatform-paths/be42a4b72acd36d685f0a9e52859c7f8d6a916b0/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Thu Dec 07 15:21:22 NPT 2023 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip 5 | zipStoreBase=GRADLE_USER_HOME 6 | zipStorePath=wrapper/dists 7 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | # 4 | # Copyright 2015 the original author or authors. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | ############################################################################## 20 | ## 21 | ## Gradle start up script for UN*X 22 | ## 23 | ############################################################################## 24 | 25 | # Attempt to set APP_HOME 26 | # Resolve links: $0 may be a link 27 | PRG="$0" 28 | # Need this for relative symlinks. 29 | while [ -h "$PRG" ] ; do 30 | ls=`ls -ld "$PRG"` 31 | link=`expr "$ls" : '.*-> \(.*\)$'` 32 | if expr "$link" : '/.*' > /dev/null; then 33 | PRG="$link" 34 | else 35 | PRG=`dirname "$PRG"`"/$link" 36 | fi 37 | done 38 | SAVED="`pwd`" 39 | cd "`dirname \"$PRG\"`/" >/dev/null 40 | APP_HOME="`pwd -P`" 41 | cd "$SAVED" >/dev/null 42 | 43 | APP_NAME="Gradle" 44 | APP_BASE_NAME=`basename "$0"` 45 | 46 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 47 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 48 | 49 | # Use the maximum available, or set MAX_FD != -1 to use that value. 50 | MAX_FD="maximum" 51 | 52 | warn () { 53 | echo "$*" 54 | } 55 | 56 | die () { 57 | echo 58 | echo "$*" 59 | echo 60 | exit 1 61 | } 62 | 63 | # OS specific support (must be 'true' or 'false'). 64 | cygwin=false 65 | msys=false 66 | darwin=false 67 | nonstop=false 68 | case "`uname`" in 69 | CYGWIN* ) 70 | cygwin=true 71 | ;; 72 | Darwin* ) 73 | darwin=true 74 | ;; 75 | MINGW* ) 76 | msys=true 77 | ;; 78 | NONSTOP* ) 79 | nonstop=true 80 | ;; 81 | esac 82 | 83 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 84 | 85 | 86 | # Determine the Java command to use to start the JVM. 87 | if [ -n "$JAVA_HOME" ] ; then 88 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 89 | # IBM's JDK on AIX uses strange locations for the executables 90 | JAVACMD="$JAVA_HOME/jre/sh/java" 91 | else 92 | JAVACMD="$JAVA_HOME/bin/java" 93 | fi 94 | if [ ! -x "$JAVACMD" ] ; then 95 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 96 | 97 | Please set the JAVA_HOME variable in your environment to match the 98 | location of your Java installation." 99 | fi 100 | else 101 | JAVACMD="java" 102 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 103 | 104 | Please set the JAVA_HOME variable in your environment to match the 105 | location of your Java installation." 106 | fi 107 | 108 | # Increase the maximum file descriptors if we can. 109 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 110 | MAX_FD_LIMIT=`ulimit -H -n` 111 | if [ $? -eq 0 ] ; then 112 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 113 | MAX_FD="$MAX_FD_LIMIT" 114 | fi 115 | ulimit -n $MAX_FD 116 | if [ $? -ne 0 ] ; then 117 | warn "Could not set maximum file descriptor limit: $MAX_FD" 118 | fi 119 | else 120 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 121 | fi 122 | fi 123 | 124 | # For Darwin, add options to specify how the application appears in the dock 125 | if $darwin; then 126 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 127 | fi 128 | 129 | # For Cygwin or MSYS, switch paths to Windows format before running java 130 | if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then 131 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 132 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 133 | 134 | JAVACMD=`cygpath --unix "$JAVACMD"` 135 | 136 | # We build the pattern for arguments to be converted via cygpath 137 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 138 | SEP="" 139 | for dir in $ROOTDIRSRAW ; do 140 | ROOTDIRS="$ROOTDIRS$SEP$dir" 141 | SEP="|" 142 | done 143 | OURCYGPATTERN="(^($ROOTDIRS))" 144 | # Add a user-defined pattern to the cygpath arguments 145 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 146 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 147 | fi 148 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 149 | i=0 150 | for arg in "$@" ; do 151 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 152 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 153 | 154 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 155 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 156 | else 157 | eval `echo args$i`="\"$arg\"" 158 | fi 159 | i=`expr $i + 1` 160 | done 161 | case $i in 162 | 0) set -- ;; 163 | 1) set -- "$args0" ;; 164 | 2) set -- "$args0" "$args1" ;; 165 | 3) set -- "$args0" "$args1" "$args2" ;; 166 | 4) set -- "$args0" "$args1" "$args2" "$args3" ;; 167 | 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 168 | 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 169 | 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 170 | 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 171 | 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 172 | esac 173 | fi 174 | 175 | # Escape application args 176 | save () { 177 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 178 | echo " " 179 | } 180 | APP_ARGS=`save "$@"` 181 | 182 | # Collect all arguments for the java command, following the shell quoting and substitution rules 183 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 184 | 185 | exec "$JAVACMD" "$@" 186 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto execute 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto execute 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :execute 68 | @rem Setup the command line 69 | 70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 71 | 72 | 73 | @rem Execute Gradle 74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 75 | 76 | :end 77 | @rem End local scope for the variables with windows NT shell 78 | if "%ERRORLEVEL%"=="0" goto mainEnd 79 | 80 | :fail 81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 82 | rem the _cmd.exe /c_ return code! 83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 84 | exit /b 1 85 | 86 | :mainEnd 87 | if "%OS%"=="Windows_NT" endlocal 88 | 89 | :omega 90 | -------------------------------------------------------------------------------- /migration-guides.md: -------------------------------------------------------------------------------- 1 | ## Migration guide 2 | 3 | ### v0.1.x to v.2.x 4 | 5 | - Update the implementation 6 | 7 | ```kotlin 8 | 9 | implementation("me.sujanpoudel.mputils:paths:0.1.x") 10 | implementation("me.sujanpoudel.mputils:platform-identifier:0.1.x") 11 | implementation("me.sujanpoudel.mputils:context-provider:0.1.x") 12 | ``` 13 | 14 | with following: 15 | 16 | ```kotlin 17 | 18 | implementation("me.sujanpoudel.multiplatform.utils:multiplatform-paths:0.2.0") 19 | implementation("me.sujanpoudel.multiplatform.utils:platform-identifier:0.2.0") 20 | implementation("me.sujanpoudel.multiplatform.utils:context-provider:0.2.0") 21 | ``` 22 | 23 | - Update the any import with `me.sujanpoudel.mputils.*` with `me.sujanpoudel.util.*` 24 | 25 | ```kotlin 26 | import me.sujanpoudel.mputils.paths.appDataDirectory // old import 27 | import me.sujanpoudel.utils.paths.appDataDirectory // replace with this 28 | 29 | 30 | import me.sujanpoudel.mputils.paths.appCacheDirectory // old import 31 | import me.sujanpoudel.utils.paths.appCacheDirectory // replace with this 32 | 33 | import me.sujanpoudel.mputils.platformIdentifier.platform // old import 34 | import me.sujanpoudel.multiplatform.utils.platformIdentifier.platform // replace with this 35 | 36 | 37 | import me.sujanpoudel.mputils.contextProvider.applicationContext // old import 38 | import me.sujanpoudel.utils.contextProvider.applicationContext // replace with this 39 | 40 | ``` 41 | -------------------------------------------------------------------------------- /multiplatform-paths/api/android/multiplatform-paths.api: -------------------------------------------------------------------------------- 1 | public final class me/sujanpoudel/multiplatform/utils/multiplatformPaths/BuildConfig { 2 | public static final field BUILD_TYPE Ljava/lang/String; 3 | public static final field DEBUG Z 4 | public static final field LIBRARY_PACKAGE_NAME Ljava/lang/String; 5 | public fun ()V 6 | } 7 | 8 | public final class me/sujanpoudel/utils/paths/DirectoriesKt { 9 | public static final fun appCacheDirectory (Ljava/lang/String;Z)Lkotlinx/io/files/Path; 10 | public static synthetic fun appCacheDirectory$default (Ljava/lang/String;ZILjava/lang/Object;)Lkotlinx/io/files/Path; 11 | public static final fun appDataDirectory (Ljava/lang/String;Z)Lkotlinx/io/files/Path; 12 | public static synthetic fun appDataDirectory$default (Ljava/lang/String;ZILjava/lang/Object;)Lkotlinx/io/files/Path; 13 | } 14 | 15 | public final class me/sujanpoudel/utils/paths/Directories_androidKt { 16 | public static final fun cacheDirectory (Ljava/lang/String;)Lkotlinx/io/files/Path; 17 | public static final fun dataDirectory (Ljava/lang/String;)Lkotlinx/io/files/Path; 18 | } 19 | 20 | public final class me/sujanpoudel/utils/paths/utils/PathKt { 21 | public static final fun div (Lkotlinx/io/files/Path;Ljava/lang/String;)Lkotlinx/io/files/Path; 22 | public static final fun toPath (Ljava/lang/String;)Lkotlinx/io/files/Path; 23 | } 24 | 25 | -------------------------------------------------------------------------------- /multiplatform-paths/api/desktop/multiplatform-paths.api: -------------------------------------------------------------------------------- 1 | public final class me/sujanpoudel/utils/paths/DirectoriesKt { 2 | public static final fun appCacheDirectory (Ljava/lang/String;Z)Lkotlinx/io/files/Path; 3 | public static synthetic fun appCacheDirectory$default (Ljava/lang/String;ZILjava/lang/Object;)Lkotlinx/io/files/Path; 4 | public static final fun appDataDirectory (Ljava/lang/String;Z)Lkotlinx/io/files/Path; 5 | public static synthetic fun appDataDirectory$default (Ljava/lang/String;ZILjava/lang/Object;)Lkotlinx/io/files/Path; 6 | } 7 | 8 | public final class me/sujanpoudel/utils/paths/Directories_desktopCommonKt { 9 | public static final fun desktopAppHomeDirectory (Ljava/lang/String;Lme/sujanpoudel/utils/platformIdentifier/Platform$OS;Lkotlin/jvm/functions/Function1;)Lkotlinx/io/files/Path; 10 | public static final fun desktopCacheDirectory (Ljava/lang/String;Lme/sujanpoudel/utils/platformIdentifier/Platform$OS;Lkotlin/jvm/functions/Function1;)Lkotlinx/io/files/Path; 11 | } 12 | 13 | public final class me/sujanpoudel/utils/paths/Directories_desktopKt { 14 | public static final fun cacheDirectory (Ljava/lang/String;)Lkotlinx/io/files/Path; 15 | public static final fun dataDirectory (Ljava/lang/String;)Lkotlinx/io/files/Path; 16 | } 17 | 18 | public final class me/sujanpoudel/utils/paths/utils/PathKt { 19 | public static final fun div (Lkotlinx/io/files/Path;Ljava/lang/String;)Lkotlinx/io/files/Path; 20 | public static final fun toPath (Ljava/lang/String;)Lkotlinx/io/files/Path; 21 | } 22 | 23 | -------------------------------------------------------------------------------- /multiplatform-paths/build.gradle.kts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Sujan Poudel 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | plugins { 18 | id("packaging") 19 | id("multiplatform-library") 20 | } 21 | 22 | @OptIn(org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi::class) 23 | kotlin { 24 | 25 | tvosArm64() 26 | tvosX64() 27 | tvosSimulatorArm64() 28 | 29 | js(IR) { 30 | nodejs() 31 | generateTypeScriptDefinitions() 32 | } 33 | 34 | sourceSets { 35 | 36 | val commonMain by getting { 37 | dependencies { 38 | implementation(projects.platformIdentifier) 39 | api(libs.kotlinx.io.core) 40 | } 41 | } 42 | 43 | val commonTest by getting { 44 | dependencies { 45 | implementation(kotlin("test")) 46 | } 47 | } 48 | 49 | val androidMain by getting { 50 | dependencies { 51 | implementation(projects.contextProvider) 52 | } 53 | } 54 | 55 | val androidUnitTest by getting { 56 | dependencies { 57 | implementation(libs.junit) 58 | implementation(libs.ext.junit) 59 | implementation(libs.espresso.core) 60 | implementation(libs.robolectric) 61 | } 62 | } 63 | 64 | val darwinMain by creating { 65 | dependsOn(commonMain) 66 | } 67 | 68 | val iosMain by getting { 69 | dependsOn(darwinMain) 70 | } 71 | 72 | val iosSimulatorArm64Main by getting { 73 | dependsOn(iosMain) 74 | } 75 | 76 | val desktopCommonMain by creating { 77 | dependsOn(commonMain) 78 | } 79 | 80 | val desktopMain by getting { 81 | dependsOn(desktopCommonMain) 82 | } 83 | 84 | val macosX64Main by getting { 85 | dependsOn(darwinMain) 86 | } 87 | 88 | val macosArm64Main by getting { 89 | dependsOn(darwinMain) 90 | } 91 | 92 | val jsMain by getting { 93 | dependsOn(desktopCommonMain) 94 | } 95 | 96 | val tvosMain by getting { 97 | dependsOn(darwinMain) 98 | } 99 | } 100 | } 101 | 102 | android { 103 | testOptions { 104 | unitTests { 105 | isIncludeAndroidResources = true 106 | } 107 | } 108 | } 109 | 110 | @Suppress("ktlint:standard:max-line-length") 111 | mavenPublishing { 112 | pom { 113 | name.set("Multiplatform Paths") 114 | description.set( 115 | "Get platform specific app data and cache directory(equivalent to ApplicationInfo.dataDir or NSApplicationSupportDirectory) in Kotlin Multiplatform application", 116 | ) 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /multiplatform-paths/src/androidMain/kotlin/me/sujanpoudel/utils/paths/directories.android.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Sujan Poudel 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package me.sujanpoudel.utils.paths 18 | 19 | import kotlinx.io.files.Path 20 | import me.sujanpoudel.utils.contextProvider.applicationContext 21 | import me.sujanpoudel.utils.paths.utils.toPath 22 | 23 | actual fun dataDirectory(appId: String): Path = applicationContext.applicationInfo.dataDir.toPath() 24 | 25 | actual fun cacheDirectory(appId: String): Path = applicationContext.cacheDir.absolutePath.toPath() 26 | -------------------------------------------------------------------------------- /multiplatform-paths/src/androidUnitTest/kotlin/me/sujanpoudel/utils/paths/AndroidDirectoriesTest.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Sujan Poudel 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package me.sujanpoudel.utils.paths 18 | 19 | import android.content.Context 20 | import androidx.test.core.app.ApplicationProvider 21 | import kotlinx.io.files.Path 22 | import me.sujanpoudel.utils.paths.utils.toPath 23 | import org.junit.Test 24 | import org.junit.runner.RunWith 25 | import org.robolectric.RobolectricTestRunner 26 | import kotlin.test.assertEquals 27 | 28 | @RunWith(RobolectricTestRunner::class) 29 | class AndroidDirectoriesTest { 30 | private val appId: String = "me.sujanpoudel.utils.paths.test" 31 | 32 | private fun exceptedCacheDir(appId: String): Path { 33 | val applicationContext = ApplicationProvider.getApplicationContext() 34 | return applicationContext.cacheDir.absolutePath.toPath() 35 | } 36 | 37 | private fun exceptedDataDir(appId: String): Path { 38 | val applicationContext = ApplicationProvider.getApplicationContext() 39 | return applicationContext.dataDir.absolutePath.toPath() 40 | } 41 | 42 | @Test 43 | fun testCacheDirectory() { 44 | assertEquals(exceptedCacheDir(appId), cacheDirectory(appId)) 45 | } 46 | 47 | @Test 48 | fun testDataDirectory() { 49 | assertEquals(exceptedDataDir(appId), dataDirectory(appId)) 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /multiplatform-paths/src/commonMain/kotlin/me/sujanpoudel/utils/paths/directories.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Sujan Poudel 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package me.sujanpoudel.utils.paths 18 | 19 | import kotlinx.io.files.Path 20 | import kotlinx.io.files.SystemFileSystem 21 | 22 | internal expect fun dataDirectory(appId: String): Path 23 | 24 | internal expect fun cacheDirectory(appId: String): Path 25 | 26 | /** 27 | * @returns Platform specific app data directory, on Android and IOS it is a secure directory 28 | * inaccessible from user and other application. 29 | * 30 | * @param appId unique app id, equivalent to packageName(android), bundle id (ios) 31 | * @param createDir whether explicitly should create the directory if it doesn't exist 32 | */ 33 | fun appDataDirectory(appId: String, createDir: Boolean = true): Path = dataDirectory(appId).also { 34 | if (createDir) { 35 | SystemFileSystem.createDirectories(it) 36 | } 37 | } 38 | 39 | /** 40 | * App specific cache directory 41 | * on android it is context.cacheDir and on IOS/darwin it is NSCachesDirectory 42 | * 43 | * @param appId unique app id, equivalent to packageName(android), bundle id (ios) 44 | * @param createDir whether explicitly should create the directory if it doesn't exist 45 | */ 46 | fun appCacheDirectory(appId: String, createDir: Boolean = true): Path = cacheDirectory(appId).also { 47 | if (createDir) { 48 | SystemFileSystem.createDirectories(it) 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /multiplatform-paths/src/commonMain/kotlin/me/sujanpoudel/utils/paths/utils/Path.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Sujan Poudel 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package me.sujanpoudel.utils.paths.utils 18 | 19 | import kotlinx.io.files.Path 20 | 21 | inline fun String.toPath(): Path = Path(this) 22 | 23 | operator fun Path.div(child: String): Path = Path(this, child) 24 | -------------------------------------------------------------------------------- /multiplatform-paths/src/commonTest/kotlin/me/sujanpoudel/utils/paths/DirectoriesTest.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Sujan Poudel 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package me.sujanpoudel.utils.paths 18 | 19 | import kotlinx.io.files.Path 20 | import kotlin.test.Test 21 | import kotlin.test.assertEquals 22 | 23 | abstract class DirectoriesTest { 24 | private val appId: String = "me.sujanpoudel.utils.paths.test" 25 | 26 | abstract fun exceptedCacheDir(appId: String): Path 27 | 28 | abstract fun exceptedDataDir(appId: String): Path 29 | 30 | @Test 31 | fun testCacheDirectory() { 32 | assertEquals(exceptedCacheDir(appId), cacheDirectory(appId)) 33 | } 34 | 35 | @Test 36 | fun testDataDirectory() { 37 | assertEquals(exceptedDataDir(appId), dataDirectory(appId)) 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /multiplatform-paths/src/darwinMain/kotlin/me/sujanpoudel/utils/paths/directories.darwin.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Sujan Poudel 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package me.sujanpoudel.utils.paths 18 | 19 | import kotlinx.io.files.Path 20 | import me.sujanpoudel.utils.paths.utils.div 21 | import me.sujanpoudel.utils.paths.utils.toPath 22 | import me.sujanpoudel.utils.platformIdentifier.Platform 23 | import me.sujanpoudel.utils.platformIdentifier.platform 24 | import platform.Foundation.NSApplicationSupportDirectory 25 | import platform.Foundation.NSCachesDirectory 26 | import platform.Foundation.NSSearchPathForDirectoriesInDomains 27 | import platform.Foundation.NSUserDomainMask 28 | 29 | actual fun dataDirectory(appId: String): Path = 30 | NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, true) 31 | .firstOrNull()?.toString()?.toPath() 32 | ?.let { it / appId } ?: error("Unable to get 'NSApplicationSupportDirectory'") 33 | 34 | actual fun cacheDirectory(appId: String): Path { 35 | val cachesDirectory = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, true) 36 | .firstOrNull()?.toString()?.toPath() ?: error("Unable to get 'NSCachesDirectory'") 37 | 38 | return if (platform() is Platform.OS.MacOs) { 39 | cachesDirectory / appId 40 | } else { 41 | cachesDirectory 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /multiplatform-paths/src/desktopCommonMain/kotlin/me/sujanpoudel/utils/paths/directories.desktopCommon.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Sujan Poudel 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package me.sujanpoudel.utils.paths 18 | 19 | import kotlinx.io.files.Path 20 | import me.sujanpoudel.utils.paths.utils.div 21 | import me.sujanpoudel.utils.paths.utils.toPath 22 | import me.sujanpoudel.utils.platformIdentifier.Platform 23 | 24 | fun desktopAppHomeDirectory(appId: String, os: Platform.OS, getEnv: (String) -> String): Path = when (os) { 25 | is Platform.OS.MacOs -> getEnv("HOME").toPath() / "Library/Application Support" / appId 26 | is Platform.OS.Windows -> getEnv("APPDATA").toPath() / appId 27 | is Platform.OS.Linux -> getEnv("HOME").toPath() / ".local" / "share" / appId 28 | else -> getEnv("HOME").toPath() / ".$appId" 29 | } 30 | 31 | fun desktopCacheDirectory(appId: String, os: Platform.OS, getEnv: (String) -> String): Path = when (os) { 32 | is Platform.OS.MacOs -> getEnv("HOME").toPath() / "Library/Caches" / appId 33 | is Platform.OS.Windows -> getEnv("APPDATA").toPath() / "Caches" / appId 34 | is Platform.OS.Linux -> getEnv("HOME").toPath() / ".cache" / appId 35 | else -> getEnv("HOME").toPath() / ".cache" / appId 36 | } 37 | -------------------------------------------------------------------------------- /multiplatform-paths/src/desktopMain/kotlin/me/sujanpoudel/utils/paths/directories.desktop.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Sujan Poudel 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package me.sujanpoudel.utils.paths 18 | 19 | import me.sujanpoudel.utils.platformIdentifier.hostOs 20 | 21 | actual fun dataDirectory(appId: String) = desktopAppHomeDirectory( 22 | appId = appId, 23 | os = hostOs, 24 | getEnv = System::getenv, 25 | ) 26 | 27 | actual fun cacheDirectory(appId: String) = desktopCacheDirectory( 28 | appId = appId, 29 | os = hostOs, 30 | getEnv = System::getenv, 31 | ) 32 | -------------------------------------------------------------------------------- /multiplatform-paths/src/desktopTest/kotlin/me/sujanpoudel/utils/paths/DesktopDirectoriesTest.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Sujan Poudel 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package me.sujanpoudel.utils.paths 18 | 19 | import kotlinx.io.files.Path 20 | import me.sujanpoudel.utils.paths.utils.div 21 | import me.sujanpoudel.utils.paths.utils.toPath 22 | import me.sujanpoudel.utils.platformIdentifier.Platform 23 | import me.sujanpoudel.utils.platformIdentifier.hostOs 24 | 25 | class DesktopDirectoriesTest : DirectoriesTest() { 26 | private fun getEnv(key: String) = System.getenv(key) as String 27 | 28 | override fun exceptedCacheDir(appId: String): Path { 29 | return when (hostOs) { 30 | is Platform.OS.Linux -> getEnv("HOME").toPath() / ".cache" / appId 31 | is Platform.OS.MacOs -> getEnv("HOME").toPath() / "Library/Caches" / appId 32 | is Platform.OS.Windows -> getEnv("APPDATA").toPath() / "Caches" / appId 33 | else -> error("not supported") 34 | } 35 | } 36 | 37 | override fun exceptedDataDir(appId: String): Path { 38 | return when (hostOs) { 39 | is Platform.OS.Linux -> getEnv("HOME").toPath() / ".local/share" / appId 40 | is Platform.OS.MacOs -> getEnv("HOME").toPath() / "Library/Application Support" / appId 41 | is Platform.OS.Windows -> getEnv("APPDATA").toPath() / appId 42 | else -> error("not supported") 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /multiplatform-paths/src/iosTest/kotlin/me/sujanpoudel/utils/paths/IosDirectoriesTest.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Sujan Poudel 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package me.sujanpoudel.utils.paths 18 | 19 | import kotlinx.io.files.Path 20 | import me.sujanpoudel.utils.paths.utils.div 21 | import me.sujanpoudel.utils.paths.utils.toPath 22 | import platform.Foundation.NSApplicationSupportDirectory 23 | import platform.Foundation.NSCachesDirectory 24 | import platform.Foundation.NSSearchPathForDirectoriesInDomains 25 | import platform.Foundation.NSUserDomainMask 26 | 27 | class IosDirectoriesTest : DirectoriesTest() { 28 | override fun exceptedCacheDir(appId: String): Path { 29 | return NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, true) 30 | .firstOrNull()?.toString()?.toPath() ?: error("Unable to get 'NSCachesDirectory'") 31 | } 32 | 33 | override fun exceptedDataDir(appId: String): Path { 34 | return NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, true) 35 | .firstOrNull()?.toString()?.toPath() 36 | ?.let { it / appId } ?: error("Unable to get 'NSApplicationSupportDirectory'") 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /multiplatform-paths/src/jsMain/kotlin/me/sujanpoudel/utils/paths/directories.js.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Sujan Poudel 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package me.sujanpoudel.utils.paths 18 | 19 | import kotlinx.io.files.Path 20 | import me.sujanpoudel.utils.platformIdentifier.Platform 21 | import me.sujanpoudel.utils.platformIdentifier.platform 22 | 23 | private val platform = platform() as Platform.JS 24 | 25 | actual fun dataDirectory(appId: String): Path = when (platform) { 26 | is Platform.JS.Node -> desktopAppHomeDirectory( 27 | appId = appId, 28 | os = platform.os, 29 | getEnv = { eval("""process.env["$it"]""") as String }, 30 | ) 31 | 32 | else -> error("Non node environment") 33 | } 34 | 35 | actual fun cacheDirectory(appId: String): Path = when (platform) { 36 | is Platform.JS.Node -> desktopCacheDirectory( 37 | appId = appId, 38 | os = platform.os, 39 | getEnv = { 40 | eval("""process.env["$it"]""") as String 41 | }, 42 | ) 43 | 44 | else -> error("Non node environment") 45 | } 46 | -------------------------------------------------------------------------------- /multiplatform-paths/src/jsTest/kotlin/me/sujanpoudel/utils/paths/NodeDirectoriesTest.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Sujan Poudel 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package me.sujanpoudel.utils.paths 18 | 19 | import kotlinx.io.files.Path 20 | import me.sujanpoudel.utils.paths.utils.div 21 | import me.sujanpoudel.utils.paths.utils.toPath 22 | import me.sujanpoudel.utils.platformIdentifier.Platform 23 | import me.sujanpoudel.utils.platformIdentifier.platform 24 | 25 | class NodeDirectoriesTest : DirectoriesTest() { 26 | private fun getEnv(key: String) = eval("""process.env["$key"]""") as String 27 | 28 | override fun exceptedCacheDir(appId: String): Path { 29 | val platform = platform() as? Platform.JS.Node ?: error("not supported") 30 | 31 | return when (platform.os) { 32 | is Platform.OS.Linux -> getEnv("HOME").toPath() / ".cache" / appId 33 | is Platform.OS.MacOs -> getEnv("HOME").toPath() / "Library/Caches" / appId 34 | is Platform.OS.Windows -> getEnv("APPDATA").toPath() / "Caches" / appId 35 | 36 | else -> error("not supported") 37 | } 38 | } 39 | 40 | override fun exceptedDataDir(appId: String): Path { 41 | val platform = platform() as? Platform.JS.Node ?: error("not supported") 42 | 43 | return when (platform.os) { 44 | is Platform.OS.Linux -> getEnv("HOME").toPath() / ".local/share" / appId 45 | is Platform.OS.MacOs -> getEnv("HOME").toPath() / "Library/Application Support" / appId 46 | is Platform.OS.Windows -> getEnv("APPDATA").toPath() / appId 47 | else -> error("not supported") 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /multiplatform-paths/src/macosTest/kotlin/me/sujanpoudel/utils/paths/MacosDirectoriesTest.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Sujan Poudel 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package me.sujanpoudel.utils.paths 18 | 19 | import kotlinx.io.files.Path 20 | import me.sujanpoudel.utils.paths.utils.div 21 | import me.sujanpoudel.utils.paths.utils.toPath 22 | import platform.Foundation.NSApplicationSupportDirectory 23 | import platform.Foundation.NSCachesDirectory 24 | import platform.Foundation.NSSearchPathForDirectoriesInDomains 25 | import platform.Foundation.NSUserDomainMask 26 | 27 | class MacosDirectoriesTest : DirectoriesTest() { 28 | override fun exceptedCacheDir(appId: String): Path { 29 | return NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, true) 30 | .firstOrNull()?.toString()?.toPath()?.let { it / appId } ?: error("Unable to get 'NSCachesDirectory'") 31 | } 32 | 33 | override fun exceptedDataDir(appId: String): Path { 34 | return NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, true) 35 | .firstOrNull()?.toString()?.toPath()?.let { it / appId } ?: error("Unable to get 'NSApplicationSupportDirectory'") 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /platform-identifier/api/android/platform-identifier.api: -------------------------------------------------------------------------------- 1 | public final class me/sujanpoudel/multiplatform/utils/platformIdentifier/BuildConfig { 2 | public static final field BUILD_TYPE Ljava/lang/String; 3 | public static final field DEBUG Z 4 | public static final field LIBRARY_PACKAGE_NAME Ljava/lang/String; 5 | public fun ()V 6 | } 7 | 8 | public final class me/sujanpoudel/utils/platformIdentifier/Arch : java/lang/Enum { 9 | public static final field ARM_X32 Lme/sujanpoudel/utils/platformIdentifier/Arch; 10 | public static final field ARM_X64 Lme/sujanpoudel/utils/platformIdentifier/Arch; 11 | public static final field UNKNOWN Lme/sujanpoudel/utils/platformIdentifier/Arch; 12 | public static final field X64 Lme/sujanpoudel/utils/platformIdentifier/Arch; 13 | public static final field X86 Lme/sujanpoudel/utils/platformIdentifier/Arch; 14 | public static fun getEntries ()Lkotlin/enums/EnumEntries; 15 | public static fun valueOf (Ljava/lang/String;)Lme/sujanpoudel/utils/platformIdentifier/Arch; 16 | public static fun values ()[Lme/sujanpoudel/utils/platformIdentifier/Arch; 17 | } 18 | 19 | public abstract class me/sujanpoudel/utils/platformIdentifier/Platform { 20 | } 21 | 22 | public abstract class me/sujanpoudel/utils/platformIdentifier/Platform$JS : me/sujanpoudel/utils/platformIdentifier/Platform { 23 | } 24 | 25 | public final class me/sujanpoudel/utils/platformIdentifier/Platform$JS$Browser : me/sujanpoudel/utils/platformIdentifier/Platform$JS { 26 | public fun (Ljava/lang/String;)V 27 | public final fun component1 ()Ljava/lang/String; 28 | public final fun copy (Ljava/lang/String;)Lme/sujanpoudel/utils/platformIdentifier/Platform$JS$Browser; 29 | public static synthetic fun copy$default (Lme/sujanpoudel/utils/platformIdentifier/Platform$JS$Browser;Ljava/lang/String;ILjava/lang/Object;)Lme/sujanpoudel/utils/platformIdentifier/Platform$JS$Browser; 30 | public fun equals (Ljava/lang/Object;)Z 31 | public final fun getUserAgent ()Ljava/lang/String; 32 | public fun hashCode ()I 33 | public fun toString ()Ljava/lang/String; 34 | } 35 | 36 | public final class me/sujanpoudel/utils/platformIdentifier/Platform$JS$Node : me/sujanpoudel/utils/platformIdentifier/Platform$JS { 37 | public fun (Lme/sujanpoudel/utils/platformIdentifier/Platform$OS;Ljava/lang/String;Ljava/lang/String;)V 38 | public final fun component1 ()Lme/sujanpoudel/utils/platformIdentifier/Platform$OS; 39 | public final fun component2 ()Ljava/lang/String; 40 | public final fun component3 ()Ljava/lang/String; 41 | public final fun copy (Lme/sujanpoudel/utils/platformIdentifier/Platform$OS;Ljava/lang/String;Ljava/lang/String;)Lme/sujanpoudel/utils/platformIdentifier/Platform$JS$Node; 42 | public static synthetic fun copy$default (Lme/sujanpoudel/utils/platformIdentifier/Platform$JS$Node;Lme/sujanpoudel/utils/platformIdentifier/Platform$OS;Ljava/lang/String;Ljava/lang/String;ILjava/lang/Object;)Lme/sujanpoudel/utils/platformIdentifier/Platform$JS$Node; 43 | public fun equals (Ljava/lang/Object;)Z 44 | public final fun getNodeVersion ()Ljava/lang/String; 45 | public final fun getOs ()Lme/sujanpoudel/utils/platformIdentifier/Platform$OS; 46 | public final fun getV8Version ()Ljava/lang/String; 47 | public fun hashCode ()I 48 | public fun toString ()Ljava/lang/String; 49 | } 50 | 51 | public abstract class me/sujanpoudel/utils/platformIdentifier/Platform$OS : me/sujanpoudel/utils/platformIdentifier/Platform { 52 | public synthetic fun (Lme/sujanpoudel/utils/platformIdentifier/Arch;Lkotlin/jvm/internal/DefaultConstructorMarker;)V 53 | public fun getArch ()Lme/sujanpoudel/utils/platformIdentifier/Arch; 54 | } 55 | 56 | public final class me/sujanpoudel/utils/platformIdentifier/Platform$OS$Android : me/sujanpoudel/utils/platformIdentifier/Platform$OS { 57 | public fun (Lme/sujanpoudel/utils/platformIdentifier/Arch;ILjava/lang/String;ZZ)V 58 | public final fun component1 ()Lme/sujanpoudel/utils/platformIdentifier/Arch; 59 | public final fun component2 ()I 60 | public final fun component3 ()Ljava/lang/String; 61 | public final fun component4 ()Z 62 | public final fun component5 ()Z 63 | public final fun copy (Lme/sujanpoudel/utils/platformIdentifier/Arch;ILjava/lang/String;ZZ)Lme/sujanpoudel/utils/platformIdentifier/Platform$OS$Android; 64 | public static synthetic fun copy$default (Lme/sujanpoudel/utils/platformIdentifier/Platform$OS$Android;Lme/sujanpoudel/utils/platformIdentifier/Arch;ILjava/lang/String;ZZILjava/lang/Object;)Lme/sujanpoudel/utils/platformIdentifier/Platform$OS$Android; 65 | public fun equals (Ljava/lang/Object;)Z 66 | public final fun getAndroidVersion ()Ljava/lang/String; 67 | public fun getArch ()Lme/sujanpoudel/utils/platformIdentifier/Arch; 68 | public final fun getBuildNumber ()I 69 | public fun hashCode ()I 70 | public final fun isTv ()Z 71 | public final fun isWatch ()Z 72 | public fun toString ()Ljava/lang/String; 73 | } 74 | 75 | public final class me/sujanpoudel/utils/platformIdentifier/Platform$OS$IOS : me/sujanpoudel/utils/platformIdentifier/Platform$OS { 76 | public fun (Lme/sujanpoudel/utils/platformIdentifier/Arch;Ljava/lang/String;Z)V 77 | public final fun component1 ()Lme/sujanpoudel/utils/platformIdentifier/Arch; 78 | public final fun component2 ()Ljava/lang/String; 79 | public final fun component3 ()Z 80 | public final fun copy (Lme/sujanpoudel/utils/platformIdentifier/Arch;Ljava/lang/String;Z)Lme/sujanpoudel/utils/platformIdentifier/Platform$OS$IOS; 81 | public static synthetic fun copy$default (Lme/sujanpoudel/utils/platformIdentifier/Platform$OS$IOS;Lme/sujanpoudel/utils/platformIdentifier/Arch;Ljava/lang/String;ZILjava/lang/Object;)Lme/sujanpoudel/utils/platformIdentifier/Platform$OS$IOS; 82 | public fun equals (Ljava/lang/Object;)Z 83 | public fun getArch ()Lme/sujanpoudel/utils/platformIdentifier/Arch; 84 | public final fun getVersion ()Ljava/lang/String; 85 | public fun hashCode ()I 86 | public final fun isSimulator ()Z 87 | public fun toString ()Ljava/lang/String; 88 | } 89 | 90 | public final class me/sujanpoudel/utils/platformIdentifier/Platform$OS$Linux : me/sujanpoudel/utils/platformIdentifier/Platform$OS { 91 | public fun (Lme/sujanpoudel/utils/platformIdentifier/Arch;Ljava/lang/String;)V 92 | public final fun component1 ()Lme/sujanpoudel/utils/platformIdentifier/Arch; 93 | public final fun component2 ()Ljava/lang/String; 94 | public final fun copy (Lme/sujanpoudel/utils/platformIdentifier/Arch;Ljava/lang/String;)Lme/sujanpoudel/utils/platformIdentifier/Platform$OS$Linux; 95 | public static synthetic fun copy$default (Lme/sujanpoudel/utils/platformIdentifier/Platform$OS$Linux;Lme/sujanpoudel/utils/platformIdentifier/Arch;Ljava/lang/String;ILjava/lang/Object;)Lme/sujanpoudel/utils/platformIdentifier/Platform$OS$Linux; 96 | public fun equals (Ljava/lang/Object;)Z 97 | public fun getArch ()Lme/sujanpoudel/utils/platformIdentifier/Arch; 98 | public final fun getVersion ()Ljava/lang/String; 99 | public fun hashCode ()I 100 | public fun toString ()Ljava/lang/String; 101 | } 102 | 103 | public final class me/sujanpoudel/utils/platformIdentifier/Platform$OS$MacOs : me/sujanpoudel/utils/platformIdentifier/Platform$OS { 104 | public fun (Lme/sujanpoudel/utils/platformIdentifier/Arch;Ljava/lang/String;)V 105 | public final fun component1 ()Lme/sujanpoudel/utils/platformIdentifier/Arch; 106 | public final fun component2 ()Ljava/lang/String; 107 | public final fun copy (Lme/sujanpoudel/utils/platformIdentifier/Arch;Ljava/lang/String;)Lme/sujanpoudel/utils/platformIdentifier/Platform$OS$MacOs; 108 | public static synthetic fun copy$default (Lme/sujanpoudel/utils/platformIdentifier/Platform$OS$MacOs;Lme/sujanpoudel/utils/platformIdentifier/Arch;Ljava/lang/String;ILjava/lang/Object;)Lme/sujanpoudel/utils/platformIdentifier/Platform$OS$MacOs; 109 | public fun equals (Ljava/lang/Object;)Z 110 | public fun getArch ()Lme/sujanpoudel/utils/platformIdentifier/Arch; 111 | public final fun getVersion ()Ljava/lang/String; 112 | public fun hashCode ()I 113 | public fun toString ()Ljava/lang/String; 114 | } 115 | 116 | public final class me/sujanpoudel/utils/platformIdentifier/Platform$OS$TvOs : me/sujanpoudel/utils/platformIdentifier/Platform$OS { 117 | public fun (Lme/sujanpoudel/utils/platformIdentifier/Arch;Ljava/lang/String;Z)V 118 | public final fun component1 ()Lme/sujanpoudel/utils/platformIdentifier/Arch; 119 | public final fun component2 ()Ljava/lang/String; 120 | public final fun component3 ()Z 121 | public final fun copy (Lme/sujanpoudel/utils/platformIdentifier/Arch;Ljava/lang/String;Z)Lme/sujanpoudel/utils/platformIdentifier/Platform$OS$TvOs; 122 | public static synthetic fun copy$default (Lme/sujanpoudel/utils/platformIdentifier/Platform$OS$TvOs;Lme/sujanpoudel/utils/platformIdentifier/Arch;Ljava/lang/String;ZILjava/lang/Object;)Lme/sujanpoudel/utils/platformIdentifier/Platform$OS$TvOs; 123 | public fun equals (Ljava/lang/Object;)Z 124 | public fun getArch ()Lme/sujanpoudel/utils/platformIdentifier/Arch; 125 | public final fun getVersion ()Ljava/lang/String; 126 | public fun hashCode ()I 127 | public final fun isSimulator ()Z 128 | public fun toString ()Ljava/lang/String; 129 | } 130 | 131 | public final class me/sujanpoudel/utils/platformIdentifier/Platform$OS$Unknown : me/sujanpoudel/utils/platformIdentifier/Platform$OS { 132 | public fun (Lme/sujanpoudel/utils/platformIdentifier/Arch;Ljava/lang/String;)V 133 | public final fun component1 ()Lme/sujanpoudel/utils/platformIdentifier/Arch; 134 | public final fun component2 ()Ljava/lang/String; 135 | public final fun copy (Lme/sujanpoudel/utils/platformIdentifier/Arch;Ljava/lang/String;)Lme/sujanpoudel/utils/platformIdentifier/Platform$OS$Unknown; 136 | public static synthetic fun copy$default (Lme/sujanpoudel/utils/platformIdentifier/Platform$OS$Unknown;Lme/sujanpoudel/utils/platformIdentifier/Arch;Ljava/lang/String;ILjava/lang/Object;)Lme/sujanpoudel/utils/platformIdentifier/Platform$OS$Unknown; 137 | public fun equals (Ljava/lang/Object;)Z 138 | public fun getArch ()Lme/sujanpoudel/utils/platformIdentifier/Arch; 139 | public final fun getVersion ()Ljava/lang/String; 140 | public fun hashCode ()I 141 | public fun toString ()Ljava/lang/String; 142 | } 143 | 144 | public final class me/sujanpoudel/utils/platformIdentifier/Platform$OS$WatchOs : me/sujanpoudel/utils/platformIdentifier/Platform$OS { 145 | public fun (Lme/sujanpoudel/utils/platformIdentifier/Arch;Ljava/lang/String;Z)V 146 | public final fun component1 ()Lme/sujanpoudel/utils/platformIdentifier/Arch; 147 | public final fun component2 ()Ljava/lang/String; 148 | public final fun component3 ()Z 149 | public final fun copy (Lme/sujanpoudel/utils/platformIdentifier/Arch;Ljava/lang/String;Z)Lme/sujanpoudel/utils/platformIdentifier/Platform$OS$WatchOs; 150 | public static synthetic fun copy$default (Lme/sujanpoudel/utils/platformIdentifier/Platform$OS$WatchOs;Lme/sujanpoudel/utils/platformIdentifier/Arch;Ljava/lang/String;ZILjava/lang/Object;)Lme/sujanpoudel/utils/platformIdentifier/Platform$OS$WatchOs; 151 | public fun equals (Ljava/lang/Object;)Z 152 | public fun getArch ()Lme/sujanpoudel/utils/platformIdentifier/Arch; 153 | public final fun getVersion ()Ljava/lang/String; 154 | public fun hashCode ()I 155 | public final fun isSimulator ()Z 156 | public fun toString ()Ljava/lang/String; 157 | } 158 | 159 | public final class me/sujanpoudel/utils/platformIdentifier/Platform$OS$Windows : me/sujanpoudel/utils/platformIdentifier/Platform$OS { 160 | public fun (Lme/sujanpoudel/utils/platformIdentifier/Arch;Ljava/lang/String;)V 161 | public final fun component1 ()Lme/sujanpoudel/utils/platformIdentifier/Arch; 162 | public final fun component2 ()Ljava/lang/String; 163 | public final fun copy (Lme/sujanpoudel/utils/platformIdentifier/Arch;Ljava/lang/String;)Lme/sujanpoudel/utils/platformIdentifier/Platform$OS$Windows; 164 | public static synthetic fun copy$default (Lme/sujanpoudel/utils/platformIdentifier/Platform$OS$Windows;Lme/sujanpoudel/utils/platformIdentifier/Arch;Ljava/lang/String;ILjava/lang/Object;)Lme/sujanpoudel/utils/platformIdentifier/Platform$OS$Windows; 165 | public fun equals (Ljava/lang/Object;)Z 166 | public fun getArch ()Lme/sujanpoudel/utils/platformIdentifier/Arch; 167 | public final fun getVersion ()Ljava/lang/String; 168 | public fun hashCode ()I 169 | public fun toString ()Ljava/lang/String; 170 | } 171 | 172 | public final class me/sujanpoudel/utils/platformIdentifier/Platform_androidKt { 173 | public static final fun platform ()Lme/sujanpoudel/utils/platformIdentifier/Platform; 174 | } 175 | 176 | -------------------------------------------------------------------------------- /platform-identifier/build.gradle.kts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Sujan Poudel 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | plugins { 18 | id("packaging") 19 | id("multiplatform-library") 20 | } 21 | 22 | @OptIn(org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi::class) 23 | kotlin { 24 | 25 | watchosArm32() 26 | watchosArm64() 27 | watchosSimulatorArm64() 28 | 29 | tvosArm64() 30 | tvosX64() 31 | tvosSimulatorArm64() 32 | 33 | androidNativeArm32() 34 | androidNativeArm64() 35 | androidNativeX64() 36 | androidNativeX86() 37 | 38 | mingwX64() 39 | 40 | js(IR) { 41 | nodejs() 42 | browser { 43 | testTask { 44 | enabled = false 45 | } 46 | } 47 | generateTypeScriptDefinitions() 48 | } 49 | 50 | sourceSets { 51 | val commonMain by getting { 52 | dependencies { 53 | implementation(libs.kotlinx.io.core) 54 | } 55 | } 56 | 57 | commonTest { 58 | dependencies { 59 | implementation(kotlin("test")) 60 | } 61 | } 62 | 63 | androidMain { 64 | dependencies { 65 | api(project(":context-provider")) 66 | } 67 | } 68 | 69 | androidUnitTest { 70 | dependencies { 71 | implementation(libs.junit) 72 | implementation(libs.robolectric) 73 | implementation(libs.ext.junit) 74 | implementation(libs.espresso.core) 75 | } 76 | } 77 | 78 | val desktopCommonMain by creating { 79 | dependsOn(commonMain) 80 | } 81 | 82 | desktopMain { 83 | dependsOn(desktopCommonMain) 84 | } 85 | 86 | jsMain { 87 | dependsOn(desktopCommonMain) 88 | } 89 | } 90 | } 91 | 92 | android { 93 | defaultConfig { 94 | minSdk = libs.versions.minSdk.get().toInt() 95 | } 96 | } 97 | 98 | mavenPublishing { 99 | pom { 100 | name.set("Platform Identifier") 101 | description.set("Identify the current platform in Kotlin Multiplatform application") 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /platform-identifier/src/androidMain/kotlin/me/sujanpoudel/utils/platformIdentifier/platform.android.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Sujan Poudel 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package me.sujanpoudel.utils.platformIdentifier 18 | 19 | import android.content.pm.PackageManager 20 | import android.os.Build 21 | import me.sujanpoudel.utils.contextProvider.applicationContext 22 | 23 | actual fun platform(): Platform { 24 | return Platform.OS.Android( 25 | arch = arch(), 26 | buildNumber = Build.VERSION.SDK_INT, 27 | androidVersion = Build.VERSION.RELEASE, 28 | isWatch = applicationContext.packageManager.hasSystemFeature(PackageManager.FEATURE_WATCH), 29 | isTv = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { 30 | applicationContext.packageManager.hasSystemFeature(PackageManager.FEATURE_LEANBACK_ONLY) 31 | } else { 32 | applicationContext.packageManager.hasSystemFeature(PackageManager.FEATURE_LEANBACK) 33 | }, 34 | ) 35 | } 36 | 37 | private fun arch(): Arch { 38 | Build.SUPPORTED_ABIS.orEmpty().forEach { 39 | when (it) { 40 | "arm64-v8a" -> return Arch.ARM_X64 41 | "armeabi-v7a" -> return Arch.ARM_X64 42 | "x86_64" -> return Arch.X64 43 | "x86" -> return Arch.X86 44 | } 45 | } 46 | return Arch.UNKNOWN 47 | } 48 | -------------------------------------------------------------------------------- /platform-identifier/src/androidNativeMain/kotlin/me/sujanpoudel/utils/platformIdentifier/platform.androidNative.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Sujan Poudel 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package me.sujanpoudel.utils.platformIdentifier 18 | 19 | import kotlinx.cinterop.ByteVar 20 | import kotlinx.cinterop.ExperimentalForeignApi 21 | import kotlinx.cinterop.allocArray 22 | import kotlinx.cinterop.memScoped 23 | import kotlinx.cinterop.toKString 24 | import platform.posix.__system_property_get 25 | import kotlin.experimental.ExperimentalNativeApi 26 | 27 | private const val SYSTEM_PROP_BUILD_VERSION: String = "ro.build.version.sdk" 28 | private const val SYSTEM_PROP_OS_VERSION: String = "ro.build.version.release" 29 | 30 | @OptIn(ExperimentalNativeApi::class) 31 | actual fun platform(): Platform { 32 | val nativePlatform = kotlin.native.Platform 33 | 34 | val arch = nativePlatform.cpuArchitecture.asArch() 35 | 36 | val buildSdk = getSystemProp(SYSTEM_PROP_BUILD_VERSION).toInt() 37 | val androidVersion = getSystemProp(SYSTEM_PROP_OS_VERSION) 38 | 39 | return Platform.OS.Android( 40 | arch = arch, 41 | buildNumber = buildSdk, 42 | androidVersion = androidVersion, 43 | isWatch = false, 44 | isTv = false, 45 | ) 46 | } 47 | 48 | @OptIn(ExperimentalForeignApi::class) 49 | private fun getSystemProp(prop: String): String = memScoped { 50 | val value = allocArray(1024L) 51 | __system_property_get(prop, value) 52 | value 53 | }.toKString() 54 | -------------------------------------------------------------------------------- /platform-identifier/src/androidNativeTest/kotlin/me/sujanpoudel/utils/platformIdentifier/PlatformTest.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Sujan Poudel 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package me.sujanpoudel.utils.platformIdentifier 18 | 19 | import kotlin.test.Test 20 | import kotlin.test.assertIs 21 | 22 | class PlatformTest { 23 | @Test 24 | fun should_have_correct_platform() { 25 | val platform = platform() 26 | assertIs(platform) 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /platform-identifier/src/androidUnitTest/kotlin/me/sujanpoudel/utils/platformIdentifier/PlatformTest.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Sujan Poudel 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package me.sujanpoudel.utils.platformIdentifier 18 | 19 | import android.content.Context 20 | import android.net.Uri 21 | import androidx.test.core.app.ApplicationProvider 22 | import org.junit.Test 23 | import org.junit.runner.RunWith 24 | import org.robolectric.RobolectricTestRunner 25 | import org.robolectric.shadows.ShadowContentResolver 26 | import kotlin.test.assertIs 27 | 28 | @RunWith(RobolectricTestRunner::class) 29 | class PlatformTest { 30 | @Test 31 | fun should_have_correct_platform() { 32 | val context = ApplicationProvider.getApplicationContext() 33 | 34 | val authority = "${context.packageName}.androidx-startup" 35 | 36 | val uri = Uri.Builder() 37 | .scheme("content") 38 | .authority(authority) 39 | .build() 40 | 41 | ShadowContentResolver.getProvider(uri) 42 | 43 | val platform = platform() 44 | 45 | assertIs(platform) 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /platform-identifier/src/appleMain/kotlin/me/sujanpoudel/utils/platformIdentifier/platform.macos.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Sujan Poudel 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package me.sujanpoudel.utils.platformIdentifier 18 | 19 | import platform.Foundation.NSProcessInfo 20 | import platform.darwin.TARGET_OS_SIMULATOR 21 | import kotlin.experimental.ExperimentalNativeApi 22 | 23 | @OptIn(ExperimentalNativeApi::class) 24 | actual fun platform(): Platform { 25 | val nativePlatform = Platform 26 | 27 | val arch = nativePlatform.cpuArchitecture.asArch() 28 | val version = NSProcessInfo.processInfo.operatingSystemVersionString 29 | 30 | val isSimulator = TARGET_OS_SIMULATOR != 0 31 | 32 | return when (nativePlatform.osFamily) { 33 | OsFamily.MACOSX -> Platform.OS.MacOs(arch, version) 34 | OsFamily.IOS -> Platform.OS.IOS(arch, version, isSimulator) 35 | OsFamily.TVOS -> Platform.OS.TvOs(arch, version, isSimulator) 36 | OsFamily.WATCHOS -> Platform.OS.WatchOs(arch, version, isSimulator) 37 | else -> Platform.OS.Unknown(arch, version) 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /platform-identifier/src/appleTest/kotlin/me/sujanpoudel/utils/platformIdentifier/PlatformTest.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Sujan Poudel 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package me.sujanpoudel.utils.platformIdentifier 18 | 19 | import kotlin.experimental.ExperimentalNativeApi 20 | import kotlin.test.Test 21 | import kotlin.test.assertIs 22 | 23 | @OptIn(ExperimentalNativeApi::class) 24 | class PlatformTest { 25 | @Test 26 | fun should_have_correct_platform() { 27 | val platform = platform() 28 | 29 | when (kotlin.native.Platform.osFamily) { 30 | OsFamily.MACOSX -> assertIs(platform) 31 | OsFamily.IOS -> assertIs(platform) 32 | OsFamily.TVOS -> assertIs(platform) 33 | OsFamily.WATCHOS -> assertIs(platform) 34 | else -> error("invalid platform") 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /platform-identifier/src/commonMain/kotlin/me/sujanpoudel/utils/platformIdentifier/platform.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Sujan Poudel 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package me.sujanpoudel.utils.platformIdentifier 18 | 19 | /** 20 | * CPU Architecture 21 | */ 22 | enum class Arch { 23 | UNKNOWN, 24 | X64, 25 | X86, 26 | ARM_X64, 27 | ARM_X32, 28 | } 29 | 30 | sealed class Platform { 31 | /** 32 | * Running on JS vm environment 33 | */ 34 | sealed class JS : Platform() { 35 | data class Node(val os: OS, val nodeVersion: String, val v8Version: String) : JS() 36 | 37 | data class Browser(val userAgent: String) : JS() 38 | } 39 | 40 | sealed class OS(open val arch: Arch) : Platform() { 41 | data class Unknown(override val arch: Arch, val version: String) : OS(arch) 42 | 43 | data class MacOs(override val arch: Arch, val version: String) : OS(arch) 44 | 45 | data class IOS(override val arch: Arch, val version: String, val isSimulator: Boolean) : OS(arch) 46 | 47 | data class WatchOs(override val arch: Arch, val version: String, val isSimulator: Boolean) : OS(arch) 48 | 49 | data class TvOs(override val arch: Arch, val version: String, val isSimulator: Boolean) : OS(arch) 50 | 51 | data class Android( 52 | override val arch: Arch, 53 | val buildNumber: Int, 54 | val androidVersion: String, 55 | val isWatch: Boolean, 56 | val isTv: Boolean, 57 | ) : OS(arch) 58 | 59 | data class Linux(override val arch: Arch, val version: String) : OS(arch) 60 | 61 | data class Windows(override val arch: Arch, val version: String) : OS(arch) 62 | } 63 | } 64 | 65 | /** 66 | * Get current platform 67 | */ 68 | expect fun platform(): Platform 69 | -------------------------------------------------------------------------------- /platform-identifier/src/desktopCommonMain/kotlin/me/sujanpoudel/utils/platformIdentifier/arch.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Sujan Poudel 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package me.sujanpoudel.utils.platformIdentifier 18 | 19 | internal fun hostArch(archName: String) = when (archName) { 20 | "i486", "i386", "i586", "i686", "x86" -> Arch.X86 21 | "x86_64", "amd64" -> Arch.X64 22 | "aarch_64", "arm64", "aarch64" -> Arch.ARM_X64 23 | "arm32" -> Arch.ARM_X32 24 | else -> Arch.UNKNOWN 25 | } 26 | -------------------------------------------------------------------------------- /platform-identifier/src/desktopCommonMain/kotlin/me/sujanpoudel/utils/platformIdentifier/os.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Sujan Poudel 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package me.sujanpoudel.utils.platformIdentifier 18 | 19 | enum class DesktopOs { 20 | Macos, 21 | Linux, 22 | Windows, 23 | Unknown, 24 | } 25 | 26 | private fun hostOs(name: String) = name.lowercase().let { osName -> 27 | when { 28 | osName.startsWith("mac") || 29 | osName.startsWith("osx") || 30 | osName.startsWith("darwin") -> DesktopOs.Macos 31 | 32 | osName.startsWith("win") -> DesktopOs.Windows 33 | osName.startsWith("linux") -> DesktopOs.Linux 34 | else -> DesktopOs.Unknown 35 | } 36 | } 37 | 38 | internal fun hostOs(osName: String, archName: String, version: String): Platform.OS { 39 | val arch = hostArch(archName) 40 | return when (hostOs(osName)) { 41 | DesktopOs.Macos -> Platform.OS.MacOs(arch, version) 42 | DesktopOs.Linux -> Platform.OS.Linux(arch, version) 43 | DesktopOs.Windows -> Platform.OS.Windows(arch, version) 44 | DesktopOs.Unknown -> Platform.OS.Unknown(arch, version) 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /platform-identifier/src/desktopMain/kotlin/me/sujanpoudel/utils/platformIdentifier/platform.desktop.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Sujan Poudel 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package me.sujanpoudel.utils.platformIdentifier 18 | 19 | val hostOs: Platform.OS = hostOs( 20 | osName = System.getProperty("os.name"), 21 | archName = System.getProperty("os.arch"), 22 | version = System.getProperty("os.version"), 23 | ) 24 | 25 | actual fun platform(): Platform = hostOs 26 | -------------------------------------------------------------------------------- /platform-identifier/src/desktopTest/kotlin/me/sujanpoudel/utils/platformIdentifier/PlatformTest.kt: -------------------------------------------------------------------------------- 1 | package me.sujanpoudel.utils.platformIdentifier 2 | 3 | import org.junit.Test 4 | import kotlin.test.assertTrue 5 | 6 | class PlatformTest { 7 | @Test 8 | fun should_have_correct_platform() { 9 | val platform = platform() 10 | 11 | val osName = System.getProperty("os.name").lowercase() 12 | 13 | when { 14 | osName.startsWith("mac") || 15 | osName.startsWith("osx") || 16 | osName.startsWith("darwin") -> assertTrue { platform is Platform.OS.MacOs } 17 | 18 | osName.startsWith("win") -> assertTrue { platform is Platform.OS.Windows } 19 | osName.startsWith("linux") -> assertTrue { platform is Platform.OS.Linux } 20 | else -> assertTrue { platform is Platform.OS.Unknown } 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /platform-identifier/src/jsMain/kotlin/me/sujanpoudel/utils/platformIdentifier/browser.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Sujan Poudel 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package me.sujanpoudel.utils.platformIdentifier 18 | 19 | fun getBrowserPlatform(): Platform.JS.Browser = Platform.JS.Browser( 20 | eval("navigator.userAgent") as String, 21 | ) 22 | -------------------------------------------------------------------------------- /platform-identifier/src/jsMain/kotlin/me/sujanpoudel/utils/platformIdentifier/node.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Sujan Poudel 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package me.sujanpoudel.utils.platformIdentifier 18 | 19 | internal fun getNodePlatform(): Platform.JS.Node { 20 | val osName = eval("require('os').type()") as String 21 | val archName = eval("require('os').arch()") as String 22 | val osVersion = eval("require('os').version()") as String 23 | 24 | return Platform.JS.Node( 25 | os = hostOs(osName = osName, archName = archName, version = osVersion), 26 | nodeVersion = eval("process.versions.node") as String, 27 | v8Version = eval("process.versions.v8") as String, 28 | ) 29 | } 30 | -------------------------------------------------------------------------------- /platform-identifier/src/jsMain/kotlin/me/sujanpoudel/utils/platformIdentifier/platform.js.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Sujan Poudel 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package me.sujanpoudel.utils.platformIdentifier 18 | 19 | fun isBrowser(): Boolean = 20 | js("""typeof window !== "undefined" && typeof window.document !== "undefined;" """) as Boolean 21 | 22 | fun isNode(): Boolean = 23 | js("""typeof process !== "undefined" && process.versions != null && process.versions.node != null;""") as Boolean 24 | 25 | actual fun platform(): Platform = when { 26 | isBrowser() -> getBrowserPlatform() 27 | isNode() -> getNodePlatform() 28 | else -> getBrowserPlatform() 29 | } 30 | -------------------------------------------------------------------------------- /platform-identifier/src/jsTest/kotlin/me/sujanpoudel/utils/platformIdentifier/PlatformTest.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Sujan Poudel 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package me.sujanpoudel.utils.platformIdentifier 18 | 19 | import kotlin.test.Test 20 | import kotlin.test.assertIs 21 | 22 | class PlatformTest { 23 | @Test 24 | fun should_have_correct_platform() { 25 | val platform = platform() 26 | 27 | if (isNode()) { 28 | assertIs(platform) 29 | } else if (isBrowser()) { 30 | assertIs(platform) 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /platform-identifier/src/mingwMain/kotlin/me/sujanpoudel/utils/platformIdentifier/platform.mingw.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Sujan Poudel 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package me.sujanpoudel.utils.platformIdentifier 18 | 19 | import platform.posix._winmajor 20 | import platform.posix._winminor 21 | import kotlin.experimental.ExperimentalNativeApi 22 | 23 | @OptIn(ExperimentalNativeApi::class) 24 | actual fun platform(): Platform = Platform.OS.Windows( 25 | arch = kotlin.native.Platform.cpuArchitecture.asArch(), 26 | version = "$_winmajor.$_winminor", 27 | ) 28 | -------------------------------------------------------------------------------- /platform-identifier/src/mingwTest/kotlin/me/sujanpoudel/utils/platformIdentifier/PlatformTest.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Sujan Poudel 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package me.sujanpoudel.utils.platformIdentifier 18 | 19 | import kotlin.test.Test 20 | import kotlin.test.assertIs 21 | 22 | class PlatformTest { 23 | @Test 24 | fun should_have_correct_platform() { 25 | val platform = platform() 26 | assertIs(platform) 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /platform-identifier/src/nativeMain/kotlin/me/sujanpoudel/utils/platformIdentifier/CpuArchitecture.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Sujan Poudel 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package me.sujanpoudel.utils.platformIdentifier 18 | 19 | import kotlin.experimental.ExperimentalNativeApi 20 | 21 | @OptIn(ExperimentalNativeApi::class) 22 | fun CpuArchitecture.asArch(): Arch = when (this) { 23 | CpuArchitecture.UNKNOWN -> Arch.UNKNOWN 24 | CpuArchitecture.ARM32 -> Arch.ARM_X32 25 | CpuArchitecture.ARM64 -> Arch.ARM_X64 26 | CpuArchitecture.X86 -> Arch.X86 27 | CpuArchitecture.X64 -> Arch.X64 28 | else -> Arch.UNKNOWN 29 | } 30 | -------------------------------------------------------------------------------- /sample/.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | .idea 4 | .DS_Store 5 | build 6 | captures 7 | .externalNativeBuild 8 | .cxx 9 | local.properties 10 | xcuserdata 11 | 12 | ## things under .idea 13 | .idea/*.xml 14 | .idea/.* 15 | !.idea/codeStyles/* 16 | 17 | build/* -------------------------------------------------------------------------------- /sample/androidApp/.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | .idea 4 | .DS_Store 5 | build 6 | captures 7 | .externalNativeBuild 8 | .cxx 9 | local.properties 10 | xcuserdata 11 | 12 | ## things under .idea 13 | .idea/*.xml 14 | .idea/.* 15 | !.idea/codeStyles/* 16 | 17 | build/* 18 | 19 | release 20 | -------------------------------------------------------------------------------- /sample/androidApp/build.gradle.kts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Sujan Poudel 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | plugins { 18 | id("android-application") 19 | } 20 | 21 | kotlin { 22 | androidTarget() 23 | 24 | sourceSets { 25 | val androidMain by getting { 26 | dependencies { 27 | implementation(projects.sample.shared) 28 | implementation(projects.platformIdentifier) 29 | 30 | implementation(libs.activity.compose) 31 | implementation(libs.core.ktx) 32 | } 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /sample/androidApp/src/androidMain/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 11 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /sample/androidApp/src/androidMain/kotlin/me/sujanpoudel/utils/sample/MainActivity.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Sujan Poudel 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package me.sujanpoudel.utils.sample 18 | 19 | import android.os.Bundle 20 | import androidx.activity.ComponentActivity 21 | import androidx.activity.compose.setContent 22 | import me.sujanpoudel.utils.sample.common.SampleMainAndroid 23 | 24 | class MainActivity : ComponentActivity() { 25 | override fun onCreate(savedInstanceState: Bundle?) { 26 | super.onCreate(savedInstanceState) 27 | 28 | setContent { 29 | SampleMainAndroid() 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /sample/androidApp/src/androidMain/res/mipmap-hdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/psuzn/multiplatform-paths/be42a4b72acd36d685f0a9e52859c7f8d6a916b0/sample/androidApp/src/androidMain/res/mipmap-hdpi/ic_launcher.webp -------------------------------------------------------------------------------- /sample/androidApp/src/androidMain/res/mipmap-hdpi/ic_launcher_foreground.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/psuzn/multiplatform-paths/be42a4b72acd36d685f0a9e52859c7f8d6a916b0/sample/androidApp/src/androidMain/res/mipmap-hdpi/ic_launcher_foreground.webp -------------------------------------------------------------------------------- /sample/androidApp/src/androidMain/res/mipmap-hdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/psuzn/multiplatform-paths/be42a4b72acd36d685f0a9e52859c7f8d6a916b0/sample/androidApp/src/androidMain/res/mipmap-hdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /sample/androidApp/src/androidMain/res/mipmap-mdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/psuzn/multiplatform-paths/be42a4b72acd36d685f0a9e52859c7f8d6a916b0/sample/androidApp/src/androidMain/res/mipmap-mdpi/ic_launcher.webp -------------------------------------------------------------------------------- /sample/androidApp/src/androidMain/res/mipmap-mdpi/ic_launcher_foreground.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/psuzn/multiplatform-paths/be42a4b72acd36d685f0a9e52859c7f8d6a916b0/sample/androidApp/src/androidMain/res/mipmap-mdpi/ic_launcher_foreground.webp -------------------------------------------------------------------------------- /sample/androidApp/src/androidMain/res/mipmap-mdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/psuzn/multiplatform-paths/be42a4b72acd36d685f0a9e52859c7f8d6a916b0/sample/androidApp/src/androidMain/res/mipmap-mdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /sample/androidApp/src/androidMain/res/mipmap-xhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/psuzn/multiplatform-paths/be42a4b72acd36d685f0a9e52859c7f8d6a916b0/sample/androidApp/src/androidMain/res/mipmap-xhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /sample/androidApp/src/androidMain/res/mipmap-xhdpi/ic_launcher_foreground.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/psuzn/multiplatform-paths/be42a4b72acd36d685f0a9e52859c7f8d6a916b0/sample/androidApp/src/androidMain/res/mipmap-xhdpi/ic_launcher_foreground.webp -------------------------------------------------------------------------------- /sample/androidApp/src/androidMain/res/mipmap-xhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/psuzn/multiplatform-paths/be42a4b72acd36d685f0a9e52859c7f8d6a916b0/sample/androidApp/src/androidMain/res/mipmap-xhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /sample/androidApp/src/androidMain/res/mipmap-xxhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/psuzn/multiplatform-paths/be42a4b72acd36d685f0a9e52859c7f8d6a916b0/sample/androidApp/src/androidMain/res/mipmap-xxhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /sample/androidApp/src/androidMain/res/mipmap-xxhdpi/ic_launcher_foreground.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/psuzn/multiplatform-paths/be42a4b72acd36d685f0a9e52859c7f8d6a916b0/sample/androidApp/src/androidMain/res/mipmap-xxhdpi/ic_launcher_foreground.webp -------------------------------------------------------------------------------- /sample/androidApp/src/androidMain/res/mipmap-xxhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/psuzn/multiplatform-paths/be42a4b72acd36d685f0a9e52859c7f8d6a916b0/sample/androidApp/src/androidMain/res/mipmap-xxhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /sample/androidApp/src/androidMain/res/mipmap-xxxhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/psuzn/multiplatform-paths/be42a4b72acd36d685f0a9e52859c7f8d6a916b0/sample/androidApp/src/androidMain/res/mipmap-xxxhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /sample/androidApp/src/androidMain/res/mipmap-xxxhdpi/ic_launcher_foreground.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/psuzn/multiplatform-paths/be42a4b72acd36d685f0a9e52859c7f8d6a916b0/sample/androidApp/src/androidMain/res/mipmap-xxxhdpi/ic_launcher_foreground.webp -------------------------------------------------------------------------------- /sample/androidApp/src/androidMain/res/mipmap-xxxhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/psuzn/multiplatform-paths/be42a4b72acd36d685f0a9e52859c7f8d6a916b0/sample/androidApp/src/androidMain/res/mipmap-xxxhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /sample/androidApp/src/androidMain/res/values-night/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /sample/androidApp/src/androidMain/res/values/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #E6E9FF 4 | -------------------------------------------------------------------------------- /sample/androidApp/src/androidMain/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Multiplatform Utils Sample 4 | 5 | -------------------------------------------------------------------------------- /sample/androidApp/src/androidMain/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | -------------------------------------------------------------------------------- /sample/desktopApp/.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | .idea 4 | .DS_Store 5 | build 6 | captures 7 | .externalNativeBuild 8 | .cxx 9 | local.properties 10 | xcuserdata -------------------------------------------------------------------------------- /sample/desktopApp/build.gradle.kts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Sujan Poudel 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | plugins { 18 | id("module") 19 | alias(libs.plugins.kotlin.multiplatform) 20 | alias(libs.plugins.compose) 21 | } 22 | 23 | kotlin { 24 | jvm {} 25 | sourceSets { 26 | val jvmMain by getting { 27 | dependencies { 28 | implementation(projects.sample.shared) 29 | 30 | implementation(compose.desktop.currentOs) 31 | } 32 | } 33 | } 34 | } 35 | 36 | compose.desktop { 37 | application { 38 | mainClass = "MainKt" 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /sample/desktopApp/src/jvmMain/kotlin/Main.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Sujan Poudel 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import androidx.compose.ui.unit.DpSize 18 | import androidx.compose.ui.unit.dp 19 | import androidx.compose.ui.window.WindowState 20 | import androidx.compose.ui.window.singleWindowApplication 21 | import me.sujanpoudel.utils.sample.common.MainDesktopView 22 | 23 | fun main(): Unit = singleWindowApplication( 24 | title = "Sample", 25 | state = WindowState( 26 | size = DpSize(400.dp, 800.dp), 27 | ), 28 | resizable = false, 29 | ) { 30 | MainDesktopView() 31 | } 32 | -------------------------------------------------------------------------------- /sample/iosApp/.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## User settings 6 | xcuserdata/ 7 | 8 | ## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9) 9 | *.xcscmblueprint 10 | *.xccheckout 11 | 12 | ## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4) 13 | build/ 14 | DerivedData/ 15 | *.moved-aside 16 | *.pbxuser 17 | !default.pbxuser 18 | *.mode1v3 19 | !default.mode1v3 20 | *.mode2v3 21 | !default.mode2v3 22 | *.perspectivev3 23 | !default.perspectivev3 24 | 25 | ## Obj-C/Swift specific 26 | *.hmap 27 | 28 | ## App packaging 29 | *.ipa 30 | *.dSYM.zip 31 | *.dSYM 32 | 33 | ## Playgrounds 34 | timeline.xctimeline 35 | playground.xcworkspace 36 | 37 | # Swift Package Manager 38 | # 39 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. 40 | # Packages/ 41 | # Package.pins 42 | # Package.resolved 43 | # *.xcodeproj 44 | # 45 | # Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata 46 | # hence it is not needed unless you have added a package configuration file to your project 47 | # .swiftpm 48 | 49 | .build/ 50 | 51 | # CocoaPods 52 | # 53 | # We recommend against adding the Pods directory to your .gitignore. However 54 | # you should judge for yourself, the pros and cons are mentioned at: 55 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 56 | # 57 | Pods/ 58 | # 59 | # Add this line if you want to avoid checking in source code from the Xcode workspace 60 | # *.xcworkspace 61 | 62 | # Carthage 63 | # 64 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 65 | # Carthage/Checkouts 66 | 67 | Carthage/Build/ 68 | 69 | # Accio dependency management 70 | Dependencies/ 71 | .accio/ 72 | 73 | # fastlane 74 | # 75 | # It is recommended to not store the screenshots in the git repo. 76 | # Instead, use fastlane to re-generate the screenshots whenever they are needed. 77 | # For more information about the recommended setup visit: 78 | # https://docs.fastlane.tools/best-practices/source-control/#source-control 79 | 80 | fastlane/report.xml 81 | fastlane/Preview.html 82 | fastlane/screenshots/**/*.png 83 | fastlane/test_output 84 | 85 | # Code Injection 86 | # 87 | # After new code Injection tools there's a generated folder /iOSInjectionProject 88 | # https://github.com/johnno1962/injectionforxcode 89 | 90 | iOSInjectionProject/ 91 | 92 | .DS_Store 93 | **/.DS_Store 94 | **/**/.DS_Store -------------------------------------------------------------------------------- /sample/iosApp/iosApp.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /sample/iosApp/iosApp.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /sample/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "platform" : "ios", 6 | "scale" : "2x", 7 | "size" : "20x20" 8 | }, 9 | { 10 | "idiom" : "universal", 11 | "platform" : "ios", 12 | "scale" : "3x", 13 | "size" : "20x20" 14 | }, 15 | { 16 | "idiom" : "universal", 17 | "platform" : "ios", 18 | "scale" : "2x", 19 | "size" : "29x29" 20 | }, 21 | { 22 | "idiom" : "universal", 23 | "platform" : "ios", 24 | "scale" : "3x", 25 | "size" : "29x29" 26 | }, 27 | { 28 | "idiom" : "universal", 29 | "platform" : "ios", 30 | "scale" : "2x", 31 | "size" : "38x38" 32 | }, 33 | { 34 | "idiom" : "universal", 35 | "platform" : "ios", 36 | "scale" : "3x", 37 | "size" : "38x38" 38 | }, 39 | { 40 | "idiom" : "universal", 41 | "platform" : "ios", 42 | "scale" : "2x", 43 | "size" : "40x40" 44 | }, 45 | { 46 | "idiom" : "universal", 47 | "platform" : "ios", 48 | "scale" : "3x", 49 | "size" : "40x40" 50 | }, 51 | { 52 | "idiom" : "universal", 53 | "platform" : "ios", 54 | "scale" : "2x", 55 | "size" : "60x60" 56 | }, 57 | { 58 | "idiom" : "universal", 59 | "platform" : "ios", 60 | "scale" : "3x", 61 | "size" : "60x60" 62 | }, 63 | { 64 | "idiom" : "universal", 65 | "platform" : "ios", 66 | "scale" : "2x", 67 | "size" : "64x64" 68 | }, 69 | { 70 | "idiom" : "universal", 71 | "platform" : "ios", 72 | "scale" : "3x", 73 | "size" : "64x64" 74 | }, 75 | { 76 | "idiom" : "universal", 77 | "platform" : "ios", 78 | "scale" : "2x", 79 | "size" : "68x68" 80 | }, 81 | { 82 | "idiom" : "universal", 83 | "platform" : "ios", 84 | "scale" : "2x", 85 | "size" : "76x76" 86 | }, 87 | { 88 | "idiom" : "universal", 89 | "platform" : "ios", 90 | "scale" : "2x", 91 | "size" : "83.5x83.5" 92 | }, 93 | { 94 | "idiom" : "universal", 95 | "platform" : "ios", 96 | "size" : "1024x1024" 97 | } 98 | ], 99 | "info" : { 100 | "author" : "xcode", 101 | "version" : 1 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /sample/iosApp/iosApp/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /sample/iosApp/iosApp/ContentView.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | import shared 3 | import Foundation 4 | 5 | struct ComposeView: UIViewControllerRepresentable { 6 | 7 | func makeUIViewController(context: Context) -> UIViewController { 8 | return Main_iosKt.MainViewController() 9 | } 10 | 11 | func updateUIViewController(_ uiViewController: UIViewController, context: Context) { 12 | 13 | } 14 | } 15 | 16 | -------------------------------------------------------------------------------- /sample/iosApp/iosApp/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UIApplicationSceneManifest 24 | 25 | UIApplicationSupportsMultipleScenes 26 | 27 | 28 | UILaunchScreen 29 | 30 | UIRequiredDeviceCapabilities 31 | 32 | armv7 33 | 34 | UIStatusBarStyle 35 | 36 | UISupportedInterfaceOrientations 37 | 38 | UIInterfaceOrientationPortrait 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /sample/iosApp/iosApp/Preview Content/Preview Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } -------------------------------------------------------------------------------- /sample/iosApp/iosApp/iOSApp.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | @main 4 | struct iOSApp: App { 5 | var body: some Scene { 6 | WindowGroup { 7 | ComposeView() 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /sample/macosApp/.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | .idea 4 | .DS_Store 5 | build 6 | captures 7 | .externalNativeBuild 8 | .cxx 9 | local.properties 10 | xcuserdata 11 | 12 | ## things under .idea 13 | .idea/*.xml 14 | .idea/.* 15 | !.idea/codeStyles/* 16 | 17 | build/* 18 | 19 | release 20 | -------------------------------------------------------------------------------- /sample/macosApp/build.gradle.kts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Sujan Poudel 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTargetWithHostTests 18 | 19 | plugins { 20 | id("module") 21 | alias(libs.plugins.kotlin.multiplatform) 22 | alias(libs.plugins.compose) 23 | } 24 | 25 | fun KotlinNativeTargetWithHostTests.makeExecutableBinary() { 26 | binaries { 27 | executable { 28 | entryPoint = "main" 29 | } 30 | } 31 | } 32 | 33 | kotlin { 34 | sourceSets { 35 | macosArm64().makeExecutableBinary() 36 | macosX64().makeExecutableBinary() 37 | 38 | macosMain { 39 | dependencies { 40 | implementation(projects.sample.shared) 41 | 42 | implementation(compose.ui) 43 | } 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /sample/macosApp/src/macosMain/kotlin/main.macos.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Sujan Poudel 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import androidx.compose.ui.window.Window 18 | import me.sujanpoudel.utils.sample.common.MainUI 19 | import platform.AppKit.NSApp 20 | import platform.AppKit.NSApplication 21 | 22 | fun main() { 23 | NSApplication.sharedApplication() 24 | Window("Chat App") { 25 | MainUI() 26 | } 27 | NSApp?.run() 28 | } 29 | -------------------------------------------------------------------------------- /sample/nodeApp/.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | .idea 4 | .DS_Store 5 | build 6 | captures 7 | .externalNativeBuild 8 | .cxx 9 | local.properties 10 | xcuserdata 11 | 12 | ## things under .idea 13 | .idea/*.xml 14 | .idea/.* 15 | !.idea/codeStyles/* 16 | 17 | build/* 18 | 19 | release 20 | -------------------------------------------------------------------------------- /sample/nodeApp/build.gradle.kts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Sujan Poudel 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | plugins { 18 | id("module") 19 | alias(libs.plugins.kotlin.multiplatform) 20 | } 21 | 22 | kotlin { 23 | 24 | js(IR) { 25 | nodejs() 26 | 27 | binaries.executable() 28 | } 29 | 30 | sourceSets { 31 | commonMain { 32 | dependencies { 33 | implementation(projects.platformIdentifier) 34 | implementation(projects.multiplatformPaths) 35 | 36 | implementation(libs.kotlinx.io.core) 37 | } 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /sample/nodeApp/src/jsMain/kotlin/me/sujanpoudel/utils/sample/main.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Sujan Poudel 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package me.sujanpoudel.utils.sample 18 | 19 | import me.sujanpoudel.utils.paths.appCacheDirectory 20 | import me.sujanpoudel.utils.paths.appDataDirectory 21 | import me.sujanpoudel.utils.platformIdentifier.platform 22 | 23 | const val APP_ID: String = "me.sujanpoudel.multiplatform.utils.sample" 24 | 25 | fun main() { 26 | println( 27 | """ 28 | _ _ _ _ _____ _ 29 | | \ | | | | | | / ____| | | 30 | | \| | ___ __| | ___ | |___ | (___ __ _ _ __ ___ _ __ | | ___ 31 | | . ` |/ _ \ / _` |/ _ \ _ | / __| \___ \ / _` | '_ ` _ \| '_ \| |/ _ \ 32 | | |\ | (_) | (_| | __/ | |__| \__ \ ____) | (_| | | | | | | |_) | | __/ 33 | |_| \_|\___/ \__,_|\___| \____/|___/ |_____/ \__,_|_| |_| |_| .__/|_|\___| 34 | | | 35 | |_| 36 | 37 | """.trimIndent(), 38 | ) 39 | 40 | println("platform is: ${platform()}") 41 | println("Paths") 42 | println("Application directory: ${appDataDirectory(APP_ID)}") 43 | println("Cache directory: ${appCacheDirectory(APP_ID)} \n\n") 44 | } 45 | -------------------------------------------------------------------------------- /sample/shared/.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | .idea 4 | .DS_Store 5 | build 6 | captures 7 | .externalNativeBuild 8 | .cxx 9 | local.properties 10 | xcuserdata -------------------------------------------------------------------------------- /sample/shared/build.gradle.kts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Sujan Poudel 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget 18 | 19 | plugins { 20 | id("multiplatform-library") 21 | alias(libs.plugins.compose) 22 | } 23 | 24 | version = "1.0-SNAPSHOT" 25 | group = "${group()}.sample" 26 | 27 | fun KotlinNativeTarget.configureFramework() { 28 | binaries.framework { 29 | baseName = "shared" 30 | isStatic = true 31 | } 32 | } 33 | 34 | kotlin { 35 | applyDefaultHierarchyTemplate() 36 | 37 | js { 38 | nodejs() 39 | } 40 | 41 | iosArm64().configureFramework() 42 | iosSimulatorArm64().configureFramework() 43 | macosArm64().configureFramework() 44 | macosX64().configureFramework() 45 | 46 | sourceSets { 47 | 48 | val commonMain by getting { 49 | dependencies { 50 | implementation(projects.platformIdentifier) 51 | implementation(projects.multiplatformPaths) 52 | 53 | implementation(compose.runtime) 54 | implementation(compose.ui) 55 | implementation(compose.material) 56 | implementation(libs.kotlinx.io.core) 57 | } 58 | } 59 | } 60 | } 61 | 62 | android { 63 | buildFeatures { 64 | compose = true 65 | buildConfig = true 66 | } 67 | 68 | composeOptions { 69 | kotlinCompilerExtensionVersion = libs.versions.composeCompiler.get() 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /sample/shared/src/androidMain/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /sample/shared/src/androidMain/kotlin/me/sujanpoudel/utils/sample/common/App.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Sujan Poudel 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package me.sujanpoudel.utils.sample.common 18 | 19 | import androidx.compose.runtime.Composable 20 | 21 | @Composable 22 | fun SampleMainAndroid() { 23 | MainUI() 24 | } 25 | -------------------------------------------------------------------------------- /sample/shared/src/commonMain/kotlin/me/sujanpoudel/utils/sample/common/Color.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Sujan Poudel 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package me.sujanpoudel.utils.sample.common 18 | 19 | import androidx.compose.ui.graphics.Color 20 | 21 | val SampleGreen: Color = Color(0xff09B3AF) 22 | val SampleGreenDark: Color = Color(0xff008380) 23 | 24 | val Red200: Color = Color(0xfff297a2) 25 | val Red800: Color = Color(0xffd00036) 26 | -------------------------------------------------------------------------------- /sample/shared/src/commonMain/kotlin/me/sujanpoudel/utils/sample/common/Constants.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Sujan Poudel 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package me.sujanpoudel.utils.sample.common 18 | 19 | object Constants { 20 | const val APP_ID: String = "me.sujanpoudel.multiplatform.utils.sample" 21 | } 22 | -------------------------------------------------------------------------------- /sample/shared/src/commonMain/kotlin/me/sujanpoudel/utils/sample/common/MainUI.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Sujan Poudel 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package me.sujanpoudel.utils.sample.common 18 | 19 | import androidx.compose.foundation.layout.Arrangement 20 | import androidx.compose.foundation.layout.Column 21 | import androidx.compose.foundation.layout.padding 22 | import androidx.compose.foundation.rememberScrollState 23 | import androidx.compose.foundation.verticalScroll 24 | import androidx.compose.material.MaterialTheme 25 | import androidx.compose.material.Scaffold 26 | import androidx.compose.material.Text 27 | import androidx.compose.runtime.Composable 28 | import androidx.compose.runtime.remember 29 | import androidx.compose.ui.Alignment 30 | import androidx.compose.ui.Modifier 31 | import androidx.compose.ui.unit.dp 32 | import me.sujanpoudel.utils.paths.appCacheDirectory 33 | import me.sujanpoudel.utils.paths.appDataDirectory 34 | import me.sujanpoudel.utils.platformIdentifier.Platform 35 | import me.sujanpoudel.utils.platformIdentifier.platform 36 | 37 | @Composable 38 | fun MainUI() { 39 | val appHomeDir = remember { 40 | if (platform() !is Platform.JS.Browser) { 41 | appDataDirectory(Constants.APP_ID) 42 | } else { 43 | "N/A" 44 | } 45 | } 46 | 47 | val cacheDir = remember { 48 | if (platform() !is Platform.JS.Browser) { 49 | appCacheDirectory(Constants.APP_ID) 50 | } else { 51 | "N/A" 52 | } 53 | } 54 | 55 | val scrollState = rememberScrollState() 56 | 57 | SampleTheme { 58 | Scaffold { 59 | Column( 60 | modifier = Modifier 61 | .verticalScroll(scrollState) 62 | .padding(it) 63 | .padding(16.dp), 64 | verticalArrangement = Arrangement.spacedBy(16.dp), 65 | horizontalAlignment = Alignment.CenterHorizontally, 66 | ) { 67 | Text("Platform:", style = MaterialTheme.typography.h6) 68 | Text(platform().toString(), style = MaterialTheme.typography.caption) 69 | 70 | Text("App Directories:", style = MaterialTheme.typography.h6) 71 | Column( 72 | modifier = Modifier.padding(16.dp), 73 | verticalArrangement = Arrangement.spacedBy(8.dp), 74 | ) { 75 | Text("App Home: $appHomeDir", style = MaterialTheme.typography.caption) 76 | Text("App Cache: $cacheDir", style = MaterialTheme.typography.caption) 77 | } 78 | } 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /sample/shared/src/commonMain/kotlin/me/sujanpoudel/utils/sample/common/Theme.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Sujan Poudel 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package me.sujanpoudel.utils.sample.common 18 | 19 | import androidx.compose.foundation.isSystemInDarkTheme 20 | import androidx.compose.material.MaterialTheme 21 | import androidx.compose.material.darkColors 22 | import androidx.compose.material.lightColors 23 | import androidx.compose.runtime.Composable 24 | import androidx.compose.ui.graphics.Color 25 | 26 | private val DarkColorPalette = darkColors( 27 | background = Color.Black, 28 | onBackground = Color.White, 29 | primary = SampleGreen, 30 | primaryVariant = SampleGreenDark, 31 | onPrimary = Color.White, 32 | secondary = SampleGreen, 33 | onSecondary = Color.White, 34 | error = Red200, 35 | ) 36 | 37 | private val LightColorPalette = lightColors( 38 | background = Color.White, 39 | onBackground = Color.Black, 40 | primary = SampleGreen, 41 | primaryVariant = SampleGreenDark, 42 | onPrimary = Color.White, 43 | secondary = SampleGreen, 44 | secondaryVariant = SampleGreenDark, 45 | onSecondary = Color.White, 46 | error = Red800, 47 | ) 48 | 49 | @Composable 50 | fun SampleTheme(darkTheme: Boolean = isSystemInDarkTheme(), content: @Composable() () -> Unit) { 51 | val colors = 52 | if (darkTheme) { 53 | DarkColorPalette 54 | } else { 55 | LightColorPalette 56 | } 57 | 58 | MaterialTheme( 59 | colors = colors, 60 | content = content, 61 | ) 62 | } 63 | -------------------------------------------------------------------------------- /sample/shared/src/desktopMain/kotlin/me/sujanpoudel/utils/sample/common/main.desktop.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Sujan Poudel 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package me.sujanpoudel.utils.sample.common 18 | 19 | import androidx.compose.runtime.Composable 20 | 21 | @Composable 22 | fun MainDesktopView() { 23 | MainUI() 24 | } 25 | -------------------------------------------------------------------------------- /sample/shared/src/iosMain/kotlin/me/sujanpoudel/utils/sample/common/main.ios.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Sujan Poudel 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package me.sujanpoudel.utils.sample.common 18 | 19 | import androidx.compose.ui.window.ComposeUIViewController 20 | import platform.UIKit.UIViewController 21 | 22 | @Suppress("FunctionName", "unused") 23 | fun MainViewController(): UIViewController = ComposeUIViewController { 24 | MainUI() 25 | } 26 | -------------------------------------------------------------------------------- /sample/wearosApp/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /sample/wearosApp/build.gradle.kts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Sujan Poudel 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | plugins { 18 | id("android-application") 19 | } 20 | 21 | kotlin { 22 | 23 | applyDefaultHierarchyTemplate() 24 | 25 | androidTarget() 26 | 27 | sourceSets { 28 | 29 | androidMain { 30 | dependencies { 31 | implementation(projects.sample.shared) 32 | implementation(projects.platformIdentifier) 33 | implementation(libs.appcompat) 34 | implementation(libs.activity.compose) 35 | } 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /sample/wearosApp/lint.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /sample/wearosApp/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile -------------------------------------------------------------------------------- /sample/wearosApp/src/androidMain/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 13 | 14 | 17 | 18 | 21 | 22 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /sample/wearosApp/src/androidMain/kotlin/me/sujanpoudel/utils/sample/wearOs/MainActivity.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 Sujan Poudel 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package me.sujanpoudel.utils.sample.wearOs 18 | 19 | import android.os.Bundle 20 | import androidx.activity.ComponentActivity 21 | import androidx.activity.compose.setContent 22 | import me.sujanpoudel.utils.sample.common.SampleMainAndroid 23 | 24 | class MainActivity : ComponentActivity() { 25 | override fun onCreate(savedInstanceState: Bundle?) { 26 | super.onCreate(savedInstanceState) 27 | 28 | setTheme(android.R.style.Theme_DeviceDefault) 29 | 30 | setContent { 31 | SampleMainAndroid() 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /sample/wearosApp/src/androidMain/res/mipmap-hdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/psuzn/multiplatform-paths/be42a4b72acd36d685f0a9e52859c7f8d6a916b0/sample/wearosApp/src/androidMain/res/mipmap-hdpi/ic_launcher.webp -------------------------------------------------------------------------------- /sample/wearosApp/src/androidMain/res/mipmap-hdpi/ic_launcher_foreground.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/psuzn/multiplatform-paths/be42a4b72acd36d685f0a9e52859c7f8d6a916b0/sample/wearosApp/src/androidMain/res/mipmap-hdpi/ic_launcher_foreground.webp -------------------------------------------------------------------------------- /sample/wearosApp/src/androidMain/res/mipmap-hdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/psuzn/multiplatform-paths/be42a4b72acd36d685f0a9e52859c7f8d6a916b0/sample/wearosApp/src/androidMain/res/mipmap-hdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /sample/wearosApp/src/androidMain/res/mipmap-mdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/psuzn/multiplatform-paths/be42a4b72acd36d685f0a9e52859c7f8d6a916b0/sample/wearosApp/src/androidMain/res/mipmap-mdpi/ic_launcher.webp -------------------------------------------------------------------------------- /sample/wearosApp/src/androidMain/res/mipmap-mdpi/ic_launcher_foreground.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/psuzn/multiplatform-paths/be42a4b72acd36d685f0a9e52859c7f8d6a916b0/sample/wearosApp/src/androidMain/res/mipmap-mdpi/ic_launcher_foreground.webp -------------------------------------------------------------------------------- /sample/wearosApp/src/androidMain/res/mipmap-mdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/psuzn/multiplatform-paths/be42a4b72acd36d685f0a9e52859c7f8d6a916b0/sample/wearosApp/src/androidMain/res/mipmap-mdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /sample/wearosApp/src/androidMain/res/mipmap-xhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/psuzn/multiplatform-paths/be42a4b72acd36d685f0a9e52859c7f8d6a916b0/sample/wearosApp/src/androidMain/res/mipmap-xhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /sample/wearosApp/src/androidMain/res/mipmap-xhdpi/ic_launcher_foreground.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/psuzn/multiplatform-paths/be42a4b72acd36d685f0a9e52859c7f8d6a916b0/sample/wearosApp/src/androidMain/res/mipmap-xhdpi/ic_launcher_foreground.webp -------------------------------------------------------------------------------- /sample/wearosApp/src/androidMain/res/mipmap-xhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/psuzn/multiplatform-paths/be42a4b72acd36d685f0a9e52859c7f8d6a916b0/sample/wearosApp/src/androidMain/res/mipmap-xhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /sample/wearosApp/src/androidMain/res/mipmap-xxhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/psuzn/multiplatform-paths/be42a4b72acd36d685f0a9e52859c7f8d6a916b0/sample/wearosApp/src/androidMain/res/mipmap-xxhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /sample/wearosApp/src/androidMain/res/mipmap-xxhdpi/ic_launcher_foreground.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/psuzn/multiplatform-paths/be42a4b72acd36d685f0a9e52859c7f8d6a916b0/sample/wearosApp/src/androidMain/res/mipmap-xxhdpi/ic_launcher_foreground.webp -------------------------------------------------------------------------------- /sample/wearosApp/src/androidMain/res/mipmap-xxhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/psuzn/multiplatform-paths/be42a4b72acd36d685f0a9e52859c7f8d6a916b0/sample/wearosApp/src/androidMain/res/mipmap-xxhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /sample/wearosApp/src/androidMain/res/mipmap-xxxhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/psuzn/multiplatform-paths/be42a4b72acd36d685f0a9e52859c7f8d6a916b0/sample/wearosApp/src/androidMain/res/mipmap-xxxhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /sample/wearosApp/src/androidMain/res/mipmap-xxxhdpi/ic_launcher_foreground.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/psuzn/multiplatform-paths/be42a4b72acd36d685f0a9e52859c7f8d6a916b0/sample/wearosApp/src/androidMain/res/mipmap-xxxhdpi/ic_launcher_foreground.webp -------------------------------------------------------------------------------- /sample/wearosApp/src/androidMain/res/mipmap-xxxhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/psuzn/multiplatform-paths/be42a4b72acd36d685f0a9e52859c7f8d6a916b0/sample/wearosApp/src/androidMain/res/mipmap-xxxhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /sample/wearosApp/src/androidMain/res/values/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #E6E9FF 4 | -------------------------------------------------------------------------------- /sample/wearosApp/src/androidMain/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | MP Utils 3 | 4 | -------------------------------------------------------------------------------- /sample/wearosApp/src/androidMain/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 |