From 6bd44df8614bbba5e19c9cf2738b0de5118fdc9d Mon Sep 17 00:00:00 2001 From: Alexander Likhachev Date: Wed, 17 Feb 2021 15:04:53 +0300 Subject: [PATCH] [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 --- .../src/main/kotlin/plugins/DexMethodCount.kt | 57 +++++++++++-------- compiler/build.gradle.kts | 5 +- dependencies/android-sdk/build.gradle.kts | 12 +++- .../build.gradle.kts | 22 +++---- idea/idea-fir/build.gradle.kts | 3 +- idea/idea-frontend-fir/build.gradle.kts | 3 +- .../idea-fir-low-level-api/build.gradle.kts | 3 +- .../build.gradle.kts | 3 +- libraries/reflect/build.gradle.kts | 2 +- libraries/stdlib/js-ir/build.gradle.kts | 3 +- .../build.gradle.kts | 16 ++++-- .../parcelize-compiler/build.gradle.kts | 12 ++-- .../build.gradle.kts | 8 ++- prepare/compiler-embeddable/build.gradle.kts | 7 ++- 14 files changed, 98 insertions(+), 58 deletions(-) diff --git a/buildSrc/src/main/kotlin/plugins/DexMethodCount.kt b/buildSrc/src/main/kotlin/plugins/DexMethodCount.kt index 166bda2ded5..551e651ee2d 100644 --- a/buildSrc/src/main/kotlin/plugins/DexMethodCount.kt +++ b/buildSrc/src/main/kotlin/plugins/DexMethodCount.kt @@ -6,12 +6,15 @@ import com.jakewharton.dex.* import org.gradle.api.DefaultTask 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.jvm.tasks.Jar import java.io.File @CacheableTask -open class DexMethodCount : DefaultTask() { +abstract class DexMethodCount : DefaultTask() { data class Counts( val total: Int, @@ -24,16 +27,18 @@ open class DexMethodCount : DefaultTask() { @Classpath lateinit var jarFile: File - @Optional - @Input - var ownPackages: List? = null + @get:Optional + @get:Input + abstract val ownPackages: ListProperty @Internal var artifactName: String? = null + private val projectName = project.name + @get:Input val artifactOrArchiveName: String - get() = artifactName ?: project.name + get() = artifactName ?: projectName fun from(jar: Jar) { jarFile = jar.archiveFile.get().asFile @@ -45,8 +50,9 @@ open class DexMethodCount : DefaultTask() { lateinit var counts: Counts @get:OutputFile - val detailOutputFile: File - get() = project.buildDir.resolve("$artifactOrArchiveName-method-count.txt") + val detailOutputFile: File by lazy { + project.buildDir.resolve("$artifactOrArchiveName-method-count.txt") + } @TaskAction fun invoke() { @@ -59,9 +65,9 @@ open class DexMethodCount : DefaultTask() { 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 { + val ownPackages = ownPackages.map { list -> list.map { "$it." } } + val byOwnPackages = if (ownPackages.isPresent) { + this.partition { method -> ownPackages.get().any { method.declaringType.startsWith(it) } }.let { it.first.size to it.second.size } } else (null to null) @@ -78,7 +84,7 @@ open class DexMethodCount : DefaultTask() { private fun outputDetails(counts: Counts) { detailOutputFile.printWriter().use { writer -> 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.totalOtherPackages?.padRight()}\tTotal methods from other packages") } @@ -96,23 +102,24 @@ open class DexMethodCount : DefaultTask() { } } -open class DexMethodCountStats : DefaultTask() { - - @Internal - lateinit var from: TaskProvider - +abstract class DexMethodCountStats : DefaultTask() { @get:InputFile - internal val inputFile - get() = from.get().detailOutputFile + internal abstract val inputFile: RegularFileProperty + + @get:Input + internal abstract val artifactOrArchiveName: Property + + @get:Input + @get:Optional + internal abstract val ownPackages: ListProperty @TaskAction private fun printStats() { - val artifactOrArchiveName = from.get().artifactOrArchiveName - inputFile.reader().useLines { lines -> + val artifactOrArchiveName = artifactOrArchiveName.get() + inputFile.get().asFile.reader().useLines { lines -> fun String.getStatValue() = substringBefore("\t").trim() - val ownPackages = from.get().ownPackages - val statsLineCount = if (ownPackages == null) 1 else 3 + val statsLineCount = if (!ownPackages.isPresent) 1 else 3 val stats = lines.take(statsLineCount).map { it.getStatValue() }.toList() val total = stats[0] @@ -122,7 +129,7 @@ open class DexMethodCountStats : DefaultTask() { println("##teamcity[buildStatisticValue key='DexMethodCount_${artifactOrArchiveName}' value='$total']") } - ownPackages?.let { packages -> + ownPackages.map { packages -> val totalOwnPackages = stats[1] val totalOtherPackages = stats[2] @@ -141,7 +148,9 @@ open class DexMethodCountStats : DefaultTask() { fun Project.printStats(dexMethodCount: TaskProvider) { val dexMethodCountStats = tasks.register("dexMethodCountStats", DexMethodCountStats::class.java) { 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 { diff --git a/compiler/build.gradle.kts b/compiler/build.gradle.kts index 2ffdfd9917d..9d4f2837843 100644 --- a/compiler/build.gradle.kts +++ b/compiler/build.gradle.kts @@ -103,8 +103,11 @@ projectTest(parallel = true) { workingDir = rootDir systemProperty("kotlin.test.script.classpath", testSourceSet.output.classesDirs.joinToString(File.pathSeparator)) + val antLauncherJarPathProvider = project.provider { + antLauncherJar.asPath + } doFirst { - systemProperty("kotlin.ant.classpath", antLauncherJar.asPath) + systemProperty("kotlin.ant.classpath", antLauncherJarPathProvider.get()) systemProperty("kotlin.ant.launcher.class", "org.apache.tools.ant.Main") } } diff --git a/dependencies/android-sdk/build.gradle.kts b/dependencies/android-sdk/build.gradle.kts index 7117662c672..f0e8790b05c 100644 --- a/dependencies/android-sdk/build.gradle.kts +++ b/dependencies/android-sdk/build.gradle.kts @@ -1,6 +1,6 @@ -import org.gradle.configurationcache.extensions.serviceOf import org.gradle.internal.os.OperatingSystem import java.net.URI +import javax.inject.Inject repositories { ivy { @@ -68,6 +68,11 @@ val prepareEmulator by task { dependsOn(prepareSdk) } +interface Injected { + @get:Inject val fs: FileSystemOperations + @get:Inject val archiveOperations: ArchiveOperations +} + fun unzipSdkTask( sdkName: String, sdkVer: String, destinationSubdir: String, coordinatesSuffix: String, additionalConfig: Configuration? = null, dirLevelsToSkipOnUnzip: Int = 0, ext: String = "zip", @@ -86,8 +91,9 @@ fun unzipSdkTask( inputs.files(cfg) val targetDir = project.file("$sdkDestDir/$destinationSubdir") outputs.dirs(targetDir) - val fs = project.serviceOf() - val archiveOperations = project.serviceOf() + val injected = project.objects.newInstance() + val fs = injected.fs + val archiveOperations = injected.archiveOperations val file = cfg.singleFile doFirst { fs.copy { diff --git a/idea/idea-fir-performance-tests/build.gradle.kts b/idea/idea-fir-performance-tests/build.gradle.kts index 76ba999be43..e42c4a488c2 100644 --- a/idea/idea-fir-performance-tests/build.gradle.kts +++ b/idea/idea-fir-performance-tests/build.gradle.kts @@ -39,9 +39,10 @@ sourceSets { projectTest(parallel = true) { dependsOn(":dist") - workingDir = rootDir + workingDir = project.rootDir + val useFirIdeaPlugin = kotlinBuildProperties.useFirIdeaPlugin doFirst { - if (!kotlinBuildProperties.useFirIdeaPlugin) { + if (!useFirIdeaPlugin) { 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() if (!currentOs.isWindows) { - System.getenv("ASYNC_PROFILER_HOME")?.let { asyncProfilerHome -> - classpath += files("$asyncProfilerHome/build/async-profiler.jar") + project.providers.systemProperty("ASYNC_PROFILER_HOME").forUseAtConfigurationTime().orNull?.let { asyncProfilerHome -> + classpath += project.files("$asyncProfilerHome/build/async-profiler.jar") } } - workingDir = rootDir + workingDir = project.rootDir jvmArgs?.removeAll { it.startsWith("-Xmx") } @@ -72,7 +73,7 @@ projectTest(taskName = "ideaFirPerformanceTest") { "-XX:+UseConcMarkSweepGC" ) - System.getenv("YOURKIT_PROFILER_HOME")?.let {yourKitHome -> + project.providers.systemProperty("YOURKIT_PROFILER_HOME").forUseAtConfigurationTime().orNull?.let {yourKitHome -> when { currentOs.isLinux -> { jvmArgs("-agentpath:$yourKitHome/bin/linux-x86-64/libyjpagent.so") @@ -85,10 +86,9 @@ projectTest(taskName = "ideaFirPerformanceTest") { } } - doFirst { - systemProperty("idea.home.path", intellijRootDir().canonicalPath) - project.findProperty("cacheRedirectorEnabled")?.let { - systemProperty("kotlin.test.gradle.import.arguments", "-PcacheRedirectorEnabled=$it") - } + systemProperty("idea.home.path", project.intellijRootDir().canonicalPath) + + project.providers.gradleProperty("cacheRedirectorEnabled").forUseAtConfigurationTime().orNull?.let { + systemProperty("kotlin.test.gradle.import.arguments", "-PcacheRedirectorEnabled=$it") } } diff --git a/idea/idea-fir/build.gradle.kts b/idea/idea-fir/build.gradle.kts index 71c7e9e39f2..0f72eeaf168 100644 --- a/idea/idea-fir/build.gradle.kts +++ b/idea/idea-fir/build.gradle.kts @@ -37,8 +37,9 @@ sourceSets { projectTest(parallel = true) { dependsOn(":dist") workingDir = rootDir + val useFirIdeaPlugin = kotlinBuildProperties.useFirIdeaPlugin doFirst { - if (!kotlinBuildProperties.useFirIdeaPlugin) { + if (!useFirIdeaPlugin) { error("Test task in the module should be executed with -Pidea.fir.plugin=true") } } diff --git a/idea/idea-frontend-fir/build.gradle.kts b/idea/idea-frontend-fir/build.gradle.kts index 56c00c3448c..e9e5bd12ee0 100644 --- a/idea/idea-frontend-fir/build.gradle.kts +++ b/idea/idea-frontend-fir/build.gradle.kts @@ -47,8 +47,9 @@ sourceSets { projectTest { dependsOn(":dist") workingDir = rootDir + val useFirIdeaPlugin = kotlinBuildProperties.useFirIdeaPlugin doFirst { - if (!kotlinBuildProperties.useFirIdeaPlugin) { + if (!useFirIdeaPlugin) { error("Test task in the module should be executed with -Pidea.fir.plugin=true") } } diff --git a/idea/idea-frontend-fir/idea-fir-low-level-api/build.gradle.kts b/idea/idea-frontend-fir/idea-fir-low-level-api/build.gradle.kts index 659170325d5..f1bcd9204be 100644 --- a/idea/idea-frontend-fir/idea-fir-low-level-api/build.gradle.kts +++ b/idea/idea-frontend-fir/idea-fir-low-level-api/build.gradle.kts @@ -48,8 +48,9 @@ sourceSets { projectTest { dependsOn(":dist") workingDir = rootDir + val useFirIdeaPlugin = kotlinBuildProperties.useFirIdeaPlugin doFirst { - if (!kotlinBuildProperties.useFirIdeaPlugin) { + if (!useFirIdeaPlugin) { error("Test task in the module should be executed with -Pidea.fir.plugin=true") } } diff --git a/libraries/examples/kotlin-jsr223-daemon-local-eval-example/build.gradle.kts b/libraries/examples/kotlin-jsr223-daemon-local-eval-example/build.gradle.kts index ce7b82338e7..80d40a91491 100644 --- a/libraries/examples/kotlin-jsr223-daemon-local-eval-example/build.gradle.kts +++ b/libraries/examples/kotlin-jsr223-daemon-local-eval-example/build.gradle.kts @@ -44,7 +44,8 @@ dependencies { projectTest { dependsOn(compilerClasspath) + val compilerClasspathProvider = project.provider { compilerClasspath.asPath } doFirst { - systemProperty("kotlin.compiler.classpath", compilerClasspath.asPath) + systemProperty("kotlin.compiler.classpath", compilerClasspathProvider.get()) } } diff --git a/libraries/reflect/build.gradle.kts b/libraries/reflect/build.gradle.kts index a25e45a93f7..1c9a6e3b7ee 100644 --- a/libraries/reflect/build.gradle.kts +++ b/libraries/reflect/build.gradle.kts @@ -244,7 +244,7 @@ modularJar { dexMethodCount { dependsOn(result) jarFile = result.get().outputs.files.single() - ownPackages = listOf("kotlin.reflect") + ownPackages.set(listOf("kotlin.reflect")) } artifacts { diff --git a/libraries/stdlib/js-ir/build.gradle.kts b/libraries/stdlib/js-ir/build.gradle.kts index 68546be08cd..2e9046e3500 100644 --- a/libraries/stdlib/js-ir/build.gradle.kts +++ b/libraries/stdlib/js-ir/build.gradle.kts @@ -154,10 +154,11 @@ val compileKotlinJs by tasks.existing(KotlinCompile::class) { val compileTestKotlinJs by tasks.existing(KotlinCompile::class) { + val sources: FileCollection = kotlin.sourceSets["commonTest"].kotlin doFirst { // Note: common test sources are copied to the actual source directory by commonMainSources task, // so can't do this at configuration time: - kotlinOptions.freeCompilerArgs += "-Xcommon-sources=${kotlin.sourceSets["commonTest"].kotlin.joinToString(",")}" + kotlinOptions.freeCompilerArgs += "-Xcommon-sources=${sources.joinToString(",")}" } } diff --git a/plugins/android-extensions/android-extensions-compiler/build.gradle.kts b/plugins/android-extensions/android-extensions-compiler/build.gradle.kts index dcd12623046..be3ea83bfb1 100644 --- a/plugins/android-extensions/android-extensions-compiler/build.gradle.kts +++ b/plugins/android-extensions/android-extensions-compiler/build.gradle.kts @@ -64,11 +64,19 @@ projectTest { dependsOn(":dist") workingDir = rootDir 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 { - systemProperty("androidExtensionsRuntime.classpath", androidExtensionsRuntimeForTests.asPath) - val androidPluginPath = File(intellijRootDir(), "plugins/android/lib").canonicalPath - systemProperty("ideaSdk.androidPlugin.path", androidPluginPath) - systemProperty("robolectric.classpath", robolectricClasspath.asPath) + systemProperty("androidExtensionsRuntime.classpath", androidExtensionsRuntimeProvider.get()) + systemProperty("robolectric.classpath", robolectricClasspathProvider.get()) } } diff --git a/plugins/parcelize/parcelize-compiler/build.gradle.kts b/plugins/parcelize/parcelize-compiler/build.gradle.kts index 34a043a72b5..d9bc5ddf644 100644 --- a/plugins/parcelize/parcelize-compiler/build.gradle.kts +++ b/plugins/parcelize/parcelize-compiler/build.gradle.kts @@ -65,11 +65,15 @@ projectTest { dependsOn(":dist") workingDir = rootDir 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 { - systemProperty("parcelizeRuntime.classpath", parcelizeRuntimeForTests.asPath) - val androidPluginPath = File(intellijRootDir(), "plugins/android/lib").canonicalPath - systemProperty("ideaSdk.androidPlugin.path", androidPluginPath) - systemProperty("robolectric.classpath", robolectricClasspath.asPath) + systemProperty("parcelizeRuntime.classpath", parcelizeRuntimeForTestsProvider.get()) + systemProperty("robolectric.classpath", robolectricClasspathProvider.get()) } } diff --git a/prepare/compiler-client-embeddable/build.gradle.kts b/prepare/compiler-client-embeddable/build.gradle.kts index 294f1159fb7..53c7e93063b 100644 --- a/prepare/compiler-client-embeddable/build.gradle.kts +++ b/prepare/compiler-client-embeddable/build.gradle.kts @@ -40,10 +40,12 @@ sourceSets { } 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 { - systemProperty("kotlin.test.script.classpath", testSourceSet.output.classesDirs.joinToString(File.pathSeparator)) - systemProperty("compilerClasspath", testCompilerClasspath.asPath) - systemProperty("compilationClasspath", testCompilationClasspath.asPath) + systemProperty("compilerClasspath", testCompilerClasspathProvider.get()) + systemProperty("compilationClasspath", testCompilationClasspathProvider.get()) } } diff --git a/prepare/compiler-embeddable/build.gradle.kts b/prepare/compiler-embeddable/build.gradle.kts index 65d0a2847f4..b4ea0a47bb4 100644 --- a/prepare/compiler-embeddable/build.gradle.kts +++ b/prepare/compiler-embeddable/build.gradle.kts @@ -97,9 +97,12 @@ javadocJar() projectTest { dependsOn(runtimeJar) + val testCompilerClasspathProvider = project.provider { testCompilerClasspath.asPath } + val testCompilationClasspathProvider = project.provider { testCompilationClasspath.asPath } + val runtimeJarPathProvider = project.provider { runtimeJar.get().outputs.files.asPath } doFirst { - systemProperty("compilerClasspath", "${runtimeJar.get().outputs.files.asPath}${File.pathSeparator}${testCompilerClasspath.asPath}") - systemProperty("compilationClasspath", testCompilationClasspath.asPath) + systemProperty("compilerClasspath", "${runtimeJarPathProvider.get()}${File.pathSeparator}${testCompilerClasspathProvider.get()}") + systemProperty("compilationClasspath", testCompilationClasspathProvider.get()) } }