Skip to content

Commit

Permalink
Use a specific version of runtime, instead of using Gradle's variant …
Browse files Browse the repository at this point in the history
…resolution.

Previously we added the KotlinVersion attribute to all configurations in the module where SKIE was applied to.
That unfortunately breaks transitive dependencies, when other modules would depend on it, as those wouldn't have the attribute.
This change no longer relies on the attribute and instead targets an artifact for the specific version directly.
  • Loading branch information
TadeasKriz committed Oct 29, 2023
1 parent febe2f6 commit 8eb3068
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 11 deletions.
Original file line number Diff line number Diff line change
@@ -1,11 +1,44 @@
package co.touchlab.skie.gradle

import org.gradle.api.Named
import org.gradle.api.artifacts.dsl.DependencyHandler
import org.gradle.api.attributes.Attribute
import org.gradle.api.attributes.AttributeDisambiguationRule
import org.gradle.api.attributes.MultipleCandidatesDetails
import org.gradle.api.logging.Logging

interface KotlinCompilerVersion : Named {
companion object {

val attribute = Attribute.of("co.touchlab.skie.kotlin.compiler.version", KotlinCompilerVersion::class.java)

fun registerIn(dependencies: DependencyHandler, currentKotlinVersion: String) {
dependencies.attributesSchema.attribute(attribute) {
disambiguationRules.add(DisambiguationRule::class.java) {
params(currentKotlinVersion)
}
}
}
}

class DisambiguationRule(
private val currentKotlinVersion: String,
): AttributeDisambiguationRule<KotlinCompilerVersion> {
override fun execute(details: MultipleCandidatesDetails<KotlinCompilerVersion>) {
val correctCandidate = details.candidateValues.lastOrNull {
it.name == currentKotlinVersion
}

if (correctCandidate != null) {
details.closestMatch(correctCandidate)
} else {
// This should've already been caught by SKIE Plugin Loader, but we'll let the user know just in case.
log.error("Could not find a Kotlin compiler version matching the current Kotlin version ($currentKotlinVersion)!")
}
}

companion object {
val log = Logging.getLogger("KotlinCompilerVersion.DisambiguationRule")
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ abstract class SkieLoaderPlugin : Plugin<Project> {
val gradleVersion = GradleVersion.current().version
logger.info("Resolving SKIE gradle plugin for Kotlin plugin version $kotlinVersion and Gradle version $gradleVersion")

KotlinCompilerVersion.registerIn(project.dependencies, kotlinVersion)
KotlinCompilerVersion.registerIn(buildscript.dependencies, kotlinVersion)
val skieGradleConfiguration = buildscript.configurations.detachedConfiguration(
buildscript.dependencies.create(BuildConfig.SKIE_GRADLE_PLUGIN),
).apply {
Expand Down
10 changes: 7 additions & 3 deletions SKIE/skie-gradle/plugin/gradle-plugin.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,9 @@ buildConfig {
buildConfigField("String", "KOTLIN_PLUGIN_VERSION", "")
buildConfigField("String", "KOTLIN_TOOLING_VERSION", "")
buildConfigField("String", "GRADLE_API_VERSION", "")
buildConfigField("String", "RUNTIME_DEPENDENCY", "")
buildConfigField("String", "RUNTIME_DEPENDENCY_GROUP", "")
buildConfigField("String", "RUNTIME_DEPENDENCY_NAME", "")
buildConfigField("String", "RUNTIME_DEPENDENCY_VERSION", "")
buildConfigField("String", "KOTLIN_PLUGIN_ID", "")
buildConfigField("String", "MIXPANEL_PROJECT_TOKEN", "")
}
Expand Down Expand Up @@ -78,8 +80,10 @@ multiDimensionTarget.configureSourceSet { sourceSet ->
buildConfigField("String", "KOTLIN_TOOLING_VERSION", sourceSet.kotlinToolingVersion.value.enquoted())
buildConfigField("String", "GRADLE_API_VERSION", sourceSet.gradleApiVersion.value.enquoted())

val runtime = project.provider { projects.runtime.runtimeKotlin.dependencyProject.dependencyName }
buildConfigField("String", "RUNTIME_DEPENDENCY", runtime.map { it.enquoted() })
val runtime = project.provider { projects.runtime.runtimeKotlin.dependencyProject }
buildConfigField("String", "RUNTIME_DEPENDENCY_GROUP", runtime.map { it.group.toString().enquoted() })
buildConfigField("String", "RUNTIME_DEPENDENCY_NAME", runtime.map { it.name.enquoted() })
buildConfigField("String", "RUNTIME_DEPENDENCY_VERSION", runtime.map { it.version.toString().enquoted() })

val pluginId: String by properties
buildConfigField("String", "KOTLIN_PLUGIN_ID", "\"$pluginId\"")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,52 @@ import co.touchlab.skie.plugin.util.named
import co.touchlab.skie.plugin.util.withType
import org.jetbrains.kotlin.gradle.plugin.mpp.AbstractNativeLibrary
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
import org.jetbrains.kotlin.konan.target.KonanTarget

internal fun KotlinNativeTarget.addDependencyOnSkieRuntime() {
if (!project.isCoroutinesInteropEnabled) {
return
}

project.configurations.configureEach {
attributes {
attribute(KotlinCompilerVersion.attribute, project.objects.named(BuildConfig.KOTLIN_TOOLING_VERSION))
}
}

compilations.named("main") {
defaultSourceSet.dependencies {
api(BuildConfig.RUNTIME_DEPENDENCY)
api(BuildConfig.RUNTIME_DEPENDENCY(konanTarget, BuildConfig.KOTLIN_TOOLING_VERSION))
}
}

binaries.withType<AbstractNativeLibrary>().configureEach {
export(BuildConfig.RUNTIME_DEPENDENCY)
export(BuildConfig.RUNTIME_DEPENDENCY(konanTarget, BuildConfig.KOTLIN_TOOLING_VERSION))
}
}

private fun BuildConfig.RUNTIME_DEPENDENCY(konanTarget: KonanTarget, kotlinVersion: String): String {
return "$RUNTIME_DEPENDENCY_GROUP:$RUNTIME_DEPENDENCY_NAME-${konanTarget.presetName}__kgp_${kotlinVersion}:$RUNTIME_DEPENDENCY_VERSION"
}

private val KonanTarget.presetName: String
get() = when (this) {
KonanTarget.IOS_ARM32 -> "iosArm32"
KonanTarget.IOS_ARM64 -> "iosArm64"
KonanTarget.IOS_X64 -> "iosX64"
KonanTarget.IOS_SIMULATOR_ARM64 -> "iosSimulatorArm64"

KonanTarget.MACOS_ARM64 -> "macosArm64"
KonanTarget.MACOS_X64 -> "macosX64"

KonanTarget.TVOS_ARM64 -> "tvosArm64"
KonanTarget.TVOS_SIMULATOR_ARM64 -> "tvosSimulatorArm64"
KonanTarget.TVOS_X64 -> "tvosX64"

KonanTarget.WATCHOS_ARM32 -> "watchosArm32"
KonanTarget.WATCHOS_ARM64 -> "watchosArm64"
KonanTarget.WATCHOS_DEVICE_ARM64 -> "watchosArm64"
KonanTarget.WATCHOS_X86 -> "watchosX86"
KonanTarget.WATCHOS_X64 -> "watchosX64"
KonanTarget.WATCHOS_SIMULATOR_ARM64 -> "watchosSimulatorArm64"

KonanTarget.ANDROID_ARM32, KonanTarget.ANDROID_ARM64, KonanTarget.ANDROID_X64, KonanTarget.ANDROID_X86, KonanTarget.LINUX_ARM32_HFP,
KonanTarget.LINUX_ARM64, KonanTarget.LINUX_MIPS32, KonanTarget.LINUX_MIPSEL32, KonanTarget.LINUX_X64, KonanTarget.MINGW_X64,
KonanTarget.MINGW_X86, KonanTarget.WASM32, is KonanTarget.ZEPHYR -> error(
"SKIE doesn't support these platforms, so it should never ask for the preset name of this target."
)
}

0 comments on commit 8eb3068

Please sign in to comment.