[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") {
|
tasks.matching { it is Zip && it.name == "mainBenchmarkJar" }.configureEach {
|
||||||
doLast {
|
this as Zip
|
||||||
tasks.named("mainBenchmarkJar", Zip::class.java) {
|
isZip64 = true
|
||||||
isZip64 = true
|
archiveFileName.set("benchmarks.jar")
|
||||||
archiveName = "benchmarks.jar"
|
}
|
||||||
}
|
|
||||||
listOf("mainBenchmark", "mainFirBenchmark", "mainNiBenchmark").forEach {
|
val benchmarkTasks = listOf("mainBenchmark", "mainFirBenchmark", "mainNiBenchmark")
|
||||||
tasks.named(it, JavaExec::class.java) {
|
tasks.matching { it is JavaExec && it.name in benchmarkTasks }.configureEach {
|
||||||
systemProperty("idea.home.path", intellijRootDir().canonicalPath)
|
this as JavaExec
|
||||||
}
|
systemProperty("idea.home.path", intellijRootDir().canonicalPath)
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.register<JavaExec>("runBenchmark") {
|
tasks.register<JavaExec>("runBenchmark") {
|
||||||
|
|||||||
+4
-9
@@ -621,17 +621,12 @@ val ideaPlugin by task<Task> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
tasks {
|
tasks {
|
||||||
named("clean") {
|
named<Delete>("clean") {
|
||||||
doLast {
|
delete += setOf("$buildDir/repo", distDir)
|
||||||
delete("$buildDir/repo")
|
|
||||||
delete(distDir)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
register("cleanupArtifacts") {
|
register<Delete>("cleanupArtifacts") {
|
||||||
doLast {
|
delete = setOf(artifactsDir)
|
||||||
delete(artifactsDir)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
listOf("clean", "assemble", "install").forEach { taskName ->
|
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) {
|
project.tasks.register(sourceSetParam.getTaskName("instrument", "classes"), IntelliJInstrumentCodeTask::class.java) {
|
||||||
dependsOn(sourceSetParam.classesTaskName).onlyIf { !classesDirsCopy.isEmpty }
|
dependsOn(sourceSetParam.classesTaskName).onlyIf { !classesDirsCopy.isEmpty }
|
||||||
sourceSet = sourceSetParam
|
sourceSet = sourceSetParam
|
||||||
instrumentationClasspath = instrumentationClasspathCfg
|
instrumentationClasspathConfiguration = instrumentationClasspathCfg
|
||||||
originalClassesDirs = classesDirsCopy
|
originalClassesDirs = classesDirsCopy
|
||||||
output = instrumentedClassesDir
|
output = instrumentedClassesDir
|
||||||
outputs.dir(instrumentedClassesDir)
|
outputs.dir(instrumentedClassesDir)
|
||||||
@@ -111,8 +111,14 @@ open class IntelliJInstrumentCodeTask : ConventionTask() {
|
|||||||
private const val LOADER_REF = "java2.loader"
|
private const val LOADER_REF = "java2.loader"
|
||||||
}
|
}
|
||||||
|
|
||||||
@Classpath
|
@Transient
|
||||||
var instrumentationClasspath: Configuration? = null
|
@Internal
|
||||||
|
lateinit var instrumentationClasspathConfiguration: Configuration
|
||||||
|
|
||||||
|
@get:Classpath
|
||||||
|
val instrumentationClasspath: String by lazy {
|
||||||
|
instrumentationClasspathConfiguration.asPath
|
||||||
|
}
|
||||||
|
|
||||||
@InputFiles
|
@InputFiles
|
||||||
@PathSensitive(PathSensitivity.RELATIVE)
|
@PathSensitive(PathSensitivity.RELATIVE)
|
||||||
@@ -121,13 +127,19 @@ open class IntelliJInstrumentCodeTask : ConventionTask() {
|
|||||||
@get:Input
|
@get:Input
|
||||||
var instrumentNotNull: Boolean = false
|
var instrumentNotNull: Boolean = false
|
||||||
|
|
||||||
|
@Transient
|
||||||
@Internal
|
@Internal
|
||||||
var sourceSet: SourceSet? = null
|
lateinit var sourceSet: SourceSet
|
||||||
|
|
||||||
|
private val compileClasspath by lazy {
|
||||||
|
sourceSet.compileClasspath
|
||||||
|
}
|
||||||
|
|
||||||
@get:InputFiles
|
@get:InputFiles
|
||||||
@get:PathSensitive(PathSensitivity.RELATIVE)
|
@get:PathSensitive(PathSensitivity.RELATIVE)
|
||||||
val sourceDirs: FileCollection
|
val sourceDirs: FileCollection by lazy {
|
||||||
get() = project.files(sourceSet!!.allSource.srcDirs.filter { !sourceSet!!.resources.contains(it) && it.exists() })
|
project.files(sourceSet.allSource.srcDirs.filter { !sourceSet.resources.contains(it) && it.exists() })
|
||||||
|
}
|
||||||
|
|
||||||
@get:OutputDirectory
|
@get:OutputDirectory
|
||||||
lateinit var output: File
|
lateinit var output: File
|
||||||
@@ -142,12 +154,12 @@ open class IntelliJInstrumentCodeTask : ConventionTask() {
|
|||||||
output.deleteRecursively()
|
output.deleteRecursively()
|
||||||
copyOriginalClasses()
|
copyOriginalClasses()
|
||||||
|
|
||||||
val classpath = instrumentationClasspath!!
|
val classpath = instrumentationClasspath
|
||||||
|
|
||||||
ant.withGroovyBuilder {
|
ant.withGroovyBuilder {
|
||||||
"taskdef"(
|
"taskdef"(
|
||||||
"name" to "instrumentIdeaExtensions",
|
"name" to "instrumentIdeaExtensions",
|
||||||
"classpath" to classpath.asPath,
|
"classpath" to classpath,
|
||||||
"loaderref" to LOADER_REF,
|
"loaderref" to LOADER_REF,
|
||||||
"classname" to "com.intellij.ant.InstrumentIdeaExtensions"
|
"classname" to "com.intellij.ant.InstrumentIdeaExtensions"
|
||||||
)
|
)
|
||||||
@@ -155,7 +167,7 @@ open class IntelliJInstrumentCodeTask : ConventionTask() {
|
|||||||
|
|
||||||
logger.info("Compiling forms and instrumenting code with nullability preconditions")
|
logger.info("Compiling forms and instrumenting code with nullability preconditions")
|
||||||
if (instrumentNotNull) {
|
if (instrumentNotNull) {
|
||||||
prepareNotNullInstrumenting(classpath.asPath)
|
prepareNotNullInstrumenting(classpath)
|
||||||
}
|
}
|
||||||
|
|
||||||
instrumentCode(sourceDirs, instrumentNotNull)
|
instrumentCode(sourceDirs, instrumentNotNull)
|
||||||
@@ -186,7 +198,7 @@ open class IntelliJInstrumentCodeTask : ConventionTask() {
|
|||||||
val depSourceDirectorySets = project.configurations["compile"].dependencies.withType(ProjectDependency::class.java)
|
val depSourceDirectorySets = project.configurations["compile"].dependencies.withType(ProjectDependency::class.java)
|
||||||
.map { p -> p.dependencyProject.mainSourceSet.allSource.sourceDirectories }
|
.map { p -> p.dependencyProject.mainSourceSet.allSource.sourceDirectories }
|
||||||
val instrumentationClasspath =
|
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")
|
logger.info("Using following dependency source dirs: $it")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,8 +25,9 @@ tasks.withType<JavaCompile> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
tasks.named<ProcessResources>("processResources") {
|
tasks.named<ProcessResources>("processResources") {
|
||||||
inputs.property("compilerVersion", kotlinVersion)
|
val kotlinVersionLocal = kotlinVersion
|
||||||
|
inputs.property("compilerVersion", kotlinVersionLocal)
|
||||||
filesMatching("META-INF/compiler.version") {
|
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 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 toolsJarStubs by tasks.registering {
|
||||||
|
val toolsJarFile = toolsJarFile(jdkHome = File(JDK_18)) ?: error("Couldn't find tools.jar in $JDK_18")
|
||||||
inputs.file(toolsJarFile)
|
inputs.file(toolsJarFile)
|
||||||
|
|
||||||
val outDir = buildDir.resolve(name)
|
val outDir = buildDir.resolve(name)
|
||||||
outputs.dir(outDir)
|
outputs.dir(outDir)
|
||||||
|
|
||||||
|
val usedInternalApiPackages = listOf(
|
||||||
|
"com/sun/tools/javac" // Used in KAPT
|
||||||
|
)
|
||||||
|
|
||||||
doLast {
|
doLast {
|
||||||
outDir.deleteRecursively()
|
outDir.deleteRecursively()
|
||||||
val zipFile = ZipFile(toolsJarFile)
|
val zipFile = ZipFile(toolsJarFile)
|
||||||
|
|||||||
@@ -24,42 +24,8 @@ fun Project.configureJavaInstrumentation() {
|
|||||||
includeJars("javac2", "jdom", "asm-all", rootProject = rootProject)
|
includeJars("javac2", "jdom", "asm-all", rootProject = rootProject)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (sourceSet in listOf(mainSourceSet, testSourceSet)) {
|
||||||
listOf(mainSourceSet, testSourceSet).forEach { sourceSet ->
|
tasks.named(sourceSet.compileJavaTaskName, InstrumentJava(javaInstrumentator, 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
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -61,10 +61,11 @@ ext.compileJava9Sources = { Project project, String moduleName, Collection<FileC
|
|||||||
it.options.fork = true
|
it.options.fork = true
|
||||||
it.options.forkOptions.javaHome = file(JDK_9)
|
it.options.forkOptions.javaHome = file(JDK_9)
|
||||||
it.options.sourcepath = files(java9SourceSet.srcDirs)
|
it.options.sourcepath = files(java9SourceSet.srcDirs)
|
||||||
|
def compileClasspath = project.configurations.java9CompileClasspath
|
||||||
|
|
||||||
doFirst {
|
doFirst {
|
||||||
def moduleFiles = files(*moduleOutputs)
|
def moduleFiles = files(*moduleOutputs)
|
||||||
def modulePath = project.configurations.java9CompileClasspath.filter { !(it in moduleFiles.files) }
|
def modulePath = compileClasspath.filter { !(it in moduleFiles.files) }
|
||||||
|
|
||||||
options.compilerArgs = [
|
options.compilerArgs = [
|
||||||
'--module-path', modulePath.asPath,
|
'--module-path', modulePath.asPath,
|
||||||
|
|||||||
@@ -21,22 +21,26 @@ artifacts.add(buildVersion.name, file(buildVersionFilePath)) {
|
|||||||
builtBy(writeBuildNumber)
|
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 writeStdlibVersion by tasks.registering {
|
||||||
|
val kotlinVersionLocal = kotlinVersion
|
||||||
val versionFile = rootDir.resolve("libraries/stdlib/src/kotlin/util/KotlinVersion.kt")
|
val versionFile = rootDir.resolve("libraries/stdlib/src/kotlin/util/KotlinVersion.kt")
|
||||||
inputs.property("version", kotlinVersion)
|
inputs.property("version", kotlinVersionLocal)
|
||||||
outputs.file(versionFile)
|
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 {
|
doLast {
|
||||||
replaceVersion(versionFile, """fun get\(\): KotlinVersion = KotlinVersion\((\d+, \d+, \d+)\)""") {
|
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" }"
|
val newVersion = "$major, $minor, ${optPatch.takeIf { it.isNotEmpty() } ?: "0" }"
|
||||||
logger.lifecycle("Writing new standard library version components: $newVersion")
|
logger.lifecycle("Writing new standard library version components: $newVersion")
|
||||||
newVersion
|
newVersion
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ noDefaultJar()
|
|||||||
|
|
||||||
// dummy is used for rewriting dependencies to the shaded packages in the embeddable compiler
|
// dummy is used for rewriting dependencies to the shaded packages in the embeddable compiler
|
||||||
compilerDummyJar(compilerDummyForDependenciesRewriting("compilerDummy") {
|
compilerDummyJar(compilerDummyForDependenciesRewriting("compilerDummy") {
|
||||||
classifier = "dummy"
|
archiveClassifier.set("dummy")
|
||||||
})
|
})
|
||||||
|
|
||||||
class CoreXmlShadingTransformer : Transformer {
|
class CoreXmlShadingTransformer : Transformer {
|
||||||
|
|||||||
+6
-3
@@ -39,9 +39,12 @@ def buildProperties = BuildPropertiesKt.getKotlinBuildPropertiesForSettings(sett
|
|||||||
def projectVersions = file("./gradle/versions.properties").text
|
def projectVersions = file("./gradle/versions.properties").text
|
||||||
|
|
||||||
gradleEnterprise {
|
gradleEnterprise {
|
||||||
|
def buildScanServer = buildProperties.buildScanServer
|
||||||
|
def isTeamCity = buildProperties.isTeamcityBuild
|
||||||
|
|
||||||
buildScan {
|
buildScan {
|
||||||
if (buildProperties.buildScanServer != null) {
|
if (buildScanServer != null) {
|
||||||
server = buildProperties.buildScanServer
|
server = buildScanServer
|
||||||
captureTaskInputFiles = true
|
captureTaskInputFiles = true
|
||||||
publishAlways()
|
publishAlways()
|
||||||
} else {
|
} else {
|
||||||
@@ -52,7 +55,7 @@ gradleEnterprise {
|
|||||||
obfuscation {
|
obfuscation {
|
||||||
ipAddresses { addresses -> ["0.0.0.0"] }
|
ipAddresses { addresses -> ["0.0.0.0"] }
|
||||||
hostname { host -> "concealed" }
|
hostname { host -> "concealed" }
|
||||||
username { name -> buildProperties.isTeamcityBuild ? "TeamCity" : "concealed" }
|
username { name -> isTeamCity ? "TeamCity" : "concealed" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user