Skip to content

Commit

Permalink
Fix Multiple Plugin Compatibility (#106)
Browse files Browse the repository at this point in the history
  • Loading branch information
tylerbwong authored Oct 20, 2024
1 parent 9ef7d19 commit abbed28
Show file tree
Hide file tree
Showing 20 changed files with 139 additions and 68 deletions.
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
android.useAndroidX=true
kotlin.code.style=official
kotlin.js.compiler=ir
kotlin.mpp.androidGradlePluginCompatibility.nowarn=true
kotlin.mpp.stability.nowarn=true
kotlin.native.ignoreDisabledTargets=true
org.gradle.configureondemand=false
Expand Down
8 changes: 4 additions & 4 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
[versions]
androidGradle = "8.5.1"
androidx-compose-runtime = "1.6.8"
androidGradle = "8.7.0"
androidx-compose-runtime = "1.7.3"
junit = "5.11.1"
kotlin = "2.0.0"
kotlin = "2.0.20"
ktlintGradle = "12.1.1"
pluginPublish = "1.2.1"
pluginPublish = "1.3.0"
metalavaGradle = "0.3.5"

[plugins]
Expand Down
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
Expand Down
49 changes: 35 additions & 14 deletions plugin/src/main/kotlin/me/tylerbwong/gradle/metalava/Module.kt
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
import org.jetbrains.kotlin.gradle.dsl.KotlinProjectExtension
import org.jetbrains.kotlin.gradle.dsl.KotlinSingleTargetExtension
import org.jetbrains.kotlin.gradle.plugin.KotlinTarget
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.targets
import java.io.File
import java.util.Locale

Expand Down Expand Up @@ -158,25 +157,47 @@ internal sealed class Module {
}
}

class Composite(private val modules: List<Module>) : Module() {
override val bootClasspath: Collection<File>
get() = modules.flatMap { it.bootClasspath }

override fun compileClasspath(project: Project, variant: String?): FileCollection {
return modules
.map { it.compileClasspath(project, variant) }
.reduce(FileCollection::plus)
.filter { it.exists() }
}

override fun sourceSets(project: Project, variant: String?): FileCollection {
return modules
.map { it.sourceSets(project, variant) }
.reduce(FileCollection::plus)
}

internal inline fun <reified T : Module> extract(): T? = modules.firstOrNull {
it is T
} as? T
}

