Skip to content

Commit

Permalink
Merge pull request #110 from mr3y-the-programmer/multiplatform_support
Browse files Browse the repository at this point in the history
Support KMP & Jetbrains compose multiplatform
  • Loading branch information
PatilShreyas committed Jun 20, 2024
2 parents cc97864 + 48af55a commit df6f61e
Show file tree
Hide file tree
Showing 7 changed files with 159 additions and 25 deletions.
6 changes: 1 addition & 5 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,6 @@ plugins {
group = GROUP
version = VERSION_NAME

repositories {
mavenCentral()
}

tasks.withType<KotlinCompile> {
kotlinOptions.jvmTarget = "1.8"
}
Expand All @@ -32,4 +28,4 @@ subprojects {
licenseHeaderFile(rootProject.file("spotless/copyright.kt"))
}
}
}
}
8 changes: 1 addition & 7 deletions gradle-plugin/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,6 @@ plugins {
alias(libs.plugins.gradle.plugin.publish)
}

repositories {
mavenCentral()
google()
gradlePluginPortal()
maven(url = "https://plugins.gradle.org/m2/")
}

group = GROUP
version = VERSION_NAME

Expand All @@ -24,6 +17,7 @@ dependencies {
compileOnly(kotlin("stdlib"))
compileOnly(libs.kotlin.gradle.plugin)
compileOnly(libs.android.gradle.plugin)
compileOnly(libs.compose.multiplatform.gradle.plugin)

implementation(project(":core"))
implementation(project(":report-generator"))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,31 +26,112 @@ package dev.shreyaspatil.composeCompilerMetricsGenerator.plugin
import com.android.build.api.dsl.CommonExtension
import com.android.build.api.variant.AndroidComponentsExtension
import dev.shreyaspatil.composeCompilerMetricsGenerator.plugin.task.executingComposeCompilerReportGenerationGradleTask
import dev.shreyaspatil.composeCompilerMetricsGenerator.plugin.task.registerComposeCompilerReportGenTaskForJvmProject
import dev.shreyaspatil.composeCompilerMetricsGenerator.plugin.task.registerComposeCompilerReportGenTaskForTarget
import dev.shreyaspatil.composeCompilerMetricsGenerator.plugin.task.registerComposeCompilerReportGenTaskForVariant
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.kotlin.dsl.getByType
import org.jetbrains.kotlin.gradle.dsl.KotlinAndroidProjectExtension
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptions
import org.jetbrains.kotlin.gradle.dsl.KotlinCommonToolOptions
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmProjectExtension
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension

@Suppress("UnstableApiUsage")
class ReportGenPlugin : Plugin<Project> {
override fun apply(target: Project) {
val reportExt = ComposeCompilerReportExtension.create(target)
var pluginApplied = false

val android =
runCatching {
target.extensions.getByType(AndroidComponentsExtension::class.java)
}.getOrElse { error("This plugin is only applicable for Android modules") }
with(target) {
pluginManager.withPlugin("org.jetbrains.compose") {
pluginApplied = true
pluginManager.withPlugin("org.jetbrains.kotlin.jvm") { // if kotlin jvm is applied
val jvm = extensions.getByType(KotlinJvmProjectExtension::class.java)
configureKotlinJvmComposeCompilerReports(jvm)
}
pluginManager.withPlugin("org.jetbrains.kotlin.multiplatform") { // if kotlin multiplatform is applied
val multiplatform = extensions.getByType(KotlinMultiplatformExtension::class.java)
configureKotlinMultiplatformComposeCompilerReports(multiplatform)
}
pluginManager.withPlugin("org.jetbrains.kotlin.android") { // if kotlin android is applied
val android = extensions.getByType(AndroidComponentsExtension::class.java)
configureKotlinAndroidComposeCompilerReports(android)
}
}
if (!pluginApplied) {
val android = extensions.getByType(AndroidComponentsExtension::class.java)
pluginManager.withPlugin("com.android.application") {
configureKotlinAndroidComposeCompilerReports(android)
}
pluginManager.withPlugin("com.android.library") {
configureKotlinAndroidComposeCompilerReports(android)
}
}
}
}

private fun Project.configureKotlinJvmComposeCompilerReports(jvmExt: KotlinJvmProjectExtension) {
// Create gradle tasks for generating report
registerComposeCompilerReportGenTaskForJvmProject()

afterEvaluate {
// When this method returns true it means gradle task for generating report is executing otherwise
// normal compilation task is executing.
val isFromReportGenGradleTask = executingComposeCompilerReportGenerationGradleTask()
if (isFromReportGenGradleTask) {
jvmExt.target {
compilations.filter { !it.name.endsWith("Test") }.forEach {
it.kotlinOptions {
configureKotlinOptionsForComposeCompilerReport(this@configureKotlinJvmComposeCompilerReports)
}
}
}
}
}
}

private fun Project.configureKotlinMultiplatformComposeCompilerReports(multiplatformExt: KotlinMultiplatformExtension) {
// Create gradle tasks for generating report
multiplatformExt.targets.configureEach {
if (this.name == "metadata") return@configureEach

if (this.name == "android") {
// register a task for each variant
val androidExt = extensions.getByType(AndroidComponentsExtension::class.java)
androidExt.onVariants { variant ->
registerComposeCompilerReportGenTaskForTarget(this, variant)
}
} else {
registerComposeCompilerReportGenTaskForTarget(this)
}
}

afterEvaluate {
// When this method returns true it means gradle task for generating report is executing otherwise
// normal compilation task is executing.
val isFromReportGenGradleTask = executingComposeCompilerReportGenerationGradleTask()
if (isFromReportGenGradleTask) {
multiplatformExt.targets.flatMap { it.compilations }
.filter { !it.name.endsWith("Test", ignoreCase = true) }
.forEach {
it.kotlinOptions {
configureKotlinOptionsForComposeCompilerReport(this@configureKotlinMultiplatformComposeCompilerReports)
}
}
}
}
}

val commonExtension = runCatching { target.extensions.getByType(CommonExtension::class.java) }.getOrNull()
private fun Project.configureKotlinAndroidComposeCompilerReports(androidExt: AndroidComponentsExtension<*, *, *>) {
val commonExtension = runCatching { extensions.getByType(CommonExtension::class.java) }.getOrNull()

android.onVariants { variant ->
androidExt.onVariants { variant ->
// Create gradle tasks for generating report
target.registerComposeCompilerReportGenTaskForVariant(variant)
registerComposeCompilerReportGenTaskForVariant(variant)
}

target.afterEvaluate {
afterEvaluate {
val isComposeEnabled = commonExtension?.buildFeatures?.compose

if (isComposeEnabled != true) {
Expand All @@ -59,7 +140,7 @@ class ReportGenPlugin : Plugin<Project> {

// When this method returns true it means gradle task for generating report is executing otherwise
// normal compilation task is executing.
val isFromReportGenGradleTask = target.executingComposeCompilerReportGenerationGradleTask()
val isFromReportGenGradleTask = executingComposeCompilerReportGenerationGradleTask()
if (isFromReportGenGradleTask) {
val kotlinAndroidExt = extensions.getByType<KotlinAndroidProjectExtension>()
kotlinAndroidExt.target {
Expand All @@ -74,7 +155,7 @@ class ReportGenPlugin : Plugin<Project> {
}
}

private fun KotlinJvmOptions.configureKotlinOptionsForComposeCompilerReport(project: Project) {
private fun KotlinCommonToolOptions.configureKotlinOptionsForComposeCompilerReport(project: Project) {
val reportExtension = project.extensions.getByType<ComposeCompilerReportExtension>()
val outputPath = reportExtension.composeRawMetricsOutputDirectory.absolutePath
if (reportExtension.enableReport.get()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ import org.gradle.api.tasks.PathSensitivity
import org.gradle.api.tasks.TaskAction
import org.gradle.api.tasks.TaskProvider
import org.gradle.tooling.GradleConnector
import org.jetbrains.kotlin.gradle.plugin.KotlinTarget
import java.io.File
import java.io.FileNotFoundException

Expand Down Expand Up @@ -156,9 +157,43 @@ abstract class ComposeCompilerReportGenerateTask : DefaultTask() {
}
}

fun Project.registerComposeCompilerReportGenTaskForTarget(
target: KotlinTarget,
variant: Variant? = null,
): TaskProvider<ComposeCompilerReportGenerateTask> {
val variantName = variant?.name?.let { it[0].toUpperCase() + it.substring(1) } ?: ""
val taskName = target.name + variantName + "ComposeCompilerHtmlReport"
val compileKotlinTaskName = compileKotlinTaskNameFromTarget(target, variantName)
val descSuffix =
buildString {
append("'${target.name}' target")
if (variant != null) {
append(" '${variant.name}' variant")
}
append(" in multiplatform project")
}
return registerComposeCompilerReportGenTask(taskName, compileKotlinTaskName, descSuffix)
}

fun Project.registerComposeCompilerReportGenTaskForJvmProject(): TaskProvider<ComposeCompilerReportGenerateTask> {
val taskName = "jvmComposeCompilerHtmlReport"
val compileKotlinTaskName = "compileKotlin"
val descSuffix = "'Jvm/Desktop' Project"
return registerComposeCompilerReportGenTask(taskName, compileKotlinTaskName, descSuffix)
}

fun Project.registerComposeCompilerReportGenTaskForVariant(variant: Variant): TaskProvider<ComposeCompilerReportGenerateTask> {
val taskName = variant.name + "ComposeCompilerHtmlReport"
val compileKotlinTaskName = compileKotlinTaskNameFromVariant(variant)
val descSuffix = "'${variant.name}' variant in android project"
return registerComposeCompilerReportGenTask(taskName, compileKotlinTaskName, descSuffix)
}

fun Project.registerComposeCompilerReportGenTask(
taskName: String,
compileKotlinTaskName: String,
descSuffix: String,
): TaskProvider<ComposeCompilerReportGenerateTask> {
val reportExtension = ComposeCompilerReportExtension.get(project)

return tasks.register(taskName, ComposeCompilerReportGenerateTask::class.java) {
Expand All @@ -173,7 +208,7 @@ fun Project.registerComposeCompilerReportGenTaskForVariant(variant: Variant): Ta
showOnlyUnstableComposables.set(reportExtension.showOnlyUnstableComposables)

group = "compose compiler report"
description = "Generate Compose Compiler Metrics and Report"
description = "Generate Compose Compiler Metrics and Report for $descSuffix"
}
}

Expand All @@ -192,3 +227,14 @@ fun compileKotlinTaskNameFromVariant(variant: Variant): String {
val variantName = variant.name.let { it[0].toUpperCase() + it.substring(1) }
return "compile${variantName}Kotlin"
}

/**
* Returns a task name for compile<BUILD_TYPE>Kotlin<TARGET> with [target]
*/
fun compileKotlinTaskNameFromTarget(
target: KotlinTarget,
variantName: String,
): String {
val targetName = target.name.let { it[0].toUpperCase() + it.substring(1) }
return "compile${variantName}Kotlin$targetName"
}
2 changes: 2 additions & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ coroutines = "1.8.1"
spotless = "6.25.0"
kotlinxHtml = "0.11.0"
kotlinxCli = "0.3.6"
compose = "1.6.10-rc03"
mavenPublish = "0.28.0"
androidGradlePlugin = "8.3.0"
gradlePluginPublish = "1.2.1"
Expand All @@ -16,6 +17,7 @@ kotlinx-html-jvm = { module = "org.jetbrains.kotlinx:kotlinx-html-jvm", version.
kotlinx-cli = { module = "org.jetbrains.kotlinx:kotlinx-cli", version.ref = "kotlinxCli" }
android-gradle-plugin = { module = "com.android.tools.build:gradle", version.ref = "androidGradlePlugin" }
kotlin-gradle-plugin = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "kotlin" }
compose-multiplatform-gradle-plugin = { module = "org.jetbrains.compose:compose-gradle-plugin", version.ref = "compose" }

[plugins]
spotless = { id = "com.diffplug.spotless", version.ref = "spotless" }
Expand Down
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
15 changes: 15 additions & 0 deletions settings.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,3 +1,18 @@
pluginManagement {
repositories {
mavenCentral()
google()
gradlePluginPortal()
maven(url = "https://plugins.gradle.org/m2/")
}
}

dependencyResolutionManagement {
repositories {
mavenCentral()
google()
}
}

rootProject.name = "compose-report-to-html"

Expand Down

0 comments on commit df6f61e

Please sign in to comment.