Skip to content

Commit

Permalink
[Issue-10] Support Single Targets and Native-Grouped Targets
Browse files Browse the repository at this point in the history
[Summary]
Some dependencies are only applicable to 1 target, and some apply to all
native targets (except WASM, which almost no one supports yet). It would
be nice to add in some target-specific dependencies, especially when
they relate closely to a shared dependency (Ktor and SQLDelight are
examples).

[Fix]
Create a "Single Target Libraries" and a "Native Target Libraries"
section. Single Target libraries are available as long as there is a
target selected that supports it. Native Target Libraries are available
as long as there is at least one native target it builds for (excluding
WASM).

[Testing]
- `./gradlew check`
- manual testing
  • Loading branch information
brady-aiello committed Dec 13, 2021
1 parent 16a6424 commit c5318ed
Show file tree
Hide file tree
Showing 11 changed files with 267 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ import org.jetbrains.webwiz.generator.deleteNans
import org.jetbrains.webwiz.models.GradlePlugin
import org.jetbrains.webwiz.models.KmpLibrary
import org.jetbrains.webwiz.models.ProjectInfo
import org.jetbrains.webwiz.models.SourceSetDelegate
import org.jetbrains.webwiz.models.SourceSetDelegate.CREATING
import org.jetbrains.webwiz.models.SourceSetDelegate.GETTING
import org.jetbrains.webwiz.models.SourceSetType.MAIN
import org.jetbrains.webwiz.models.Target
import org.jetbrains.webwiz.models.isNativeTargetPresent

