Track changes for jar files for non-Android Gradle projects

This commit is contained in:
Alexey Tsvetkov
2018-05-16 23:34:43 +03:00
parent 61e330fa57
commit e5cdc64f4f
7 changed files with 119 additions and 33 deletions
@@ -25,14 +25,14 @@ internal open class GradleCompilerEnvironment(
}
internal class GradleIncrementalCompilerEnvironment(
compilerClasspath: List<File>,
val changedFiles: ChangedFiles,
val workingDir: File,
messageCollector: GradleMessageCollector,
outputItemsCollector: OutputItemsCollector,
compilerArgs: CommonCompilerArguments,
val buildHistoryFile: File,
val kaptAnnotationsFileUpdater: AnnotationFileUpdater? = null,
val usePreciseJavaTracking: Boolean = false,
val localStateDirs: List<File> = emptyList()
compilerClasspath: List<File>,
val changedFiles: ChangedFiles,
val workingDir: File,
messageCollector: GradleMessageCollector,
outputItemsCollector: OutputItemsCollector,
compilerArgs: CommonCompilerArguments,
val buildHistoryFile: File,
val kaptAnnotationsFileUpdater: AnnotationFileUpdater? = null,
val usePreciseJavaTracking: Boolean = false,
val localStateDirs: List<File> = emptyList()
) : GradleCompilerEnvironment(compilerClasspath, messageCollector, outputItemsCollector, compilerArgs)
@@ -35,6 +35,7 @@ import org.jetbrains.kotlin.daemon.common.*
import org.jetbrains.kotlin.daemon.common.IncrementalModuleEntry
import org.jetbrains.kotlin.daemon.common.IncrementalModuleInfo
import org.jetbrains.kotlin.gradle.plugin.kotlinDebug
import org.jetbrains.kotlin.gradle.tasks.InspectClassesForMultiModuleIC
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import org.jetbrains.kotlin.incremental.*
import java.io.ByteArrayOutputStream
@@ -356,17 +357,25 @@ internal class GradleCompilerRunner(private val project: Project) : KotlinCompil
val dirToModule = HashMap<File, IncrementalModuleEntry>()
val nameToModules = HashMap<String, HashSet<IncrementalModuleEntry>>()
val jarToClassListFile = HashMap<File, File>()
for (project in gradle.rootProject.allprojects) {
for (task in project.tasks.withType(KotlinCompile::class.java)) {
val module = IncrementalModuleEntry(project.path, task.moduleName, project.buildDir, task.buildHistoryFile)
dirToModule[task.destinationDir] = module
task.javaOutputDir?.let { dirToModule[it] = module }
nameToModules.getOrPut(module.name) { HashSet() }.add(module)
for (task in project.tasks) {
when (task) {
is KotlinCompile -> {
val module = IncrementalModuleEntry(project.path, task.moduleName, project.buildDir, task.buildHistoryFile)
dirToModule[task.destinationDir] = module
task.javaOutputDir?.let { dirToModule[it] = module }
nameToModules.getOrPut(module.name) { HashSet() }.add(module)
}
is InspectClassesForMultiModuleIC -> {
jarToClassListFile[File(task.archivePath)] = task.classesListFile
}
}
}
}
return IncrementalModuleInfo(gradle.rootProject.projectDir, dirToModule, nameToModules)
return IncrementalModuleInfo(gradle.rootProject.projectDir, dirToModule, nameToModules, jarToClassListFile)
.also {
cachedGradle = WeakReference(gradle)
cachedModulesInfo = it
@@ -23,6 +23,7 @@ import org.gradle.api.plugins.JavaPluginConvention
import org.gradle.api.tasks.*
import org.gradle.api.tasks.compile.AbstractCompile
import org.gradle.api.tasks.compile.JavaCompile
import org.gradle.jvm.tasks.Jar
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptionsImpl
import org.jetbrains.kotlin.gradle.internal.*
@@ -358,6 +359,7 @@ internal abstract class AbstractKotlinPlugin(
configureSourceSetDefaults(project, javaBasePlugin, javaPluginConvention)
configureDefaultVersionsResolutionStrategy(project)
configureClassInspectionForIC(project)
}
open protected fun configureSourceSetDefaults(
@@ -390,6 +392,24 @@ internal abstract class AbstractKotlinPlugin(
}
}
}
private fun configureClassInspectionForIC(project: Project) {
val classesTask = project.tasks.findByName(JavaPlugin.CLASSES_TASK_NAME)
val jarTask = project.tasks.findByName(JavaPlugin.JAR_TASK_NAME)
if (classesTask == null || jarTask !is Jar) {
project.logger.info(
"Could not configure class inspection task " +
"(classes task = ${classesTask?.javaClass?.canonicalName}, " +
"jar task = ${classesTask?.javaClass?.canonicalName}"
)
return
}
val inspectTask = project.tasks.create("inspectClassesForKotlinIC", InspectClassesForMultiModuleIC::class.java)
inspectTask.jarTask = jarTask
inspectTask.dependsOn(classesTask)
jarTask.dependsOn(inspectTask)
}
}
internal open class KotlinPlugin(
@@ -0,0 +1,44 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.gradle.tasks
import org.gradle.api.DefaultTask
import org.gradle.api.file.FileCollection
import org.gradle.api.tasks.*
import org.gradle.jvm.tasks.Jar
import org.jetbrains.kotlin.gradle.utils.inputsCompatible
import org.jetbrains.kotlin.incremental.isClassFile
import java.io.File
internal open class InspectClassesForMultiModuleIC : DefaultTask() {
@get:Internal
lateinit var jarTask: Jar
@Suppress("MemberVisibilityCanBePrivate")
@get:OutputFile
internal val classesListFile: File
get() = File(File(project.buildDir, KOTLIN_BUILD_DIR_NAME), "${sanitizeFileName(jarTask.archiveName)}-classes.txt")
@Suppress("MemberVisibilityCanBePrivate")
@get:InputFiles
internal val classFiles: FileCollection
get() = jarTask.inputsCompatible.files.filter { it.isClassFile() }
@get:Input
internal val archivePath: String
get() = jarTask.archivePath.canonicalPath
@TaskAction
fun run() {
classesListFile.parentFile.mkdirs()
val paths = classFiles.map { it.canonicalPath }.sorted()
val text = paths.joinToString(File.pathSeparator)
classesListFile.writeText(text)
}
private fun sanitizeFileName(candidate: String): String =
candidate.filter { it.isLetterOrDigit() }
}