[Build] Fix configuration cache issues (part 6)

Make DexMethodCountStats task class, tasks :examples:kotlin-jsr223-daemon-local-eval-example:test,:idea:idea-fir:test, :idea:idea-fir-performance-tests:test, :idea:idea-frontend-fir:test, :idea:idea-frontend-fir:idea-fir-low-level-api:test, :kotlin-compiler-client-embeddable:test, :kotlin-compiler-embeddable:test, :kotlin-stdlib-js-ir:compileTestKotlinJs, :plugins:android-extensions-compiler:test, :plugins:parcelize:parcelize-compiler:test, :compiler:test compatible with configuration cache
Relates to #KT-44611
This commit is contained in:
Alexander Likhachev
2021-02-17 15:04:53 +03:00
parent 1751b5182b
commit 6bd44df861
14 changed files with 98 additions and 58 deletions
@@ -6,12 +6,15 @@
import com.jakewharton.dex.* import com.jakewharton.dex.*
import org.gradle.api.DefaultTask import org.gradle.api.DefaultTask
import org.gradle.api.Project import org.gradle.api.Project
import org.gradle.api.file.RegularFileProperty
import org.gradle.api.provider.ListProperty
import org.gradle.api.provider.Property
import org.gradle.api.tasks.* import org.gradle.api.tasks.*
import org.gradle.jvm.tasks.Jar import org.gradle.jvm.tasks.Jar
import java.io.File import java.io.File
@CacheableTask @CacheableTask
open class DexMethodCount : DefaultTask() { abstract class DexMethodCount : DefaultTask() {
data class Counts( data class Counts(
val total: Int, val total: Int,
@@ -24,16 +27,18 @@ open class DexMethodCount : DefaultTask() {
@Classpath @Classpath
lateinit var jarFile: File lateinit var jarFile: File
@Optional @get:Optional
@Input @get:Input
var ownPackages: List<String>? = null abstract val ownPackages: ListProperty<String>
@Internal @Internal
var artifactName: String? = null var artifactName: String? = null
private val projectName = project.name
@get:Input @get:Input
val artifactOrArchiveName: String val artifactOrArchiveName: String
get() = artifactName ?: project.name get() = artifactName ?: projectName
fun from(jar: Jar) { fun from(jar: Jar) {
jarFile = jar.archiveFile.get().asFile jarFile = jar.archiveFile.get().asFile
@@ -45,8 +50,9 @@ open class DexMethodCount : DefaultTask() {
lateinit var counts: Counts lateinit var counts: Counts
@get:OutputFile @get:OutputFile
val detailOutputFile: File val detailOutputFile: File by lazy {
get() = project.buildDir.resolve("$artifactOrArchiveName-method-count.txt") project.buildDir.resolve("$artifactOrArchiveName-method-count.txt")
}
@TaskAction @TaskAction
fun invoke() { fun invoke() {
@@ -59,9 +65,9 @@ open class DexMethodCount : DefaultTask() {
val byPackage = this.groupingBy { it.`package` }.eachCount() val byPackage = this.groupingBy { it.`package` }.eachCount()
val byClass = this.groupingBy { it.declaringType }.eachCount() val byClass = this.groupingBy { it.declaringType }.eachCount()
val ownPackages = ownPackages?.map { "$it." } val ownPackages = ownPackages.map { list -> list.map { "$it." } }
val byOwnPackages = if (ownPackages != null) { val byOwnPackages = if (ownPackages.isPresent) {
this.partition { method -> ownPackages.any { method.declaringType.startsWith(it) } }.let { this.partition { method -> ownPackages.get().any { method.declaringType.startsWith(it) } }.let {
it.first.size to it.second.size it.first.size to it.second.size
} }
} else (null to null) } else (null to null)
@@ -78,7 +84,7 @@ open class DexMethodCount : DefaultTask() {
private fun outputDetails(counts: Counts) { private fun outputDetails(counts: Counts) {
detailOutputFile.printWriter().use { writer -> detailOutputFile.printWriter().use { writer ->
writer.println("${counts.total.padRight()}\tTotal methods") writer.println("${counts.total.padRight()}\tTotal methods")
ownPackages?.let { packages -> ownPackages.orNull?.let { packages ->
writer.println("${counts.totalOwnPackages?.padRight()}\tTotal methods from packages ${packages.joinToString { "$it.*" }}") writer.println("${counts.totalOwnPackages?.padRight()}\tTotal methods from packages ${packages.joinToString { "$it.*" }}")
writer.println("${counts.totalOtherPackages?.padRight()}\tTotal methods from other packages") writer.println("${counts.totalOtherPackages?.padRight()}\tTotal methods from other packages")
} }
@@ -96,23 +102,24 @@ open class DexMethodCount : DefaultTask() {
} }
} }
open class DexMethodCountStats : DefaultTask() { abstract class DexMethodCountStats : DefaultTask() {
@Internal
lateinit var from: TaskProvider<DexMethodCount>
@get:InputFile @get:InputFile
internal val inputFile internal abstract val inputFile: RegularFileProperty
get() = from.get().detailOutputFile
@get:Input
internal abstract val artifactOrArchiveName: Property<String>
@get:Input
@get:Optional
internal abstract val ownPackages: ListProperty<String>
@TaskAction @TaskAction
private fun printStats() { private fun printStats() {
val artifactOrArchiveName = from.get().artifactOrArchiveName val artifactOrArchiveName = artifactOrArchiveName.get()
inputFile.reader().useLines { lines -> inputFile.get().asFile.reader().useLines { lines ->
fun String.getStatValue() = substringBefore("\t").trim() fun String.getStatValue() = substringBefore("\t").trim()
val ownPackages = from.get().ownPackages val statsLineCount = if (!ownPackages.isPresent) 1 else 3
val statsLineCount = if (ownPackages == null) 1 else 3
val stats = lines.take(statsLineCount).map { it.getStatValue() }.toList() val stats = lines.take(statsLineCount).map { it.getStatValue() }.toList()
val total = stats[0] val total = stats[0]
@@ -122,7 +129,7 @@ open class DexMethodCountStats : DefaultTask() {
println("##teamcity[buildStatisticValue key='DexMethodCount_${artifactOrArchiveName}' value='$total']") println("##teamcity[buildStatisticValue key='DexMethodCount_${artifactOrArchiveName}' value='$total']")
} }
ownPackages?.let { packages -> ownPackages.map { packages ->
val totalOwnPackages = stats[1] val totalOwnPackages = stats[1]
val totalOtherPackages = stats[2] val totalOtherPackages = stats[2]
@@ -141,7 +148,9 @@ open class DexMethodCountStats : DefaultTask() {
fun Project.printStats(dexMethodCount: TaskProvider<DexMethodCount>) { fun Project.printStats(dexMethodCount: TaskProvider<DexMethodCount>) {
val dexMethodCountStats = tasks.register("dexMethodCountStats", DexMethodCountStats::class.java) { val dexMethodCountStats = tasks.register("dexMethodCountStats", DexMethodCountStats::class.java) {
dependsOn(dexMethodCount) dependsOn(dexMethodCount)
from = dexMethodCount inputFile.set(dexMethodCount.flatMap { objects.fileProperty().apply { set(it.detailOutputFile) } })
artifactOrArchiveName.set(dexMethodCount.map { it.artifactOrArchiveName })
ownPackages.set(dexMethodCount.flatMap { it.ownPackages })
} }
dexMethodCount.configure { dexMethodCount.configure {
+4 -1
View File
@@ -103,8 +103,11 @@ projectTest(parallel = true) {
workingDir = rootDir workingDir = rootDir
systemProperty("kotlin.test.script.classpath", testSourceSet.output.classesDirs.joinToString(File.pathSeparator)) systemProperty("kotlin.test.script.classpath", testSourceSet.output.classesDirs.joinToString(File.pathSeparator))
val antLauncherJarPathProvider = project.provider {
antLauncherJar.asPath
}
doFirst { doFirst {
systemProperty("kotlin.ant.classpath", antLauncherJar.asPath) systemProperty("kotlin.ant.classpath", antLauncherJarPathProvider.get())
systemProperty("kotlin.ant.launcher.class", "org.apache.tools.ant.Main") systemProperty("kotlin.ant.launcher.class", "org.apache.tools.ant.Main")
} }
} }
+9 -3
View File
@@ -1,6 +1,6 @@
import org.gradle.configurationcache.extensions.serviceOf
import org.gradle.internal.os.OperatingSystem import org.gradle.internal.os.OperatingSystem
import java.net.URI import java.net.URI
import javax.inject.Inject
repositories { repositories {
ivy { ivy {
@@ -68,6 +68,11 @@ val prepareEmulator by task<DefaultTask> {
dependsOn(prepareSdk) dependsOn(prepareSdk)
} }
interface Injected {
@get:Inject val fs: FileSystemOperations
@get:Inject val archiveOperations: ArchiveOperations
}
fun unzipSdkTask( fun unzipSdkTask(
sdkName: String, sdkVer: String, destinationSubdir: String, coordinatesSuffix: String, sdkName: String, sdkVer: String, destinationSubdir: String, coordinatesSuffix: String,
additionalConfig: Configuration? = null, dirLevelsToSkipOnUnzip: Int = 0, ext: String = "zip", additionalConfig: Configuration? = null, dirLevelsToSkipOnUnzip: Int = 0, ext: String = "zip",
@@ -86,8 +91,9 @@ fun unzipSdkTask(
inputs.files(cfg) inputs.files(cfg)
val targetDir = project.file("$sdkDestDir/$destinationSubdir") val targetDir = project.file("$sdkDestDir/$destinationSubdir")
outputs.dirs(targetDir) outputs.dirs(targetDir)
val fs = project.serviceOf<FileSystemOperations>() val injected = project.objects.newInstance<Injected>()
val archiveOperations = project.serviceOf<ArchiveOperations>() val fs = injected.fs
val archiveOperations = injected.archiveOperations
val file = cfg.singleFile val file = cfg.singleFile
doFirst { doFirst {
fs.copy { fs.copy {
@@ -39,9 +39,10 @@ sourceSets {
projectTest(parallel = true) { projectTest(parallel = true) {
dependsOn(":dist") dependsOn(":dist")
workingDir = rootDir workingDir = project.rootDir
val useFirIdeaPlugin = kotlinBuildProperties.useFirIdeaPlugin
doFirst { doFirst {
if (!kotlinBuildProperties.useFirIdeaPlugin) { if (!useFirIdeaPlugin) {
error("Test task in the module should be executed with -Pidea.fir.plugin=true") error("Test task in the module should be executed with -Pidea.fir.plugin=true")
} }
} }
@@ -53,12 +54,12 @@ projectTest(taskName = "ideaFirPerformanceTest") {
val currentOs = org.gradle.internal.os.OperatingSystem.current() val currentOs = org.gradle.internal.os.OperatingSystem.current()
if (!currentOs.isWindows) { if (!currentOs.isWindows) {
System.getenv("ASYNC_PROFILER_HOME")?.let { asyncProfilerHome -> project.providers.systemProperty("ASYNC_PROFILER_HOME").forUseAtConfigurationTime().orNull?.let { asyncProfilerHome ->
classpath += files("$asyncProfilerHome/build/async-profiler.jar") classpath += project.files("$asyncProfilerHome/build/async-profiler.jar")
} }
} }
workingDir = rootDir workingDir = project.rootDir
jvmArgs?.removeAll { it.startsWith("-Xmx") } jvmArgs?.removeAll { it.startsWith("-Xmx") }
@@ -72,7 +73,7 @@ projectTest(taskName = "ideaFirPerformanceTest") {
"-XX:+UseConcMarkSweepGC" "-XX:+UseConcMarkSweepGC"
) )
System.getenv("YOURKIT_PROFILER_HOME")?.let {yourKitHome -> project.providers.systemProperty("YOURKIT_PROFILER_HOME").forUseAtConfigurationTime().orNull?.let {yourKitHome ->
when { when {
currentOs.isLinux -> { currentOs.isLinux -> {
jvmArgs("-agentpath:$yourKitHome/bin/linux-x86-64/libyjpagent.so") jvmArgs("-agentpath:$yourKitHome/bin/linux-x86-64/libyjpagent.so")
@@ -85,10 +86,9 @@ projectTest(taskName = "ideaFirPerformanceTest") {
} }
} }
doFirst { systemProperty("idea.home.path", project.intellijRootDir().canonicalPath)
systemProperty("idea.home.path", intellijRootDir().canonicalPath)
project.findProperty("cacheRedirectorEnabled")?.let { project.providers.gradleProperty("cacheRedirectorEnabled").forUseAtConfigurationTime().orNull?.let {
systemProperty("kotlin.test.gradle.import.arguments", "-PcacheRedirectorEnabled=$it") systemProperty("kotlin.test.gradle.import.arguments", "-PcacheRedirectorEnabled=$it")
}
} }
} }
+2 -1
View File
@@ -37,8 +37,9 @@ sourceSets {
projectTest(parallel = true) { projectTest(parallel = true) {
dependsOn(":dist") dependsOn(":dist")
workingDir = rootDir workingDir = rootDir
val useFirIdeaPlugin = kotlinBuildProperties.useFirIdeaPlugin
doFirst { doFirst {
if (!kotlinBuildProperties.useFirIdeaPlugin) { if (!useFirIdeaPlugin) {
error("Test task in the module should be executed with -Pidea.fir.plugin=true") error("Test task in the module should be executed with -Pidea.fir.plugin=true")
} }
} }
+2 -1
View File
@@ -47,8 +47,9 @@ sourceSets {
projectTest { projectTest {
dependsOn(":dist") dependsOn(":dist")
workingDir = rootDir workingDir = rootDir
val useFirIdeaPlugin = kotlinBuildProperties.useFirIdeaPlugin
doFirst { doFirst {
if (!kotlinBuildProperties.useFirIdeaPlugin) { if (!useFirIdeaPlugin) {
error("Test task in the module should be executed with -Pidea.fir.plugin=true") error("Test task in the module should be executed with -Pidea.fir.plugin=true")
} }
} }
@@ -48,8 +48,9 @@ sourceSets {
projectTest { projectTest {
dependsOn(":dist") dependsOn(":dist")
workingDir = rootDir workingDir = rootDir
val useFirIdeaPlugin = kotlinBuildProperties.useFirIdeaPlugin
doFirst { doFirst {
if (!kotlinBuildProperties.useFirIdeaPlugin) { if (!useFirIdeaPlugin) {
error("Test task in the module should be executed with -Pidea.fir.plugin=true") error("Test task in the module should be executed with -Pidea.fir.plugin=true")
} }
} }
@@ -44,7 +44,8 @@ dependencies {
projectTest { projectTest {
dependsOn(compilerClasspath) dependsOn(compilerClasspath)
val compilerClasspathProvider = project.provider { compilerClasspath.asPath }
doFirst { doFirst {
systemProperty("kotlin.compiler.classpath", compilerClasspath.asPath) systemProperty("kotlin.compiler.classpath", compilerClasspathProvider.get())
} }
} }
+1 -1
View File
@@ -244,7 +244,7 @@ modularJar {
dexMethodCount { dexMethodCount {
dependsOn(result) dependsOn(result)
jarFile = result.get().outputs.files.single() jarFile = result.get().outputs.files.single()
ownPackages = listOf("kotlin.reflect") ownPackages.set(listOf("kotlin.reflect"))
} }
artifacts { artifacts {
+2 -1
View File
@@ -154,10 +154,11 @@ val compileKotlinJs by tasks.existing(KotlinCompile::class) {
val compileTestKotlinJs by tasks.existing(KotlinCompile::class) { val compileTestKotlinJs by tasks.existing(KotlinCompile::class) {
val sources: FileCollection = kotlin.sourceSets["commonTest"].kotlin
doFirst { doFirst {
// Note: common test sources are copied to the actual source directory by commonMainSources task, // Note: common test sources are copied to the actual source directory by commonMainSources task,
// so can't do this at configuration time: // so can't do this at configuration time:
kotlinOptions.freeCompilerArgs += "-Xcommon-sources=${kotlin.sourceSets["commonTest"].kotlin.joinToString(",")}" kotlinOptions.freeCompilerArgs += "-Xcommon-sources=${sources.joinToString(",")}"
} }
} }
@@ -64,11 +64,19 @@ projectTest {
dependsOn(":dist") dependsOn(":dist")
workingDir = rootDir workingDir = rootDir
useAndroidJar() useAndroidJar()
val androidPluginPath = File(intellijRootDir(), "plugins/android/lib").canonicalPath
systemProperty("ideaSdk.androidPlugin.path", androidPluginPath)
val androidExtensionsRuntimeProvider = project.provider {
androidExtensionsRuntimeForTests.asPath
}
val robolectricClasspathProvider = project.provider {
robolectricClasspath.asPath
}
doFirst { doFirst {
systemProperty("androidExtensionsRuntime.classpath", androidExtensionsRuntimeForTests.asPath) systemProperty("androidExtensionsRuntime.classpath", androidExtensionsRuntimeProvider.get())
val androidPluginPath = File(intellijRootDir(), "plugins/android/lib").canonicalPath systemProperty("robolectric.classpath", robolectricClasspathProvider.get())
systemProperty("ideaSdk.androidPlugin.path", androidPluginPath)
systemProperty("robolectric.classpath", robolectricClasspath.asPath)
} }
} }
@@ -65,11 +65,15 @@ projectTest {
dependsOn(":dist") dependsOn(":dist")
workingDir = rootDir workingDir = rootDir
useAndroidJar() useAndroidJar()
val androidPluginPath = File(intellijRootDir(), "plugins/android/lib").canonicalPath
systemProperty("ideaSdk.androidPlugin.path", androidPluginPath)
val parcelizeRuntimeForTestsProvider = project.provider { parcelizeRuntimeForTests.asPath }
val robolectricClasspathProvider = project.provider { robolectricClasspath.asPath }
doFirst { doFirst {
systemProperty("parcelizeRuntime.classpath", parcelizeRuntimeForTests.asPath) systemProperty("parcelizeRuntime.classpath", parcelizeRuntimeForTestsProvider.get())
val androidPluginPath = File(intellijRootDir(), "plugins/android/lib").canonicalPath systemProperty("robolectric.classpath", robolectricClasspathProvider.get())
systemProperty("ideaSdk.androidPlugin.path", androidPluginPath)
systemProperty("robolectric.classpath", robolectricClasspath.asPath)
} }
} }
@@ -40,10 +40,12 @@ sourceSets {
} }
projectTest { projectTest {
systemProperty("kotlin.test.script.classpath", testSourceSet.output.classesDirs.joinToString(File.pathSeparator))
val testCompilerClasspathProvider = project.provider { testCompilerClasspath.asPath }
val testCompilationClasspathProvider = project.provider { testCompilationClasspath.asPath }
doFirst { doFirst {
systemProperty("kotlin.test.script.classpath", testSourceSet.output.classesDirs.joinToString(File.pathSeparator)) systemProperty("compilerClasspath", testCompilerClasspathProvider.get())
systemProperty("compilerClasspath", testCompilerClasspath.asPath) systemProperty("compilationClasspath", testCompilationClasspathProvider.get())
systemProperty("compilationClasspath", testCompilationClasspath.asPath)
} }
} }
+5 -2
View File
@@ -97,9 +97,12 @@ javadocJar()
projectTest { projectTest {
dependsOn(runtimeJar) dependsOn(runtimeJar)
val testCompilerClasspathProvider = project.provider { testCompilerClasspath.asPath }
val testCompilationClasspathProvider = project.provider { testCompilationClasspath.asPath }
val runtimeJarPathProvider = project.provider { runtimeJar.get().outputs.files.asPath }
doFirst { doFirst {
systemProperty("compilerClasspath", "${runtimeJar.get().outputs.files.asPath}${File.pathSeparator}${testCompilerClasspath.asPath}") systemProperty("compilerClasspath", "${runtimeJarPathProvider.get()}${File.pathSeparator}${testCompilerClasspathProvider.get()}")
systemProperty("compilationClasspath", testCompilationClasspath.asPath) systemProperty("compilationClasspath", testCompilationClasspathProvider.get())
} }
} }