[Build] Fix configuration cache issues (part 3)
* Make IntelliJInstrumentCodeTask compatible with configuration cache * Make CoreXmlShadingTransformer compatible with configuration cache * Make :kotlin-reflect:relocateCoreSources 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:
@@ -21,12 +21,14 @@ import org.gradle.api.artifacts.Configuration
|
|||||||
import org.gradle.api.artifacts.ProjectDependency
|
import org.gradle.api.artifacts.ProjectDependency
|
||||||
import org.gradle.api.file.ConfigurableFileCollection
|
import org.gradle.api.file.ConfigurableFileCollection
|
||||||
import org.gradle.api.file.FileCollection
|
import org.gradle.api.file.FileCollection
|
||||||
|
import org.gradle.api.file.FileSystemOperations
|
||||||
import org.gradle.api.internal.ConventionTask
|
import org.gradle.api.internal.ConventionTask
|
||||||
import org.gradle.api.plugins.ExtensionAware
|
import org.gradle.api.plugins.ExtensionAware
|
||||||
import org.gradle.api.tasks.*
|
import org.gradle.api.tasks.*
|
||||||
import org.gradle.api.tasks.compile.AbstractCompile
|
import org.gradle.api.tasks.compile.AbstractCompile
|
||||||
import org.gradle.kotlin.dsl.*
|
import org.gradle.kotlin.dsl.*
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
fun Project.configureFormInstrumentation() {
|
fun Project.configureFormInstrumentation() {
|
||||||
plugins.matching { it::class.java.canonicalName.startsWith("org.jetbrains.kotlin.gradle.plugin") }.all {
|
plugins.matching { it::class.java.canonicalName.startsWith("org.jetbrains.kotlin.gradle.plugin") }.all {
|
||||||
@@ -76,7 +78,7 @@ fun Project.configureFormInstrumentation() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
afterEvaluate {
|
afterEvaluate {
|
||||||
sourceSets.all { sourceSetParam ->
|
sourceSets.forEach { sourceSetParam ->
|
||||||
// This copy will ignore filters, but they are unlikely to be used.
|
// This copy will ignore filters, but they are unlikely to be used.
|
||||||
val classesDirs = (sourceSetParam.output.classesDirs as ConfigurableFileCollection).from as Collection<Any>
|
val classesDirs = (sourceSetParam.output.classesDirs as ConfigurableFileCollection).from as Collection<Any>
|
||||||
|
|
||||||
@@ -88,7 +90,7 @@ fun Project.configureFormInstrumentation() {
|
|||||||
(sourceSetParam.output.classesDirs as ConfigurableFileCollection).setFrom(instrumentedClassesDir)
|
(sourceSetParam.output.classesDirs as ConfigurableFileCollection).setFrom(instrumentedClassesDir)
|
||||||
val instrumentTask =
|
val instrumentTask =
|
||||||
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)
|
||||||
sourceSet = sourceSetParam
|
sourceSet = sourceSetParam
|
||||||
instrumentationClasspathConfiguration = instrumentationClasspathCfg
|
instrumentationClasspathConfiguration = instrumentationClasspathCfg
|
||||||
originalClassesDirs = classesDirsCopy
|
originalClassesDirs = classesDirsCopy
|
||||||
@@ -98,14 +100,12 @@ fun Project.configureFormInstrumentation() {
|
|||||||
|
|
||||||
// Ensure that our task is invoked when the source set is built
|
// Ensure that our task is invoked when the source set is built
|
||||||
sourceSetParam.compiledBy(instrumentTask)
|
sourceSetParam.compiledBy(instrumentTask)
|
||||||
@Suppress("UNUSED_EXPRESSION")
|
|
||||||
true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@CacheableTask
|
@CacheableTask
|
||||||
open class IntelliJInstrumentCodeTask : ConventionTask() {
|
abstract class IntelliJInstrumentCodeTask : ConventionTask() {
|
||||||
companion object {
|
companion object {
|
||||||
private const val FILTER_ANNOTATION_REGEXP_CLASS = "com.intellij.ant.ClassFilterAnnotationRegexp"
|
private const val FILTER_ANNOTATION_REGEXP_CLASS = "com.intellij.ant.ClassFilterAnnotationRegexp"
|
||||||
private const val LOADER_REF = "java2.loader"
|
private const val LOADER_REF = "java2.loader"
|
||||||
@@ -122,7 +122,8 @@ open class IntelliJInstrumentCodeTask : ConventionTask() {
|
|||||||
|
|
||||||
@InputFiles
|
@InputFiles
|
||||||
@PathSensitive(PathSensitivity.RELATIVE)
|
@PathSensitive(PathSensitivity.RELATIVE)
|
||||||
var originalClassesDirs: FileCollection? = null
|
@SkipWhenEmpty
|
||||||
|
lateinit var originalClassesDirs: FileCollection
|
||||||
|
|
||||||
@get:Input
|
@get:Input
|
||||||
var instrumentNotNull: Boolean = false
|
var instrumentNotNull: Boolean = false
|
||||||
@@ -135,6 +136,12 @@ open class IntelliJInstrumentCodeTask : ConventionTask() {
|
|||||||
sourceSet.compileClasspath
|
sourceSet.compileClasspath
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Instrumentation needs to have access to sources of forms for inclusion
|
||||||
|
private val depSourceDirectorySets by lazy {
|
||||||
|
project.configurations["compile"].dependencies.withType(ProjectDependency::class.java)
|
||||||
|
.map { p -> p.dependencyProject.mainSourceSet.allSource.sourceDirectories }
|
||||||
|
}
|
||||||
|
|
||||||
@get:InputFiles
|
@get:InputFiles
|
||||||
@get:PathSensitive(PathSensitivity.RELATIVE)
|
@get:PathSensitive(PathSensitivity.RELATIVE)
|
||||||
val sourceDirs: FileCollection by lazy {
|
val sourceDirs: FileCollection by lazy {
|
||||||
@@ -144,10 +151,13 @@ open class IntelliJInstrumentCodeTask : ConventionTask() {
|
|||||||
@get:OutputDirectory
|
@get:OutputDirectory
|
||||||
lateinit var output: File
|
lateinit var output: File
|
||||||
|
|
||||||
|
@get:Inject
|
||||||
|
abstract val fs: FileSystemOperations
|
||||||
|
|
||||||
@TaskAction
|
@TaskAction
|
||||||
fun instrumentClasses() {
|
fun instrumentClasses() {
|
||||||
logger.info(
|
logger.info(
|
||||||
"input files are: ${originalClassesDirs?.joinToString(
|
"input files are: ${originalClassesDirs.joinToString(
|
||||||
"; ",
|
"; ",
|
||||||
transform = { "'${it.name}'${if (it.exists()) "" else " (does not exists)"}" })}"
|
transform = { "'${it.name}'${if (it.exists()) "" else " (does not exists)"}" })}"
|
||||||
)
|
)
|
||||||
@@ -174,7 +184,7 @@ open class IntelliJInstrumentCodeTask : ConventionTask() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun copyOriginalClasses() {
|
private fun copyOriginalClasses() {
|
||||||
project.copy {
|
fs.copy {
|
||||||
from(originalClassesDirs)
|
from(originalClassesDirs)
|
||||||
into(output)
|
into(output)
|
||||||
}
|
}
|
||||||
@@ -194,9 +204,6 @@ open class IntelliJInstrumentCodeTask : ConventionTask() {
|
|||||||
private fun instrumentCode(srcDirs: FileCollection, instrumentNotNull: Boolean) {
|
private fun instrumentCode(srcDirs: FileCollection, instrumentNotNull: Boolean) {
|
||||||
val headlessOldValue = System.setProperty("java.awt.headless", "true")
|
val headlessOldValue = System.setProperty("java.awt.headless", "true")
|
||||||
|
|
||||||
// Instrumentation needs to have access to sources of forms for inclusion
|
|
||||||
val depSourceDirectorySets = project.configurations["compile"].dependencies.withType(ProjectDependency::class.java)
|
|
||||||
.map { p -> p.dependencyProject.mainSourceSet.allSource.sourceDirectories }
|
|
||||||
val instrumentationClasspath =
|
val instrumentationClasspath =
|
||||||
depSourceDirectorySets.fold(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")
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import com.github.jengelman.gradle.plugins.shadow.transformers.Transformer
|
|||||||
import com.github.jengelman.gradle.plugins.shadow.transformers.TransformerContext
|
import com.github.jengelman.gradle.plugins.shadow.transformers.TransformerContext
|
||||||
import kotlinx.metadata.jvm.KmModuleVisitor
|
import kotlinx.metadata.jvm.KmModuleVisitor
|
||||||
import kotlinx.metadata.jvm.KotlinModuleMetadata
|
import kotlinx.metadata.jvm.KotlinModuleMetadata
|
||||||
|
import org.gradle.kotlin.dsl.support.serviceOf
|
||||||
import shadow.org.apache.tools.zip.ZipEntry
|
import shadow.org.apache.tools.zip.ZipEntry
|
||||||
import shadow.org.apache.tools.zip.ZipOutputStream
|
import shadow.org.apache.tools.zip.ZipOutputStream
|
||||||
|
|
||||||
@@ -157,8 +158,12 @@ val proguard by task<CacheableProguardTask> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val relocateCoreSources by task<Copy> {
|
val relocateCoreSources by task<Copy> {
|
||||||
|
val relocatedCoreSrc = relocatedCoreSrc
|
||||||
|
val fs = serviceOf<FileSystemOperations>()
|
||||||
doFirst {
|
doFirst {
|
||||||
delete(relocatedCoreSrc)
|
fs.delete {
|
||||||
|
delete(relocatedCoreSrc)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
from("$core/descriptors/src")
|
from("$core/descriptors/src")
|
||||||
|
|||||||
@@ -76,6 +76,9 @@ val jsMainSources by task<Sync> {
|
|||||||
|
|
||||||
into("$buildDir/jsMainSources")
|
into("$buildDir/jsMainSources")
|
||||||
|
|
||||||
|
val unimplementedNativeBuiltIns = unimplementedNativeBuiltIns
|
||||||
|
val buildDir = buildDir
|
||||||
|
val builtInsHeader = builtInsHeader
|
||||||
doLast {
|
doLast {
|
||||||
unimplementedNativeBuiltIns.forEach { path ->
|
unimplementedNativeBuiltIns.forEach { path ->
|
||||||
val file = File("$buildDir/jsMainSources/$path")
|
val file = File("$buildDir/jsMainSources/$path")
|
||||||
|
|||||||
@@ -50,25 +50,34 @@ class CoreXmlShadingTransformer : Transformer {
|
|||||||
private const val XML_NAME = "META-INF/extensions/core.xml"
|
private const val XML_NAME = "META-INF/extensions/core.xml"
|
||||||
}
|
}
|
||||||
|
|
||||||
private val content = StringBuilder()
|
@kotlin.jvm.Transient
|
||||||
|
private var content: StringBuilder? = StringBuilder()
|
||||||
|
|
||||||
|
private fun ensureStringBuilderExist() {
|
||||||
|
if (content == null) {
|
||||||
|
content = StringBuilder()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun canTransformResource(element: FileTreeElement): Boolean {
|
override fun canTransformResource(element: FileTreeElement): Boolean {
|
||||||
return (element.name == XML_NAME)
|
return (element.name == XML_NAME)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun transform(context: TransformerContext) {
|
override fun transform(context: TransformerContext) {
|
||||||
|
ensureStringBuilderExist()
|
||||||
val text = context.`is`.bufferedReader().lines()
|
val text = context.`is`.bufferedReader().lines()
|
||||||
.map { it.replace("com.intellij.psi", "org.jetbrains.kotlin.com.intellij.psi") }
|
.map { it.replace("com.intellij.psi", "org.jetbrains.kotlin.com.intellij.psi") }
|
||||||
.collect(Collectors.joining("\n"))
|
.collect(Collectors.joining("\n"))
|
||||||
content.appendln(text)
|
content!!.appendln(text)
|
||||||
context.`is`.close()
|
context.`is`.close()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun hasTransformedResource(): Boolean {
|
override fun hasTransformedResource(): Boolean {
|
||||||
return content.isNotEmpty()
|
return content?.isNotEmpty() ?: false
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun modifyOutputStream(outputStream: ZipOutputStream, preserveFileTimestamps: Boolean) {
|
override fun modifyOutputStream(outputStream: ZipOutputStream, preserveFileTimestamps: Boolean) {
|
||||||
|
if (content == null) return
|
||||||
val entry = ZipEntry(XML_NAME)
|
val entry = ZipEntry(XML_NAME)
|
||||||
outputStream.putNextEntry(entry)
|
outputStream.putNextEntry(entry)
|
||||||
outputStream.write(content.toString().toByteArray())
|
outputStream.write(content.toString().toByteArray())
|
||||||
|
|||||||
@@ -13,6 +13,9 @@ val markdownVersion = findProperty("versions.markdown").toString()
|
|||||||
|
|
||||||
val writeVersions by tasks.registering {
|
val writeVersions by tasks.registering {
|
||||||
val versionFile = File(versionFilePath)
|
val versionFile = File(versionFilePath)
|
||||||
|
val ideaVersion = ideaVersion
|
||||||
|
val markdownVersion = markdownVersion
|
||||||
|
|
||||||
inputs.property("ideaVersion", ideaVersion)
|
inputs.property("ideaVersion", ideaVersion)
|
||||||
inputs.property("markdownVersion", markdownVersion)
|
inputs.property("markdownVersion", markdownVersion)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user