Make a task to count dex methods in kotlin-stdlib and kotlin-reflect
This commit is contained in:
@@ -32,11 +32,13 @@ repositories {
|
||||
extra["buildSrcKotlinRepo"]?.let {
|
||||
maven { setUrl(it) }
|
||||
}
|
||||
maven(url = "https://dl.bintray.com/kotlin/kotlin-dev") // for dex-method-list
|
||||
// maven { setUrl("https://repo.gradle.org/gradle/libs-releases-local") }
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile(files("../dependencies/native-platform-uberjar.jar"))
|
||||
compile("com.jakewharton.dex:dex-method-list:2.0.0-alpha")
|
||||
// compile("net.rubygrapefruit:native-platform:0.14")
|
||||
// TODO: adding the dep to the plugin breaks the build unexpectedly, resolve and uncomment
|
||||
// compile("org.jetbrains.kotlin:kotlin-gradle-plugin:${rootProject.extra["bootstrap_kotlin_version"]}")
|
||||
|
||||
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
* Copyright 2010-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import com.jakewharton.dex.*
|
||||
import org.gradle.api.DefaultTask
|
||||
import org.gradle.api.tasks.*
|
||||
import org.gradle.jvm.tasks.Jar
|
||||
import java.io.File
|
||||
|
||||
open class DexMethodCount : DefaultTask() {
|
||||
|
||||
data class Counts(
|
||||
val total: Int,
|
||||
val totalOwnPackages: Int?,
|
||||
val totalOtherPackages: Int?,
|
||||
val byPackage: Map<String, Int>,
|
||||
val byClass: Map<String, Int>
|
||||
)
|
||||
|
||||
@InputFile
|
||||
lateinit var jarFile: File
|
||||
|
||||
@Input
|
||||
@Optional
|
||||
var ownPackages: List<String>? = null
|
||||
|
||||
// ##teamcity[buildStatisticValue key='DexMethodCount_${artifactOrArchiveName}' value='62362']
|
||||
@Input
|
||||
@Optional
|
||||
var teamCityStatistics: Boolean? = null
|
||||
|
||||
@Input
|
||||
@Optional
|
||||
var artifactName: String? = null
|
||||
|
||||
private val artifactOrArchiveName get() = artifactName ?: project.name
|
||||
|
||||
fun from(jar: Jar) {
|
||||
jarFile = jar.archivePath
|
||||
artifactName = jar.baseName
|
||||
dependsOn(jar)
|
||||
}
|
||||
|
||||
lateinit var counts: Counts
|
||||
|
||||
@TaskAction
|
||||
fun invoke() {
|
||||
val methods = DexMethods.list(jarFile)
|
||||
|
||||
val counts = methods.getCounts().also { this.counts = it }
|
||||
|
||||
printTotals(counts)
|
||||
printTCStats(counts)
|
||||
outputDetails(counts)
|
||||
}
|
||||
|
||||
private fun List<DexMethod>.getCounts(): Counts {
|
||||
val byPackage = this.groupingBy { it.`package` }.eachCount()
|
||||
val byClass = this.groupingBy { it.declaringType }.eachCount()
|
||||
|
||||
val ownPackages = ownPackages?.map { it + '.' }
|
||||
val byOwnPackages = if (ownPackages != null) {
|
||||
this.partition { method -> ownPackages.any { method.declaringType.startsWith(it) }}.let {
|
||||
it.first.size to it.second.size
|
||||
}
|
||||
} else (null to null)
|
||||
|
||||
return Counts(total = this.size,
|
||||
totalOwnPackages = byOwnPackages.first,
|
||||
totalOtherPackages = byOwnPackages.second,
|
||||
byPackage = byPackage,
|
||||
byClass = byClass)
|
||||
}
|
||||
|
||||
private fun printTotals(counts: Counts) {
|
||||
logger.lifecycle("Artifact $artifactOrArchiveName, total methods: ${counts.total}")
|
||||
ownPackages?.let { packages ->
|
||||
logger.lifecycle("Artifact $artifactOrArchiveName, total methods from packages ${packages.joinToString { "$it.*" }}: ${counts.totalOwnPackages}")
|
||||
logger.lifecycle("Artifact $artifactOrArchiveName, total methods from other packages: ${counts.totalOtherPackages}")
|
||||
}
|
||||
}
|
||||
|
||||
private fun printTCStats(counts: Counts) {
|
||||
if (teamCityStatistics ?: project.hasProperty("teamcity")) {
|
||||
println("##teamcity[buildStatisticValue key='DexMethodCount_${artifactOrArchiveName}' value='${counts.total}']")
|
||||
counts.totalOwnPackages?.let { value ->
|
||||
println("##teamcity[buildStatisticValue key='DexMethodCount_${artifactOrArchiveName}_OwnPackages' value='$value']")
|
||||
}
|
||||
counts.totalOtherPackages?.let { value ->
|
||||
println("##teamcity[buildStatisticValue key='DexMethodCount_${artifactOrArchiveName}_OtherPackages' value='$value']")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun outputDetails(counts: Counts) {
|
||||
val detailFile = project.buildDir.resolve("$artifactOrArchiveName-method-count.txt")
|
||||
detailFile.printWriter().use { writer ->
|
||||
writer.println("${counts.total.padRight()}\tTotal methods")
|
||||
ownPackages?.let { packages ->
|
||||
writer.println("${counts.totalOwnPackages?.padRight()}\tTotal methods from packages ${packages.joinToString { "$it.*" }}")
|
||||
writer.println("${counts.totalOtherPackages?.padRight()}\tTotal methods from other packages")
|
||||
}
|
||||
writer.println()
|
||||
writer.println("Method count by package:")
|
||||
counts.byPackage.forEach { (name, count) ->
|
||||
writer.println("${count.padRight()}\t$name")
|
||||
}
|
||||
writer.println()
|
||||
writer.println("Method count by class:")
|
||||
counts.byClass.forEach { (name, count) ->
|
||||
writer.println("${count.padRight()}\t$name")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
private val DexMethod.`package`: String get() = declaringType.substringBeforeLast('.')
|
||||
private fun Int.padRight() = toString().padStart(5, ' ')
|
||||
@@ -109,6 +109,12 @@ dist {
|
||||
}
|
||||
}
|
||||
|
||||
task dexMethodCount(type: DexMethodCount) {
|
||||
from jar
|
||||
ownPackages = ['kotlin']
|
||||
}
|
||||
assemble.dependsOn(dexMethodCount)
|
||||
|
||||
compileBuiltinsKotlin {
|
||||
dependsOn ":core:builtins:serialize"
|
||||
kotlinOptions {
|
||||
|
||||
@@ -170,6 +170,13 @@ task relocatedSourcesJar(type: Jar) {
|
||||
|
||||
def artifactJar = [file: file(outputJarPath), builtBy: proguard, name: archivesBaseName]
|
||||
|
||||
task dexMethodCount(type: DexMethodCount) {
|
||||
dependsOn(artifactJar.builtBy)
|
||||
jarFile = artifactJar.file
|
||||
ownPackages = ['kotlin.reflect']
|
||||
}
|
||||
assemble.dependsOn(dexMethodCount)
|
||||
|
||||
artifacts {
|
||||
mainJar artifactJar
|
||||
runtime artifactJar
|
||||
|
||||
Reference in New Issue
Block a user