Expand Down Expand Up @@ -84,7 +88,9 @@ kotlin {
""".trimMargin().deleteNans()

private fun commonMainSourceSet(): String {
val deps = projectInfo.dependencies.map { "implementation(\"${it.dep}\")" }
val deps = projectInfo.dependencies.filter {
it.sourceSetType.sourceSetTypeName == MAIN.sourceSetTypeName
}.map { "implementation(\"${it.dep}\")" }
return if (deps.isEmpty()) {
" | val commonMain by getting"
} else {
Expand All @@ -96,6 +102,25 @@ kotlin {
}
}

private fun singleSourceSet(
target: Target,
compilation: String,
sourceSetDelegate: SourceSetDelegate
): String {
val deps = projectInfo.singleTargetDependencies
.filter { it.target == target && it.sourceSetType.sourceSetTypeName == compilation }
.map { "implementation(\"${it.dep}\")" }
return if (deps.isEmpty()) {
"val ${target.targetName}$compilation by ${sourceSetDelegate.delegate}"
} else {
"""val ${target.targetName}$compilation by ${sourceSetDelegate.delegate} {
| dependencies {
| ${deps.joinToString("\n| ")}
| }
| }"""
}
}

private fun commonTestSourceSet() =
"""| val commonTest by getting {
| dependencies {
Expand All @@ -107,9 +132,9 @@ kotlin {
val intention = "\n| "
return projectInfo.targets.joinToString(intention) {
when (it) {
Target.ANDROID -> "val android$compilation by getting"
Target.JVM -> "val jvm$compilation by getting"
Target.JS -> "val js$compilation by getting"
Target.ANDROID -> singleSourceSet(Target.ANDROID, compilation, GETTING)
Target.JVM -> singleSourceSet(Target.JVM, compilation, GETTING)
Target.JS -> singleSourceSet(Target.JS, compilation, GETTING)
Target.WASM -> "val wasm32$compilation by getting"
Target.ANDROID_NATIVE -> "val androidNativeArm64$compilation by getting"
Target.LINUX -> "val linuxX64$compilation by getting"
Expand All @@ -132,7 +157,7 @@ kotlin {
Target.ANDROID_NATIVE -> "val androidNative$compilation by creating"
Target.LINUX -> "val linux$compilation by creating"
Target.MACOS -> "val macos$compilation by creating"
Target.IOS -> "val ios$compilation by creating"
Target.IOS -> singleSourceSet(Target.IOS, compilation, CREATING)
Target.TV_OS -> "val tvos$compilation by creating"
Target.WATCH_OS -> "val watchos$compilation by creating"
Target.WINDOWS -> "val windows$compilation by creating"
Expand All @@ -158,7 +183,27 @@ kotlin {
}
}

private fun nativeSourceSets(compilation: String) = "val native$compilation by creating"
private fun nativeUmbrellaSourceSet(
compilation: String,
sourceSetDelegate: SourceSetDelegate
): String {
val deps = projectInfo.nativeTargetLibraries
.filter { it.sourceSetType.sourceSetTypeName == compilation }
.map { "implementation(\"${it.dep}\")" }
return if (deps.isEmpty()) {
"val native$compilation by ${sourceSetDelegate.delegate}"
} else {
"""val native$compilation by ${sourceSetDelegate.delegate} {
| dependencies {
| ${deps.joinToString("\n| ")}
| }
| }"""
}
}

private fun nativeSourceSets(compilation: String): String {
return nativeUmbrellaSourceSet(compilation, CREATING)
}
private fun nativeSourceSetsDependencies(compilation: String) = "native$compilation.dependsOn(common$compilation)"

private fun generateAndroidPluginConfig(minSdk: String, compileSdk: String) = """
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,7 @@ enum class GradlePlugin(
),
SQL_DELIGHT(
emptySet(),
setOf(
Target.ANDROID_NATIVE,
Target.LINUX,
Target.WASM,
Target.TV_OS,
Target.WATCH_OS
),
setOf(Target.WASM),
"SQLDelight"
);

Expand Down
31 changes: 22 additions & 9 deletions src/commonMain/kotlin/org/jetbrains/webwiz/models/KmpLibraries.kt
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
package org.jetbrains.webwiz.models

import org.jetbrains.webwiz.models.SourceSetType.MAIN

enum class KmpLibrary(
val targets: Set<Target>?, //null means any target
val userName: String,
val dep: String
val dep: String,
val sourceSetType: SourceSetType
) {
COROUTINES(
setOf(
Expand All @@ -18,7 +21,8 @@ enum class KmpLibrary(
Target.WINDOWS
),
"KotlinX Coroutines",
"org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2"
"org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2",
MAIN
),
SERIALIZATION(
setOf(
Expand All @@ -33,7 +37,8 @@ enum class KmpLibrary(
Target.WINDOWS
),
"KotlinX Serialization",
"org.jetbrains.kotlinx:kotlinx-serialization-json:1.3.1"
"org.jetbrains.kotlinx:kotlinx-serialization-json:1.3.1",
MAIN
),
DATE_TIME(
setOf(
Expand All @@ -48,7 +53,8 @@ enum class KmpLibrary(
Target.WINDOWS
),
"KotlinX DateTime",
"org.jetbrains.kotlinx:kotlinx-datetime:0.3.1"
"org.jetbrains.kotlinx:kotlinx-datetime:0.3.1",
MAIN
),
KERMIT_LOGGER(
setOf(
Expand All @@ -63,7 +69,8 @@ enum class KmpLibrary(
Target.WINDOWS
),
"Kermit Logger",
"co.touchlab:kermit:1.0.0"
"co.touchlab:kermit:1.0.0",
MAIN
),
NAPIER_LOGGER(
setOf(
Expand All @@ -76,19 +83,24 @@ enum class KmpLibrary(
Target.WATCH_OS
),
"Napier logger",
"io.github.aakira:napier:2.1.0"
"io.github.aakira:napier:2.1.0",
MAIN
),
SQLDELIGHT_COROUTINES(
setOf(
Target.ANDROID,
Target.JVM,
Target.JS,
Target.IOS,
Target.LINUX,
Target.MACOS,
Target.WINDOWS
Target.WINDOWS,
Target.TV_OS,
Target.WATCH_OS
),
"SQLDelight Coroutines",
"com.squareup.sqldelight:coroutines-extensions:1.5.3"
"com.squareup.sqldelight:coroutines-extensions:1.5.3",
MAIN
),
KTOR_CORE(
setOf(
Expand All @@ -101,6 +113,7 @@ enum class KmpLibrary(
Target.WINDOWS
),
"Ktor Core",
"io.ktor:ktor-client-core:1.6.7"
"io.ktor:ktor-client-core:1.6.7",
MAIN
),
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package org.jetbrains.webwiz.models

import org.jetbrains.webwiz.models.SourceSetType.MAIN

// Dependencies in here will be available for all native targets
enum class NativeTargetLibrary(
val userName: String,
val dep: String,
val sourceSetType: SourceSetType
) {
SQLDELIGHT_DRIVER_NATIVE(
"SQDelight Native Driver",
"com.squareup.sqldelight:native-driver:1.5.3",
MAIN
),
}
11 changes: 10 additions & 1 deletion src/commonMain/kotlin/org/jetbrains/webwiz/models/ProjectInfo.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ data class ProjectInfo(
val kotlinVersion: KotlinVersion,
val targets: Set<Target>,
val dependencies: Set<KmpLibrary>,
val singleTargetDependencies: Set<SingleTargetLibrary>,
val nativeTargetLibraries: Set<NativeTargetLibrary>,
val gradlePlugins: Set<GradlePlugin>,
val enableTests: Boolean
) {
Expand All @@ -20,11 +22,18 @@ data class ProjectInfo(
require(dependencies.all { dep -> dep.targets == null || targets.all { dep.targets.contains(it) } }) {
"incorrect dependency was used for current set of targets"
}
require(singleTargetDependencies.all { dep -> dep.target in targets}) {
"incorrect dependency was used for current set of targets"
}
}

fun normalize() = copy(
moduleName = moduleName.replace(' ', '_'),
gradlePlugins = gradlePlugins.filter { it.canBeApplied(targets) }.toSet(),
dependencies = dependencies.filter { dep -> dep.targets == null || targets.all { dep.targets.contains(it) } }.toSet()
dependencies = dependencies
.filter { dep -> dep.targets == null || targets.all { dep.targets.contains(it) } }.toSet(),
singleTargetDependencies = singleTargetDependencies
.filter { dep -> dep.target in targets }.toSet(),
nativeTargetLibraries = if (this.targets.isNativeTargetPresent()) nativeTargetLibraries else emptySet()
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package org.jetbrains.webwiz.models

import org.jetbrains.webwiz.models.SourceSetType.MAIN

enum class SingleTargetLibrary(
val target: Target,
val userName: String,
val dep: String,
val sourceSetType: SourceSetType
) {
KTOR_CLIENT_IOS(
Target.IOS,
"Ktor iOS Client",
"io.ktor:ktor-client-ios:1.6.7",
MAIN
),
KTOR_CLIENT_OKHTTP(
Target.ANDROID,
"Ktor OkHttp Client",
"io.ktor:ktor-client-okhttp:1.6.7",
MAIN
),
KTOR_CLIENT_JVM(
Target.JVM,
"Ktor JVM Client",
"io.ktor:ktor-client-jvm:1.6.7",
MAIN
),
KTOR_CLIENT_JS(
Target.JS,
"Ktor JS Client",
"io.ktor:ktor-client-js:1.6.7",
MAIN
),
SQLDELIGHT_DRIVER_ANDROID(
Target.ANDROID,
"SQLDelight Android Driver",
"com.squareup.sqldelight:android-driver:1.5.3",
MAIN
),
SQLDELIGHT_DRIVER_JVM(
Target.JVM,
"SQLDelight JVM Driver",
"com.squareup.sqldelight:sqlite-driver:1.5.3",
MAIN
),
SQLDELIGHT_DRIVER_JS(
Target.JS,
"SQDelight JS Driver",
"com.squareup.sqldelight:sqljs-driver:1.5.3",
MAIN
),
}
11 changes: 11 additions & 0 deletions src/commonMain/kotlin/org/jetbrains/webwiz/models/SourceSetType.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package org.jetbrains.webwiz.models

enum class SourceSetType(val sourceSetTypeName: String) {
MAIN("Main"),
TEST("Test")
}

enum class SourceSetDelegate(val delegate: String) {
CREATING("creating"),
GETTING("getting")
}
10 changes: 10 additions & 0 deletions src/commonMain/kotlin/org/jetbrains/webwiz/models/Targets.kt
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,18 @@ private val NativeTargets = setOf(
Target.WINDOWS
)

private val CommonNativeTargets = setOf(
Target.LINUX,
Target.MACOS,
Target.IOS,
Target.TV_OS,
Target.WATCH_OS,
Target.WINDOWS
)

fun Target.isJvm() = this in setOf(Target.JVM, Target.ANDROID)

fun Set<Target>.isNativeTargetPresent() = this.any { it in NativeTargets }
fun Set<Target>.isCommonNativeTargetPresent() = this.any { it in CommonNativeTargets }
fun Set<Target>.isAndroidTargetPresent() = this.any { it == Target.ANDROID }
fun Set<Target>.isJvmTargetPresent() = this.any { it.isJvm() }
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ internal class ProjectBuilderTest {
KotlinVersion.Stable,
setOf(JVM, JS, IOS, ANDROID),
emptySet(),
emptySet(),
emptySet(),
setOf(GradlePlugin.PUBLISH),
true
)
Expand Down Expand Up @@ -62,6 +64,8 @@ internal class ProjectBuilderTest {
KotlinVersion.EAP,
setOf(JVM, JS, IOS, ANDROID),
setOf(KmpLibrary.SERIALIZATION),
emptySet(),
emptySet(),
setOf(GradlePlugin.PUBLISH),
true
)
Expand Down Expand Up @@ -164,6 +168,8 @@ internal class ProjectBuilderTest {
KotlinVersion.EAP,
setOf(JVM, JS, IOS, ANDROID),
setOf(KmpLibrary.SERIALIZATION),
emptySet(),
emptySet(),
setOf(GradlePlugin.PUBLISH),
true
)
Expand Down
Loading

0 comments on commit c5318ed

Please sign in to comment.