Skip to content

Commit

Permalink
Merge branch 'main' of github.com:PatilShreyas/compose-report-to-html
Browse files Browse the repository at this point in the history
  • Loading branch information
PatilShreyas committed Jul 28, 2024
2 parents 98b7da2 + 3bccc64 commit 70e838a
Show file tree
Hide file tree
Showing 18 changed files with 342 additions and 79 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"))
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -222,5 +222,5 @@ fun printHeader(header: String) =
)

object Constants {
const val VERSION = "v1.3.1"
const val VERSION = "v1.4.0"
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ import dev.shreyaspatil.composeCompilerMetricsGenerator.core.model.composables.C
*/
object ComposableReportParser : Parser<String, ComposablesReport> {
private val REGEX_COMPOSABLE_FUNCTION = "(?:(.*))fun (\\w*)".toRegex()
private val REGEX_COMPOSABLE_PARAMETERS = "(?:(stable|unstable|) (\\w*:\\s.*))".toRegex()
private val REGEX_COMPOSABLE_PARAMETERS = "(?:(stable|unstable|\\w+) (\\w*:\\s.*))".toRegex()

/**
* Parses all composable functions
Expand Down
File renamed without changes
Binary file added docs/images/gradle-plugin-example-kmp.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion docs/use/using-cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ Run the command to know the usage of CLI
!!! success "▶️Output"

```shell
Usage: Compose Compiler Report to HTML Generator ~ v1.3.1 options_list
Usage: Compose Compiler Report to HTML Generator ~ v1.4.0 options_list
Options:
--applicationName, -app -> Application name (To be displayed in the report) (always required) { String }
--inputDirectory, -i -> Input directory where composable report and metrics are available { String }
Expand Down
28 changes: 20 additions & 8 deletions docs/use/using-gradle-plugin.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ Using the Gradle Plugin, you can fully automate the process of generating the re
This Gradle plugin takes care of generating raw compose metrics and report from the Compose compiler and then
generates the beautified report from them.

**This plugin has support for Android projects and Kotlin Multiplatform projects.**

## ✅ Apply the plugin

Apply the plugin to the module in which _**compose is enabled**_.
Expand All @@ -19,15 +21,15 @@ Apply the plugin to the module in which _**compose is enabled**_.

```groovy title="build.gradle"
plugins {
id "dev.shreyaspatil.compose-compiler-report-generator" version "1.3.1"
id "dev.shreyaspatil.compose-compiler-report-generator" version "1.4.0"
}
```

=== "Kotlin"

```kotlin title="build.gradle.kts"
plugins {
id("dev.shreyaspatil.compose-compiler-report-generator") version "1.3.1"
id("dev.shreyaspatil.compose-compiler-report-generator") version "1.4.0"
}
```

Expand All @@ -45,7 +47,7 @@ Add this to top project level `build.gradle`
}
}
dependencies {
classpath "dev.shreyaspatil.compose-compiler-report-generator:gradle-plugin:1.3.1"
classpath "dev.shreyaspatil.compose-compiler-report-generator:gradle-plugin:1.4.0"
}
}
```
Expand All @@ -66,7 +68,7 @@ Add this to top project level `build.gradle`
}
}
dependencies {
classpath("dev.shreyaspatil.compose-compiler-report-generator:gradle-plugin:1.3.1")
classpath("dev.shreyaspatil.compose-compiler-report-generator:gradle-plugin:1.4.0")
}
}
```
Expand All @@ -79,12 +81,22 @@ Add this to top project level `build.gradle`

## 💫 Sync the project

Once plugin is applied, sync the project. After the project is synced, tasks for generating compose report will be
generated for the variants and flavors used in the project.
Once plugin is applied, sync the project. After the project is synced, tasks for generating compose
report will be generated for the variants and flavors used in the project.

!!! example

=== "Android Project"

![](../images/gradle-plugin-example-android.png){ height="150" }

=== "Multiplatform Project"
For Kotlin Multiplatform project, tasks will be generated for the platform modules
and build types.

![](../images/gradle-plugin-example-kmp.png){ height="120" }


![](../images/gradle-plugin-example.png){ height="150" }

## 🪄 Generate report

Expand Down Expand Up @@ -139,7 +151,7 @@ If you have to configure plugin parameters manually (which is completely optiona
}
```

=== "Kotlin"
=== "Kotlin (JVM / Android / Multiplatform)"

```kotlin title="build.gradle.kts"
htmlComposeCompilerReport {
Expand Down
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 @@ -23,73 +23,73 @@
*/
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.registerComposeCompilerReportGenTaskForVariant
import dev.shreyaspatil.composeCompilerMetricsGenerator.plugin.multiplatform.android.configureKotlinAndroidComposeCompilerReports
import dev.shreyaspatil.composeCompilerMetricsGenerator.plugin.multiplatform.configureKotlinMultiplatformComposeCompilerReports
import dev.shreyaspatil.composeCompilerMetricsGenerator.plugin.multiplatform.jvm.configureKotlinJvmComposeCompilerReports
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 isAppliedForKmp = false

val android =
runCatching {
target.extensions.getByType(AndroidComponentsExtension::class.java)
}.getOrElse { error("This plugin is only applicable for Android modules") }

val commonExtension = runCatching { target.extensions.getByType(CommonExtension::class.java) }.getOrNull()

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

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

if (isComposeEnabled != true) {
error("Jetpack Compose is not found enabled in this module '$name'")
with(target) {
pluginManager.withPlugin("org.jetbrains.compose") {
isAppliedForKmp = 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)
}
}

// When this method returns true it means gradle task for generating report is executing otherwise
// normal compilation task is executing.
val isFromReportGenGradleTask = target.executingComposeCompilerReportGenerationGradleTask()
if (isFromReportGenGradleTask) {
val kotlinAndroidExt = extensions.getByType<KotlinAndroidProjectExtension>()
kotlinAndroidExt.target {
// Exclude for test variants, no use!
compilations.filter { !it.name.endsWith("Test") }.forEach {
it.kotlinOptions {
configureKotlinOptionsForComposeCompilerReport(this@afterEvaluate)
}
}
var isAppliedForAndroid = false
if (!isAppliedForKmp) {
val android = extensions.getByType(AndroidComponentsExtension::class.java)
pluginManager.withPlugin("com.android.application") {
configureKotlinAndroidComposeCompilerReports(android)
isAppliedForAndroid = true
}
pluginManager.withPlugin("com.android.library") {
configureKotlinAndroidComposeCompilerReports(android)
isAppliedForAndroid = true
}
}
if (!isAppliedForAndroid && !isAppliedForKmp) {
error("Jetpack Compose is not found enabled in this module '$name'")
}
}
}
}

private fun KotlinJvmOptions.configureKotlinOptionsForComposeCompilerReport(project: Project) {
val reportExtension = project.extensions.getByType<ComposeCompilerReportExtension>()
val outputPath = reportExtension.composeRawMetricsOutputDirectory.absolutePath
if (reportExtension.enableReport.get()) {
freeCompilerArgs +=
listOf(
"-P",
"plugin:androidx.compose.compiler.plugins.kotlin:reportsDestination=$outputPath",
)
}
if (reportExtension.enableMetrics.get()) {
freeCompilerArgs +=
listOf(
"-P",
"plugin:androidx.compose.compiler.plugins.kotlin:metricsDestination=$outputPath",
)
}
fun KotlinCommonToolOptions.configureKotlinOptionsForComposeCompilerReport(project: Project) {
val reportExtension = project.extensions.getByType<ComposeCompilerReportExtension>()
val outputPath = reportExtension.composeRawMetricsOutputDirectory.absolutePath
if (reportExtension.enableReport.get()) {
freeCompilerArgs +=
listOf(
"-P",
"plugin:androidx.compose.compiler.plugins.kotlin:reportsDestination=$outputPath",
)
}
if (reportExtension.enableMetrics.get()) {
freeCompilerArgs +=
listOf(
"-P",
"plugin:androidx.compose.compiler.plugins.kotlin:metricsDestination=$outputPath",
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/**
* MIT License
*
* Copyright (c) 2022 Shreyas Patil
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
@file:Suppress("ktlint:standard:filename")

package dev.shreyaspatil.composeCompilerMetricsGenerator.plugin.multiplatform.android

import com.android.build.api.dsl.CommonExtension
import com.android.build.api.variant.AndroidComponentsExtension
import dev.shreyaspatil.composeCompilerMetricsGenerator.plugin.multiplatform.configureKotlinOptionsForComposeCompilerReport
import dev.shreyaspatil.composeCompilerMetricsGenerator.plugin.task.executingComposeCompilerReportGenerationGradleTask
import dev.shreyaspatil.composeCompilerMetricsGenerator.plugin.task.registerComposeCompilerReportGenTaskForVariant
import org.gradle.api.Project
import org.gradle.kotlin.dsl.getByType
import org.jetbrains.kotlin.gradle.dsl.KotlinAndroidProjectExtension

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

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

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

if (isComposeEnabled != true) {
error("Jetpack Compose is not found enabled in this module '$name'")
}

// 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) {
val kotlinAndroidExt = extensions.getByType<KotlinAndroidProjectExtension>()
kotlinAndroidExt.target {
// Exclude for test variants, no use!
configureKotlinOptionsForComposeCompilerReport(compilations)
}
}
}
}
Loading

0 comments on commit 70e838a

Please sign in to comment.