[Build] Fix configuration cache issues (part 1)
* Make `clean` task compatible with configuration cache * Make Java compile instrumentation compatible with configuration cache * Make settings.gradle compatible with configuration cache * Initial work on making IntelliJInstrumentCodeTask compatible with configuration cache * Make writeStdlibVersion task compatible with configuration cache * Copy some properties to not capture it's owning object into lambda to support configuration cache Relates to #KT-44611
This commit is contained in:
+10
-12
@@ -92,18 +92,16 @@ benchmark {
|
||||
}
|
||||
}
|
||||
|
||||
tasks.named("classes") {
|
||||
doLast {
|
||||
tasks.named("mainBenchmarkJar", Zip::class.java) {
|
||||
isZip64 = true
|
||||
archiveName = "benchmarks.jar"
|
||||
}
|
||||
listOf("mainBenchmark", "mainFirBenchmark", "mainNiBenchmark").forEach {
|
||||
tasks.named(it, JavaExec::class.java) {
|
||||
systemProperty("idea.home.path", intellijRootDir().canonicalPath)
|
||||
}
|
||||
}
|
||||
}
|
||||
tasks.matching { it is Zip && it.name == "mainBenchmarkJar" }.configureEach {
|
||||
this as Zip
|
||||
isZip64 = true
|
||||
archiveFileName.set("benchmarks.jar")
|
||||
}
|
||||
|
||||
val benchmarkTasks = listOf("mainBenchmark", "mainFirBenchmark", "mainNiBenchmark")
|
||||
tasks.matching { it is JavaExec && it.name in benchmarkTasks }.configureEach {
|
||||
this as JavaExec
|
||||
systemProperty("idea.home.path", intellijRootDir().canonicalPath)
|
||||
}
|
||||
|
||||
tasks.register<JavaExec>("runBenchmark") {
|
||||
|
||||
+4
-9
@@ -621,17 +621,12 @@ val ideaPlugin by task<Task> {
|
||||
}
|
||||
|
||||
tasks {
|
||||
named("clean") {
|
||||
doLast {
|
||||
delete("$buildDir/repo")
|
||||
delete(distDir)
|
||||
}
|
||||
named<Delete>("clean") {
|
||||
delete += setOf("$buildDir/repo", distDir)
|
||||
}
|
||||
|
||||
register("cleanupArtifacts") {
|
||||
doLast {
|
||||
delete(artifactsDir)
|
||||
}
|
||||
register<Delete>("cleanupArtifacts") {
|
||||
delete = setOf(artifactsDir)
|
||||
}
|
||||
|
||||
listOf("clean", "assemble", "install").forEach { taskName ->
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
import org.gradle.api.Action
|
||||
import org.gradle.api.Task
|
||||
import org.gradle.api.artifacts.Configuration
|
||||
import org.gradle.api.file.FileCollection
|
||||
import org.gradle.api.tasks.SourceSet
|
||||
import org.gradle.api.tasks.compile.JavaCompile
|
||||
import org.gradle.kotlin.dsl.provideDelegate
|
||||
import org.gradle.kotlin.dsl.withGroovyBuilder
|
||||
|
||||
/*
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
class InstrumentJava(@Transient val javaInstrumentator: Configuration, @Transient val sourceSet: SourceSet) : Action<Task> {
|
||||
private val instrumentatorClasspath: String by lazy {
|
||||
javaInstrumentator.asPath
|
||||
}
|
||||
|
||||
private val srcDirs: FileCollection by lazy {
|
||||
sourceSet.allJava.sourceDirectories
|
||||
}
|
||||
|
||||
override fun execute(task: Task) {
|
||||
require(task is JavaCompile) { "$task is not of type JavaCompile!" }
|
||||
task.doLast {
|
||||
task.ant.withGroovyBuilder {
|
||||
"taskdef"(
|
||||
"name" to "instrumentIdeaExtensions",
|
||||
"classpath" to instrumentatorClasspath,
|
||||
"loaderref" to "java2.loader",
|
||||
"classname" to "com.intellij.ant.InstrumentIdeaExtensions"
|
||||
)
|
||||
}
|
||||
|
||||
val javaSourceDirectories = srcDirs.filter { it.exists() }
|
||||
|
||||
task.ant.withGroovyBuilder {
|
||||
javaSourceDirectories.forEach { directory ->
|
||||
"instrumentIdeaExtensions"(
|
||||
"srcdir" to directory,
|
||||
"destdir" to task.destinationDir,
|
||||
"classpath" to task.classpath.asPath,
|
||||
"includeantruntime" to false,
|
||||
"instrumentNotNull" to true
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -90,7 +90,7 @@ fun Project.configureFormInstrumentation() {
|
||||
project.tasks.register(sourceSetParam.getTaskName("instrument", "classes"), IntelliJInstrumentCodeTask::class.java) {
|
||||
dependsOn(sourceSetParam.classesTaskName).onlyIf { !classesDirsCopy.isEmpty }
|
||||
sourceSet = sourceSetParam
|
||||
instrumentationClasspath = instrumentationClasspathCfg
|
||||
instrumentationClasspathConfiguration = instrumentationClasspathCfg
|
||||
originalClassesDirs = classesDirsCopy
|
||||
output = instrumentedClassesDir
|
||||
outputs.dir(instrumentedClassesDir)
|
||||
@@ -111,8 +111,14 @@ open class IntelliJInstrumentCodeTask : ConventionTask() {
|
||||
private const val LOADER_REF = "java2.loader"
|
||||
}
|
||||
|
||||
@Classpath
|
||||
var instrumentationClasspath: Configuration? = null
|
||||
@Transient
|
||||
@Internal
|
||||
lateinit var instrumentationClasspathConfiguration: Configuration
|
||||
|
||||
@get:Classpath
|
||||
val instrumentationClasspath: String by lazy {
|
||||
instrumentationClasspathConfiguration.asPath
|
||||
}
|
||||
|
||||
@InputFiles
|
||||
@PathSensitive(PathSensitivity.RELATIVE)
|
||||
@@ -121,13 +127,19 @@ open class IntelliJInstrumentCodeTask : ConventionTask() {
|
||||
@get:Input
|
||||
var instrumentNotNull: Boolean = false
|
||||
|
||||
@Transient
|
||||
@Internal
|
||||
var sourceSet: SourceSet? = null
|
||||
lateinit var sourceSet: SourceSet
|
||||
|
||||
private val compileClasspath by lazy {
|
||||
sourceSet.compileClasspath
|
||||
}
|
||||
|
||||
@get:InputFiles
|
||||
@get:PathSensitive(PathSensitivity.RELATIVE)
|
||||
val sourceDirs: FileCollection
|
||||
get() = project.files(sourceSet!!.allSource.srcDirs.filter { !sourceSet!!.resources.contains(it) && it.exists() })
|
||||
val sourceDirs: FileCollection by lazy {
|
||||
project.files(sourceSet.allSource.srcDirs.filter { !sourceSet.resources.contains(it) && it.exists() })
|
||||
}
|
||||
|
||||
@get:OutputDirectory
|
||||
lateinit var output: File
|
||||
@@ -142,12 +154,12 @@ open class IntelliJInstrumentCodeTask : ConventionTask() {
|
||||
output.deleteRecursively()
|
||||
copyOriginalClasses()
|
||||
|
||||
val classpath = instrumentationClasspath!!
|
||||
val classpath = instrumentationClasspath
|
||||
|
||||
ant.withGroovyBuilder {
|
||||
"taskdef"(
|
||||
"name" to "instrumentIdeaExtensions",
|
||||
"classpath" to classpath.asPath,
|
||||
"classpath" to classpath,
|
||||
"loaderref" to LOADER_REF,
|
||||
"classname" to "com.intellij.ant.InstrumentIdeaExtensions"
|
||||
)
|
||||
@@ -155,7 +167,7 @@ open class IntelliJInstrumentCodeTask : ConventionTask() {
|
||||
|
||||
logger.info("Compiling forms and instrumenting code with nullability preconditions")
|
||||
if (instrumentNotNull) {
|
||||
prepareNotNullInstrumenting(classpath.asPath)
|
||||
prepareNotNullInstrumenting(classpath)
|
||||
}
|
||||
|
||||
instrumentCode(sourceDirs, instrumentNotNull)
|
||||
@@ -186,7 +198,7 @@ open class IntelliJInstrumentCodeTask : ConventionTask() {
|
||||
val depSourceDirectorySets = project.configurations["compile"].dependencies.withType(ProjectDependency::class.java)
|
||||
.map { p -> p.dependencyProject.mainSourceSet.allSource.sourceDirectories }
|
||||
val instrumentationClasspath =
|
||||
depSourceDirectorySets.fold(sourceSet!!.compileClasspath) { acc, v -> acc + v }.asPath.also {
|
||||
depSourceDirectorySets.fold(compileClasspath) { acc, v -> acc + v }.asPath.also {
|
||||
logger.info("Using following dependency source dirs: $it")
|
||||
}
|
||||
|
||||
|
||||
@@ -25,8 +25,9 @@ tasks.withType<JavaCompile> {
|
||||
}
|
||||
|
||||
tasks.named<ProcessResources>("processResources") {
|
||||
inputs.property("compilerVersion", kotlinVersion)
|
||||
val kotlinVersionLocal = kotlinVersion
|
||||
inputs.property("compilerVersion", kotlinVersionLocal)
|
||||
filesMatching("META-INF/compiler.version") {
|
||||
filter<ReplaceTokens>("tokens" to mapOf("snapshot" to kotlinVersion))
|
||||
filter<ReplaceTokens>("tokens" to mapOf("snapshot" to kotlinVersionLocal))
|
||||
}
|
||||
}
|
||||
+5
-4
@@ -16,17 +16,18 @@ val runtimeElements by configurations.creating {
|
||||
}
|
||||
|
||||
val JDK_18: String by rootProject.extra
|
||||
val toolsJarFile = toolsJarFile(jdkHome = File(JDK_18)) ?: error("Couldn't find tools.jar in $JDK_18")
|
||||
val usedInternalApiPackages = listOf(
|
||||
"com/sun/tools/javac" // Used in KAPT
|
||||
)
|
||||
|
||||
val toolsJarStubs by tasks.registering {
|
||||
val toolsJarFile = toolsJarFile(jdkHome = File(JDK_18)) ?: error("Couldn't find tools.jar in $JDK_18")
|
||||
inputs.file(toolsJarFile)
|
||||
|
||||
val outDir = buildDir.resolve(name)
|
||||
outputs.dir(outDir)
|
||||
|
||||
val usedInternalApiPackages = listOf(
|
||||
"com/sun/tools/javac" // Used in KAPT
|
||||
)
|
||||
|
||||
doLast {
|
||||
outDir.deleteRecursively()
|
||||
val zipFile = ZipFile(toolsJarFile)
|
||||
|
||||
@@ -24,42 +24,8 @@ fun Project.configureJavaInstrumentation() {
|
||||
includeJars("javac2", "jdom", "asm-all", rootProject = rootProject)
|
||||
}
|
||||
}
|
||||
|
||||
listOf(mainSourceSet, testSourceSet).forEach { sourceSet ->
|
||||
tasks.named<JavaCompile>(sourceSet.compileJavaTaskName) javaCompile@ {
|
||||
doLast {
|
||||
instrumentClasses(javaInstrumentator.asPath, this@javaCompile, sourceSet)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun instrumentClasses(
|
||||
instrumentatorClasspath: String,
|
||||
javaCompile: JavaCompile,
|
||||
sourceSet: SourceSet
|
||||
) {
|
||||
javaCompile.ant.withGroovyBuilder {
|
||||
"taskdef"(
|
||||
"name" to "instrumentIdeaExtensions",
|
||||
"classpath" to instrumentatorClasspath,
|
||||
"loaderref" to "java2.loader",
|
||||
"classname" to "com.intellij.ant.InstrumentIdeaExtensions"
|
||||
)
|
||||
}
|
||||
|
||||
val javaSourceDirectories = sourceSet.allJava.sourceDirectories.filter { it.exists() }
|
||||
|
||||
javaCompile.ant.withGroovyBuilder {
|
||||
javaSourceDirectories.forEach { directory ->
|
||||
"instrumentIdeaExtensions"(
|
||||
"srcdir" to directory,
|
||||
"destdir" to javaCompile.destinationDir,
|
||||
"classpath" to javaCompile.classpath.asPath,
|
||||
"includeantruntime" to false,
|
||||
"instrumentNotNull" to true
|
||||
)
|
||||
for (sourceSet in listOf(mainSourceSet, testSourceSet)) {
|
||||
tasks.named(sourceSet.compileJavaTaskName, InstrumentJava(javaInstrumentator, sourceSet))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -61,10 +61,11 @@ ext.compileJava9Sources = { Project project, String moduleName, Collection<FileC
|
||||
it.options.fork = true
|
||||
it.options.forkOptions.javaHome = file(JDK_9)
|
||||
it.options.sourcepath = files(java9SourceSet.srcDirs)
|
||||
def compileClasspath = project.configurations.java9CompileClasspath
|
||||
|
||||
doFirst {
|
||||
def moduleFiles = files(*moduleOutputs)
|
||||
def modulePath = project.configurations.java9CompileClasspath.filter { !(it in moduleFiles.files) }
|
||||
def modulePath = compileClasspath.filter { !(it in moduleFiles.files) }
|
||||
|
||||
options.compilerArgs = [
|
||||
'--module-path', modulePath.asPath,
|
||||
|
||||
@@ -21,22 +21,26 @@ artifacts.add(buildVersion.name, file(buildVersionFilePath)) {
|
||||
builtBy(writeBuildNumber)
|
||||
}
|
||||
|
||||
fun replaceVersion(versionFile: File, versionPattern: String, replacement: (MatchResult) -> String) {
|
||||
check(versionFile.isFile) { "Version file $versionFile is not found" }
|
||||
val text = versionFile.readText()
|
||||
val pattern = Regex(versionPattern)
|
||||
val match = pattern.find(text) ?: error("Version pattern is missing in file $versionFile")
|
||||
val newValue = replacement(match)
|
||||
versionFile.writeText(text.replaceRange(match.groups[1]!!.range, newValue))
|
||||
}
|
||||
|
||||
|
||||
val writeStdlibVersion by tasks.registering {
|
||||
val kotlinVersionLocal = kotlinVersion
|
||||
val versionFile = rootDir.resolve("libraries/stdlib/src/kotlin/util/KotlinVersion.kt")
|
||||
inputs.property("version", kotlinVersion)
|
||||
inputs.property("version", kotlinVersionLocal)
|
||||
outputs.file(versionFile)
|
||||
|
||||
fun replaceVersion(versionFile: File, versionPattern: String, replacement: (MatchResult) -> String) {
|
||||
check(versionFile.isFile) { "Version file $versionFile is not found" }
|
||||
val text = versionFile.readText()
|
||||
val pattern = Regex(versionPattern)
|
||||
val match = pattern.find(text) ?: error("Version pattern is missing in file $versionFile")
|
||||
val newValue = replacement(match)
|
||||
versionFile.writeText(text.replaceRange(match.groups[1]!!.range, newValue))
|
||||
}
|
||||
|
||||
doLast {
|
||||
replaceVersion(versionFile, """fun get\(\): KotlinVersion = KotlinVersion\((\d+, \d+, \d+)\)""") {
|
||||
val (major, minor, _, optPatch) = Regex("""^(\d+)\.(\d+)(\.(\d+))?""").find(kotlinVersion)?.destructured ?: error("Cannot parse current version $kotlinVersion")
|
||||
val (major, minor, _, optPatch) = Regex("""^(\d+)\.(\d+)(\.(\d+))?""").find(kotlinVersionLocal)?.destructured ?: error("Cannot parse current version $kotlinVersionLocal")
|
||||
val newVersion = "$major, $minor, ${optPatch.takeIf { it.isNotEmpty() } ?: "0" }"
|
||||
logger.lifecycle("Writing new standard library version components: $newVersion")
|
||||
newVersion
|
||||
|
||||
@@ -42,7 +42,7 @@ noDefaultJar()
|
||||
|
||||
// dummy is used for rewriting dependencies to the shaded packages in the embeddable compiler
|
||||
compilerDummyJar(compilerDummyForDependenciesRewriting("compilerDummy") {
|
||||
classifier = "dummy"
|
||||
archiveClassifier.set("dummy")
|
||||
})
|
||||
|
||||
class CoreXmlShadingTransformer : Transformer {
|
||||
|
||||
+6
-3
@@ -39,9 +39,12 @@ def buildProperties = BuildPropertiesKt.getKotlinBuildPropertiesForSettings(sett
|
||||
def projectVersions = file("./gradle/versions.properties").text
|
||||
|
||||
gradleEnterprise {
|
||||
def buildScanServer = buildProperties.buildScanServer
|
||||
def isTeamCity = buildProperties.isTeamcityBuild
|
||||
|
||||
buildScan {
|
||||
if (buildProperties.buildScanServer != null) {
|
||||
server = buildProperties.buildScanServer
|
||||
if (buildScanServer != null) {
|
||||
server = buildScanServer
|
||||
captureTaskInputFiles = true
|
||||
publishAlways()
|
||||
} else {
|
||||
@@ -52,7 +55,7 @@ gradleEnterprise {
|
||||
obfuscation {
|
||||
ipAddresses { addresses -> ["0.0.0.0"] }
|
||||
hostname { host -> "concealed" }
|
||||
username { name -> buildProperties.isTeamcityBuild ? "TeamCity" : "concealed" }
|
||||
username { name -> isTeamCity ? "TeamCity" : "concealed" }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user