KMP Readiness IS UNDER DEVELOPMENT
Decisioning Logic
Positive Signals ✅
Only Kotlin .kt
Source Files
Using Kotlin JVM Plugin
Uses the Kotlin Multiplatform Plugin
- NOTE: We could check the configuration in the future to see if it has multiple targets if deemed important.
Negative Signals ❌
Are there any java imports in the source files?
Imports starting with java.
, etc.
- Iterate through all
main
sourcesets for a simple.contains("import java.")
List of all java stdlib packages: https://docs.oracle.com/en/java/javase/11/docs/api/java.base/module-summary.html - NOTE: This wouldn’t find fully qualified references, but that could be added later if deemed important.
Any non-multiplatform dependencies?
Search for transitive artifacts that are not multiplatform compatible
- Use a list of well known libraries that are known to be multiplatform compatible, but then using the Maven Search API to look for the presence of the
kotlin-tooling-metadata.json
object via their JSON API at https://search.maven.org/. - NOTE: These results would be cached, the same way dependencies are today.
- NOTE: We could traverse local module dependencies, and check theirs as well if deemed important.
Is this an Android Library Module?
Could work if…
- No
res
folder - No
assets
folder - Uses no
android.
packages in the source AndroidManifest.xml
only defines package name.
kmpReadiness
Gradle Task
Could be applied to a specific module or the root so that all modules are scanned.
Run the kmpReadiness
task and get a result like this:
┌─────────────────────────────────┬───────────────────────────────────────────────────────────────────────────────────────────────────────────┬────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ Module │ KMP Readiness Result │ Data │
├─────────────────────────────────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────┼────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ :samples:android_app │ Not KMP Ready │ { │
│ │ --- │ "projectName": ":samples:android_app", │
│ │ ✅ HasOnlyMultiplatformCompatibleDependencies │ "dependencyAnalysis": { │
│ │ ✅ HasOnlyKotlinFiles │ "compatible": [ │
│ │ ❌ DoesNotHaveKotlinJvmOrMultiplatformPlugin │ ], │
│ │ │ "incompatible": [ │
│ │ │ ] │
│ │ │ }, │
│ │ │ "gradlePlugins": { │
│ │ │ "kotlin": false, │
│ │ │ "multiplatform": false, │
│ │ │ "java": false │
│ │ │ }, │
│ │ │ "sourceSets": { │
│ │ │ "sourceSetToFiles": { │
│ │ │ } │
│ │ │ } │
│ │ │ } │
├─────────────────────────────────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────┼────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ :samples:android_lib │ Not KMP Ready │ { │
│ │ --- │ "projectName": ":samples:android_lib", │
│ │ ✅ HasOnlyMultiplatformCompatibleDependencies │ "dependencyAnalysis": { │
│ │ ✅ HasOnlyKotlinFiles │ "compatible": [ │
│ │ ❌ DoesNotHaveKotlinJvmOrMultiplatformPlugin │ ], │
│ │ │ "incompatible": [ │
│ │ │ ] │
│ │ │ }, │
│ │ │ "gradlePlugins": { │
│ │ │ "kotlin": false, │
│ │ │ "multiplatform": false, │
│ │ │ "java": false │
│ │ │ }, │
│ │ │ "sourceSets": { │
│ │ │ "sourceSetToFiles": { │
│ │ │ } │
│ │ │ } │
│ │ │ } │
├─────────────────────────────────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────┼────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ :samples:jvm │ Not KMP Ready │ { │
│ │ --- │ "projectName": ":samples:jvm", │
│ │ ✅ HasOnlyKotlinFiles │ "dependencyAnalysis": { │
│ │ ✅ KotlinPluginEnabled │ "compatible": [ │
│ │ ❌ IncompatibleDependencies │ "org.jetbrains.kotlin:kotlin-stdlib:1.6.21" │
│ │ * com.google.truth:truth:1.1.3 │ ], │
│ │ │ "incompatible": [ │
│ │ │ "com.google.truth:truth:1.1.3" │
│ │ │ ] │
│ │ │ }, │
│ │ │ "gradlePlugins": { │
│ │ │ "kotlin": true, │
│ │ │ "multiplatform": false, │
│ │ │ "java": true │
│ │ │ }, │
│ │ │ "sourceSets": { │
│ │ │ "sourceSetToFiles": { │
│ │ │ "kotlin-main": [ │
│ │ │ "/Users/samedwards/src/kmp-readiness/samples/jvm/src/main/java/kmp4free/samples/JvmLib.kt" │
│ │ │ ], │
│ │ │ "java-main": [ │
│ │ │ ] │
│ │ │ } │
│ │ │ } │
│ │ │ } │
├─────────────────────────────────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────┼────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ :samples:jvm_kmp4free │ Not KMP Ready │ { │
│ │ --- │ "projectName": ":samples:jvm_kmp4free", │
│ │ ✅ HasOnlyMultiplatformCompatibleDependencies │ "dependencyAnalysis": { │
│ │ ✅ KotlinPluginEnabled │ "compatible": [ │
│ │ ❌ HasJavaFiles │ "org.jetbrains.kotlin:kotlin-stdlib:1.6.21", │
│ │ * /Users/samedwards/src/kmp-readiness/samples/jvm_kmp4free/src/main/kotlin/kmp4free/samples/JvmMain2.java │ "org.jetbrains.kotlinx:kotlinx-datetime:0.3.2" │
│ │ │ ], │
│ │ │ "incompatible": [ │
│ │ │ ] │
│ │ │ }, │
│ │ │ "gradlePlugins": { │
│ │ │ "kotlin": true, │
│ │ │ "multiplatform": false, │
│ │ │ "java": true │
│ │ │ }, │
│ │ │ "sourceSets": { │
│ │ │ "sourceSetToFiles": { │
│ │ │ "kotlin-main": [ │
│ │ │ "/Users/samedwards/src/kmp-readiness/samples/jvm_kmp4free/src/main/kotlin/kmp4free/samples/JvmMain2.java", │
│ │ │ "/Users/samedwards/src/kmp-readiness/samples/jvm_kmp4free/src/main/kotlin/kmp4free/samples/JvmMain.kt" │
│ │ │ ], │
│ │ │ "java-main": [ │
│ │ │ ] │
│ │ │ } │
│ │ │ } │
│ │ │ } │
├─────────────────────────────────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────┼────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ :samples:multiplatform │ KMP Ready │ { │
│ │ --- │ "projectName": ":samples:multiplatform", │
│ │ ✅ HasOnlyMultiplatformCompatibleDependencies │ "dependencyAnalysis": { │
│ │ ✅ HasOnlyKotlinFiles │ "compatible": [ │
│ │ ✅ MultiplatformPluginAlreadyEnabled │ ], │
│ │ │ "incompatible": [ │
│ │ │ ] │
│ │ │ }, │
│ │ │ "gradlePlugins": { │
│ │ │ "kotlin": false, │
│ │ │ "multiplatform": true, │
│ │ │ "java": false │
│ │ │ }, │
│ │ │ "sourceSets": { │
│ │ │ "sourceSetToFiles": { │
│ │ │ } │
│ │ │ } │
│ │ │ } │
├─────────────────────────────────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────┼────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ :samples:multiplatform_kmp4free │ KMP Ready │ { │
│ │ --- │ "projectName": ":samples:multiplatform_kmp4free", │
│ │ ✅ HasOnlyMultiplatformCompatibleDependencies │ "dependencyAnalysis": { │
│ │ ✅ HasOnlyKotlinFiles │ "compatible": [ │
│ │ ✅ KotlinPluginEnabled │ "org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.6.21", │
│ │ │ "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.1" │
│ │ │ ], │
│ │ │ "incompatible": [ │
│ │ │ ] │
│ │ │ }, │
│ │ │ "gradlePlugins": { │
│ │ │ "kotlin": true, │
│ │ │ "multiplatform": false, │
│ │ │ "java": true │
│ │ │ }, │
│ │ │ "sourceSets": { │
│ │ │ "sourceSetToFiles": { │
│ │ │ "kotlin-main": [ │
│ │ │ "/Users/samedwards/src/kmp-readiness/samples/multiplatform_kmp4free/src/commonMain/kotlin/kmp4free/samples/MultiplatformCommonMain.kt" │
│ │ │ ], │
│ │ │ "java-main": [ │
│ │ │ ] │
│ │ │ } │
│ │ │ } │
│ │ │ } │
└─────────────────────────────────┴───────────────────────────────────────────────────────────────────────────────────────────────────────────┴────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