Skip to content

Commit

Permalink
Refactoring booster-task-analyser to support reporting API for perf…
Browse files Browse the repository at this point in the history
…ormance analysis
  • Loading branch information
johnsonlee authored and neighbWang committed Jun 11, 2022
1 parent 4498913 commit 684272a
Show file tree
Hide file tree
Showing 5 changed files with 112 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,27 @@ import com.android.build.gradle.api.BaseVariant
import com.didiglobal.booster.gradle.extension
import com.didiglobal.booster.kotlinx.file
import com.didiglobal.booster.task.analyser.Build
import com.didiglobal.booster.task.analyser.performance.reporting.PerformanceReports
import com.didiglobal.booster.task.analyser.performance.reporting.PerformanceReportsImpl
import com.didiglobal.booster.task.analyser.reference.reporting.ReferenceReports
import com.didiglobal.booster.task.analyser.reference.reporting.ReferenceReportsImpl
import com.didiglobal.booster.transform.artifacts
import groovy.lang.Closure
import org.gradle.api.Action
import org.gradle.api.DefaultTask
import org.gradle.api.reporting.Reporting
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.Internal
import org.gradle.api.tasks.TaskAction
import org.gradle.util.ClosureBackedAction
import java.io.File

/**
* Represents a task for performance analysing
*
* @author johnsonlee
*/
open class PerformanceAnalysisTask : DefaultTask() {
open class PerformanceAnalysisTask : DefaultTask(), Reporting<PerformanceReports> {

@get:Internal
lateinit var variant: BaseVariant
Expand All @@ -28,8 +36,39 @@ open class PerformanceAnalysisTask : DefaultTask() {
val variantName: String
get() = variant.name

@get:Internal
val _reports: PerformanceReports by lazy {
project.objects.newInstance(PerformanceReportsImpl::class.java, this)
}

override fun getReports(): PerformanceReports = _reports

override fun reports(closure: Closure<*>): PerformanceReports {
return reports(ClosureBackedAction(closure))
}

override fun reports(configureAction: Action<in PerformanceReports>): PerformanceReports {
configureAction.execute(_reports)
return _reports
}

@TaskAction
fun analyse() {
if ((!reports.html.isEnabled) && (!reports.dot.isEnabled) && (!reports.json.isEnabled)) {
logger.warn("""
Please enable reference analysis reports with following configuration:
tasks.withType(${PerformanceAnalysisTask::class.java.simpleName}) {
reports {
html.enabled = true
json.enabled = true
dot.enabled = true
}
}
""".trimIndent())
return
}

val classpath = supplier().let {
if (it.isDirectory) {
it.listFiles()?.toList() ?: emptyList()
Expand All @@ -42,9 +81,7 @@ open class PerformanceAnalysisTask : DefaultTask() {
}
}

val output = project.projectDir.file("build", "reports", Build.ARTIFACT, variant.dirName)

PerformanceAnalyser(variant.extension.bootClasspath, classpath, variant.artifacts, project.properties).analyse(output)
PerformanceAnalyser(variant.extension.bootClasspath, classpath, variant.artifacts, project.properties).analyse(reports.dot.destination.parentFile)
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,14 @@ import com.android.build.api.transform.QualifiedContent
import com.android.build.gradle.api.BaseVariant
import com.android.build.gradle.internal.pipeline.TransformManager
import com.android.build.gradle.internal.pipeline.TransformTask
import com.android.build.gradle.internal.tasks.factory.dependsOn
import com.didiglobal.booster.gradle.extension
import com.didiglobal.booster.gradle.project
import com.didiglobal.booster.task.analyser.configureReportConvention
import com.didiglobal.booster.task.spi.VariantProcessor
import com.google.auto.service.AutoService
import org.gradle.api.GradleException
import org.gradle.api.UnknownTaskException

/**
* @author johnsonlee
Expand All @@ -23,17 +26,28 @@ class PerformanceAnalysisVariantProcessor : VariantProcessor {
it.scopes.containsAll(TransformManager.SCOPE_FULL_PROJECT)
&& it.inputTypes.contains(QualifiedContent.DefaultContentType.CLASSES)
} ?: throw GradleException("No available transform")
val profiles = project.tasks.findByName("analyse") ?: project.tasks.create("analyse")
val profiles = try {
project.tasks.named(TASK_ANALYSE_PERFORMANCE)
} catch (e: UnknownTaskException) {
project.tasks.register(TASK_ANALYSE_PERFORMANCE) {
it.description = "Analyses performance issues for Android project"
it.group = "booster"
}
}

project.tasks.withType(TransformTask::class.java).find {
it.name.endsWith(variantName) && it.transform == transform
}?.let { transformTask ->
val profile = project.tasks.create("analyse${variantName}", PerformanceAnalysisTask::class.java) {
val profile = project.tasks.register("${TASK_ANALYSE_PERFORMANCE}${variantName}", PerformanceAnalysisTask::class.java) {
it.description = "Analyses performance issues for Android project"
it.group = "booster"
it.variant = variant
it.supplier = {
transformTask.outputs.files.single()
}
}.dependsOn(transformTask)
it.dependsOn(transformTask)
it.configureReportConvention("performance", variantName)
}
profiles.dependsOn(profile)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,4 +83,6 @@ internal val ANY_THREAD_ANNOTATIONS = arrayOf(
"androidx/annotation/AnyThread",
"android/support/annotation/AnyThread",
"android/annotation/AnyThread"
)
)

internal val TASK_ANALYSE_PERFORMANCE = "analysePerformance"
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.didiglobal.booster.task.analyser.performance.reporting

import org.gradle.api.reporting.CustomizableHtmlReport
import org.gradle.api.reporting.ReportContainer
import org.gradle.api.reporting.SingleFileReport
import org.gradle.api.tasks.Internal

interface PerformanceReports : ReportContainer<SingleFileReport> {

@get:Internal
val html: CustomizableHtmlReport

@get:Internal
val json: SingleFileReport

@get:Internal
val dot: SingleFileReport

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.didiglobal.booster.task.analyser.performance.reporting

import org.gradle.api.Task
import org.gradle.api.internal.CollectionCallbackActionDecorator
import org.gradle.api.reporting.CustomizableHtmlReport
import org.gradle.api.reporting.SingleFileReport
import org.gradle.api.reporting.internal.CustomizableHtmlReportImpl
import org.gradle.api.reporting.internal.TaskGeneratedSingleFileReport
import org.gradle.api.reporting.internal.TaskReportContainer
import javax.inject.Inject

open class PerformanceReportsImpl @Inject constructor(
task: Task,
callbackActionDecorator: CollectionCallbackActionDecorator
) : TaskReportContainer<SingleFileReport>(SingleFileReport::class.java, task, callbackActionDecorator), PerformanceReports {

init {
add(CustomizableHtmlReportImpl::class.java, "html", task)
add(TaskGeneratedSingleFileReport::class.java, "json", task)
add(TaskGeneratedSingleFileReport::class.java, "dot", task)
}

override val html: CustomizableHtmlReport
get() = withType(CustomizableHtmlReport::class.java).getByName("html")

override val json: SingleFileReport
get() = getByName("json")

override val dot: SingleFileReport
get() = getByName("dot")

}

0 comments on commit 684272a

Please sign in to comment.