Skip to content

Commit

Permalink
Add some functions to aid with KMP (#35)
Browse files Browse the repository at this point in the history
  • Loading branch information
eygraber authored Sep 5, 2022
1 parent 8fc65e7 commit 633e693
Show file tree
Hide file tree
Showing 7 changed files with 224 additions and 26 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.eygraber.gradle.publishing

import org.gradle.api.Action
import org.gradle.api.Project
import org.gradle.api.artifacts.repositories.ArtifactRepository
import org.gradle.api.publish.PublishingExtension
import org.gradle.api.publish.plugins.PublishingPlugin
import org.gradle.kotlin.dsl.getByType

public fun Project.configurePublishingRepositories(action: Action<ArtifactRepository>) {
plugins.whenPluginAdded {
if(this::class.java == PublishingPlugin::class.java) {
extensions.getByType<PublishingExtension>().repositories.configureEach(action)
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.eygraber.gradle.detekt

import com.eygraber.gradle.kotlin.kmpSourceSets
import com.eygraber.gradle.kotlin.kmp.kmpSourceSets
import org.gradle.api.Project
import org.jetbrains.kotlin.gradle.plugin.KotlinMultiplatformPluginWrapper

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.eygraber.gradle.detekt

import com.eygraber.gradle.kotlin.kmpSourceSets
import com.eygraber.gradle.kotlin.kmp.kmpSourceSets
import com.eygraber.gradle.tasks.dependsOn
import io.gitlab.arturbosch.detekt.Detekt
import io.gitlab.arturbosch.detekt.extensions.DetektExtension
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.eygraber.gradle.kotlin.kmp

import org.gradle.api.Project
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension

/**
* [Fixed in Kotlin 1.7.20](https://youtrack.jetbrains.com/issue/KT-48436)
*/
public fun Project.removeUnusedKmpAndroidSourceSets() {
afterEvaluate {
extensions.findByType(KotlinMultiplatformExtension::class.java)?.let { kmpExt ->
kmpExt.sourceSets.removeAll { sourceSet ->
sourceSet.name == "androidAndroidTestRelease" ||
sourceSet.name.startsWith("androidTestFixtures")
}
}
}
}

/**
* apply this hack for Android Studio because AGP and KGP aren't handling it correctly yet
*
* [Kotlin Slack](https://kotlinlang.slack.com/archives/C3PQML5NU/p1652777328313809)
*
* [Issue Tracker](https://issuetracker.google.com/issues/231701341)
*/
public fun KotlinMultiplatformExtension.androidStudioHackForCommonMain() {
sourceSets.configureEach {
if(name == "androidMain") {
kotlin.srcDir("src/commonMain/kotlin")
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
package com.eygraber.gradle.kotlin.kmp

import com.eygraber.gradle.publishing.configurePublishingRepositories
import com.eygraber.gradle.tasks.dependsOn
import org.gradle.api.NamedDomainObjectContainer
import org.gradle.api.NamedDomainObjectProvider
import org.gradle.api.Project
import org.gradle.kotlin.dsl.named
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
import org.jetbrains.kotlin.gradle.plugin.KotlinTarget
import java.util.Locale

public val Project.kmpSourceSets: NamedDomainObjectContainer<KotlinSourceSet>
get() = extensions.getByType(KotlinMultiplatformExtension::class.java).sourceSets

public fun KotlinTarget.mainAndTestSourceSets(): Pair<KotlinSourceSet, KotlinSourceSet> =
compilations.getByName(KotlinCompilation.MAIN_COMPILATION_NAME).defaultSourceSet to
compilations.getByName(KotlinCompilation.TEST_COMPILATION_NAME).defaultSourceSet

public fun KotlinMultiplatformExtension.createSharedSourceSet(
project: Project,
name: String
) {
with(sourceSets) {
create("${name}Main") {
dependsOn(getByName("commonMain"))
}

create("${name}Test") {
dependsOn(getByName("commonTest"))
}
}

val sourceSetNameForTasks = name.capitalize(Locale.US)

project.configurePublishingRepositories {
val repoNameForTasks = name.capitalize(Locale.US)
project.tasks.register("publish${sourceSetNameForTasks}PublicationTo${repoNameForTasks}Repository")
}
}

public fun <T : KotlinTarget> KotlinMultiplatformExtension.createNestedSharedSourceSetForTargets(
project: Project,
name: String,
targets: List<T>,
parentSourceSetName: String,
createIntermediatePublishingTasks: Boolean = true,
configureTarget: (T) -> Unit
) {
val (nestedMainSourceSet, nestedTestSourceSet) = with(sourceSets) {
val main = create("${name}Main") {
dependsOn(getByName("${parentSourceSetName}Main"))
}

val test = create("${name}Test") {
dependsOn(getByName("${parentSourceSetName}Test"))
}

main to test
}

val nameForTasks = name.capitalize(Locale.US)
val parentSourceSetNameForTasks = parentSourceSetName.capitalize(Locale.US)

if(createIntermediatePublishingTasks) {
project.configurePublishingRepositories {
val repoNameForTasks = name.capitalize(Locale.US)
val publishTask = project.tasks.register(
"publish${nameForTasks}PublicationTo${repoNameForTasks}Repository"
)

project.tasks.named(
"publish${parentSourceSetNameForTasks}PublicationTo${repoNameForTasks}Repository"
).dependsOn(publishTask.name)
}
}

targets.forEach { target ->
configureTarget(target)

val targetNameForTasks = name.capitalize(Locale.US)

val (targetMainSourceSet, targetTestSourceSet) = target.mainAndTestSourceSets()
targetMainSourceSet.dependsOn(nestedMainSourceSet)
targetTestSourceSet.dependsOn(nestedTestSourceSet)

if(createIntermediatePublishingTasks) {
project.configurePublishingRepositories {
val repoNameForTasks = name.capitalize(Locale.US)

project.tasks.named(
"publish${nameForTasks}PublicationTo${repoNameForTasks}Repository"
).dependsOn(
"publish${targetNameForTasks}PublicationTo${repoNameForTasks}Repository"
)
}
}
}
}

/**
* Provides the existing [androidMain][KotlinSourceSet] element.
*/
public val NamedDomainObjectContainer<KotlinSourceSet>.androidMain: NamedDomainObjectProvider<KotlinSourceSet>
get() = named<KotlinSourceSet>("androidMain")

/**
* Provides the existing [androidTest][KotlinSourceSet] element.
*/
public val NamedDomainObjectContainer<KotlinSourceSet>.androidTest: NamedDomainObjectProvider<KotlinSourceSet>
get() = named<KotlinSourceSet>("androidTest")

/**
* Provides the existing [appleMain][KotlinSourceSet] element.
*/
public val NamedDomainObjectContainer<KotlinSourceSet>.appleMain: NamedDomainObjectProvider<KotlinSourceSet>
get() = named<KotlinSourceSet>("appleMain")

/**
* Provides the existing [appleTest][KotlinSourceSet] element.
*/
public val NamedDomainObjectContainer<KotlinSourceSet>.appleTest: NamedDomainObjectProvider<KotlinSourceSet>
get() = named<KotlinSourceSet>("appleTest")

/**
* Provides the existing [iosMain][KotlinSourceSet] element.
*/
public val NamedDomainObjectContainer<KotlinSourceSet>.iosMain: NamedDomainObjectProvider<KotlinSourceSet>
get() = named<KotlinSourceSet>("iosMain")

/**
* Provides the existing [iosTest][KotlinSourceSet] element.
*/
public val NamedDomainObjectContainer<KotlinSourceSet>.iosTest: NamedDomainObjectProvider<KotlinSourceSet>
get() = named<KotlinSourceSet>("iosTest")

/**
* Provides the existing [macosMain][KotlinSourceSet] element.
*/
public val NamedDomainObjectContainer<KotlinSourceSet>.macosMain: NamedDomainObjectProvider<KotlinSourceSet>
get() = named<KotlinSourceSet>("macosMain")

/**
* Provides the existing [macosTest][KotlinSourceSet] element.
*/
public val NamedDomainObjectContainer<KotlinSourceSet>.macosTest: NamedDomainObjectProvider<KotlinSourceSet>
get() = named<KotlinSourceSet>("macosTest")

/**
* Provides the existing [jsMain][KotlinSourceSet] element.
*/
public val NamedDomainObjectContainer<KotlinSourceSet>.jsMain: NamedDomainObjectProvider<KotlinSourceSet>
get() = named<KotlinSourceSet>("jsMain")

/**
* Provides the existing [jsTest][KotlinSourceSet] element.
*/
public val NamedDomainObjectContainer<KotlinSourceSet>.jsTest: NamedDomainObjectProvider<KotlinSourceSet>
get() = named<KotlinSourceSet>("jsTest")

/**
* Provides the existing [jvmMain][KotlinSourceSet] element.
*/
public val NamedDomainObjectContainer<KotlinSourceSet>.jvmMain: NamedDomainObjectProvider<KotlinSourceSet>
get() = named<KotlinSourceSet>("jvmMain")

/**
* Provides the existing [jvmTest][KotlinSourceSet] element.
*/
public val NamedDomainObjectContainer<KotlinSourceSet>.jvmTest: NamedDomainObjectProvider<KotlinSourceSet>
get() = named<KotlinSourceSet>("jvmTest")

This file was deleted.

0 comments on commit 633e693

Please sign in to comment.