companion object {
internal val Project.module: Module?
get() {
// Use findByName to avoid requiring consumers to have the Android Gradle plugin
// in their classpath when applying this plugin to a non-Android project
val libraryExtension = extensions.findByName("android")
val kotlinExtension = extensions.findByName("kotlin")
val androidModule = extensions.findByName("android")
?.takeIf { it is LibraryExtension }
?.let { Android(it as LibraryExtension) }

val javaPluginExtension = extensions.findByType<JavaPluginExtension>()
return when {
libraryExtension != null && libraryExtension is LibraryExtension -> Android(
libraryExtension,
)
kotlinExtension != null && javaPluginExtension != null && kotlinExtension is KotlinProjectExtension -> Kotlin(
javaPluginExtension,
kotlinExtension,
)
javaPluginExtension != null -> Java(javaPluginExtension)
else -> null
}

val kotlinModule = extensions.findByName("kotlin")
?.takeIf { it is KotlinProjectExtension && javaPluginExtension != null }
?.let { Kotlin(javaPluginExtension!!, it as KotlinProjectExtension) }

val javaModule = javaPluginExtension?.let { Java(it) }

val modules = listOfNotNull(androidModule, kotlinModule, javaModule)
return modules.takeIf { it.isNotEmpty() }?.let { Composite(it) }
}

internal fun File.checkDirectory(validExtensions: Collection<String>): Boolean {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,10 @@ internal class MetalavaPlugin : Plugin<Project> {
afterEvaluate {
val currentModule = module
if (currentModule != null) {
if (currentModule is Module.Android) {
currentModule.libraryVariants.forEach {
val androidModule = (currentModule as? Module.Composite)
?.extract<Module.Android>()
if (androidModule != null) {
androidModule.libraryVariants.forEach {
createMetalavaTasks(this, extension, currentModule, it)
}
} else {
Expand Down
38 changes: 22 additions & 16 deletions samples/kotlin-multiplatform/api/kotlin-multiplatform-api.txt
Original file line number Diff line number Diff line change
@@ -1,28 +1,34 @@
// Signature format: 4.0
package me.tylerbwong.gradle.metalava.sample {

public interface SamplePublicApi {
method public String getPublicApiProperty();
method public void publicApiFunction();
property public abstract String publicApiProperty;
public interface Platform {
method public String getPlatform();
property public abstract String platform;
}

public interface SamplePublicApi {
method public String getPublicApiProperty();
method public void publicApiFunction();
property public abstract String publicApiProperty;
public final class SampleAndroidPublicApiKt {
method public static me.tylerbwong.gradle.metalava.sample.Platform getPlatform();
property public static final me.tylerbwong.gradle.metalava.sample.Platform platform;
}

public interface SamplePublicApi {
method public String getPublicApiProperty();
method public void publicApiFunction();
property public abstract String publicApiProperty;
public final class SampleIosPublicApiKt {
method public static me.tylerbwong.gradle.metalava.sample.Platform getPlatform();
property public static final me.tylerbwong.gradle.metalava.sample.Platform platform;
}

public interface SamplePublicApi {
method public String getPublicApiProperty();
method public void publicApiFunction();
property public abstract String publicApiProperty;
public final class SampleJsPublicApiKt {
method public static me.tylerbwong.gradle.metalava.sample.Platform getPlatform();
property public static final me.tylerbwong.gradle.metalava.sample.Platform platform;
}

public final class SampleJvmPublicApiKt {
method public static me.tylerbwong.gradle.metalava.sample.Platform getPlatform();
property public static final me.tylerbwong.gradle.metalava.sample.Platform platform;
}

public final class SampleLinuxPublicApiKt {
method public static me.tylerbwong.gradle.metalava.sample.Platform getPlatform();
property public static final me.tylerbwong.gradle.metalava.sample.Platform platform;
}

}
Expand Down
23 changes: 23 additions & 0 deletions samples/kotlin-multiplatform/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
plugins {
kotlin("multiplatform")
id("com.android.library")
id("me.tylerbwong.gradle.metalava")
}

kotlin {
androidTarget()
iosX64()
iosArm64()
iosSimulatorArm64()
Expand All @@ -14,6 +16,27 @@ kotlin {
linuxX64()
}

android {
namespace = "me.tylerbwong.gradle.metalava.sample"
compileSdk = 34

sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml")
sourceSets["main"].res.srcDirs("src/androidMain/res")
sourceSets["main"].resources.srcDirs("src/commonMain/resources")

defaultConfig {
minSdk = 21
}

compileOptions {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
kotlin {
jvmToolchain(17)
}
}

metalava {
filename.set("api/$name-api.txt")
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest />
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package me.tylerbwong.gradle.metalava.sample

internal class SampleAndroidInternalApi {
val internalApiProperty: String = ""
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package me.tylerbwong.gradle.metalava.sample

internal class AndroidPlatform : Platform {
override val platform: String = "Android"
}

actual val platform: Platform = AndroidPlatform()
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package me.tylerbwong.gradle.metalava.sample

interface Platform {
val platform: String
}

expect val platform: Platform

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package me.tylerbwong.gradle.metalava.sample

internal class IosPlatform : Platform {
override val platform: String = "iOS"
}

actual val platform: Platform = IosPlatform()

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package me.tylerbwong.gradle.metalava.sample

internal class JsPlatform : Platform {
override val platform: String = "JS"
}

actual val platform: Platform = JsPlatform()

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package me.tylerbwong.gradle.metalava.sample

internal class JvmPlatform : Platform {
override val platform: String = "JVM"
}

actual val platform: Platform = JvmPlatform()

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package me.tylerbwong.gradle.metalava.sample

internal class LinuxPlatform : Platform {
override val platform: String = "Linux"
}

actual val platform: Platform = LinuxPlatform()

This file was deleted.

0 comments on commit abbed28

Please sign in to comment.