Refactor version checking

This commit is contained in:
Alexey Tsvetkov
2016-08-10 19:13:48 +03:00
parent eea01f468b
commit 4ceec37bfe
4 changed files with 27 additions and 21 deletions
@@ -66,6 +66,14 @@ abstract class AbstractKotlinCompile<T : CommonCompilerArguments>() : AbstractCo
// indicates that task should compile kotlin incrementally if possible // indicates that task should compile kotlin incrementally if possible
// it's not possible when IncrementalTaskInputs#isIncremental returns false (i.e first build) // it's not possible when IncrementalTaskInputs#isIncremental returns false (i.e first build)
var incremental: Boolean = false var incremental: Boolean = false
get() = field
set(value) {
field = value
logger.kotlinDebug { "Set $this.incremental=$value" }
System.setProperty("kotlin.incremental.compilation", value.toString())
System.setProperty("kotlin.incremental.compilation.experimental", value.toString())
}
var kotlinOptions: T = createBlankArgs() var kotlinOptions: T = createBlankArgs()
var compilerCalled: Boolean = false var compilerCalled: Boolean = false
// TODO: consider more reliable approach (see usage) // TODO: consider more reliable approach (see usage)
@@ -152,6 +160,9 @@ open class KotlinCompile() : AbstractKotlinCompile<K2JVMCompilerArguments>() {
dataContainerCacheVersion(taskBuildDirectory), dataContainerCacheVersion(taskBuildDirectory),
gradleCacheVersion(taskBuildDirectory)) gradleCacheVersion(taskBuildDirectory))
} }
val isCacheFormatUpToDate: Boolean by lazy {
cacheVersions.all { it.checkVersion() == CacheVersion.Action.DO_NOTHING }
}
private var kaptAnnotationsFileUpdater: AnnotationFileUpdater? = null private var kaptAnnotationsFileUpdater: AnnotationFileUpdater? = null
private val additionalClasspath = arrayListOf<File>() private val additionalClasspath = arrayListOf<File>()
@@ -301,7 +312,6 @@ open class KotlinCompile() : AbstractKotlinCompile<K2JVMCompilerArguments>() {
// so far considering it not incremental TODO: store java files in the cache and extract removed symbols from it here // so far considering it not incremental TODO: store java files in the cache and extract removed symbols from it here
|| removed.any { it.isJavaFile() || it.hasClassFileExtension() } || removed.any { it.isJavaFile() || it.hasClassFileExtension() }
|| modified.any { it.hasClassFileExtension() } || modified.any { it.hasClassFileExtension() }
|| cacheVersions.any { it.checkVersion() != CacheVersion.Action.DO_NOTHING }
) { ) {
logger.kotlinInfo(if (!isIncrementalRequested) "clean caches on rebuild" else "classpath changed, rebuilding all kotlin files") logger.kotlinInfo(if (!isIncrementalRequested) "clean caches on rebuild" else "classpath changed, rebuilding all kotlin files")
targets.forEach { getIncrementalCache(it).clean() } targets.forEach { getIncrementalCache(it).clean() }
@@ -343,7 +353,10 @@ open class KotlinCompile() : AbstractKotlinCompile<K2JVMCompilerArguments>() {
ExitCode.COMPILATION_ERROR -> throw GradleException("Compilation error. See log for more details") ExitCode.COMPILATION_ERROR -> throw GradleException("Compilation error. See log for more details")
ExitCode.INTERNAL_ERROR -> throw GradleException("Internal compiler error. See log for more details") ExitCode.INTERNAL_ERROR -> throw GradleException("Internal compiler error. See log for more details")
ExitCode.SCRIPT_EXECUTION_ERROR -> throw GradleException("Script execution error. See log for more details") ExitCode.SCRIPT_EXECUTION_ERROR -> throw GradleException("Script execution error. See log for more details")
ExitCode.OK -> logger.kotlinInfo("Compilation succeeded") ExitCode.OK -> {
cacheVersions.forEach { it.saveIfNeeded() }
logger.kotlinInfo("Compilation succeeded")
}
} }
} }
@@ -405,7 +418,6 @@ open class KotlinCompile() : AbstractKotlinCompile<K2JVMCompilerArguments>() {
getIncrementalCache = { caches[it]!! }) getIncrementalCache = { caches[it]!! })
lookupStorage.update(lookupTracker, sourcesToCompile, currentRemoved) lookupStorage.update(lookupTracker, sourcesToCompile, currentRemoved)
cacheVersions.forEach { it.saveIfNeeded() }
if (!isIncrementalDecided) break if (!isIncrementalDecided) break
@@ -1,10 +1,11 @@
package org.jetbrains.kotlin.gradle.plugin package org.jetbrains.kotlin.gradle.plugin
import org.gradle.api.Project import org.gradle.api.Project
import org.gradle.api.tasks.compile.AbstractCompile import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import java.util.* import java.util.*
import kotlin.reflect.KMutableProperty1
fun mapKotlinTaskProperties(project: Project, task: AbstractCompile) { fun mapKotlinTaskProperties(project: Project, task: KotlinCompile) {
propertyMappings.forEach { it.apply(project, task) } propertyMappings.forEach { it.apply(project, task) }
val localPropertiesFile = project.rootProject.file("local.properties") val localPropertiesFile = project.rootProject.file("local.properties")
@@ -16,28 +17,28 @@ fun mapKotlinTaskProperties(project: Project, task: AbstractCompile) {
} }
private val propertyMappings = listOf( private val propertyMappings = listOf(
KotlinPropertyMapping("kotlin.incremental", "incremental", String::toBoolean) KotlinPropertyMapping("kotlin.incremental", KotlinCompile::incremental, String::toBoolean)
) )
private class KotlinPropertyMapping<T>( private class KotlinPropertyMapping<T>(
private val projectPropName: String, private val projectPropName: String,
private val taskPropName: String, private val taskProperty: KMutableProperty1<KotlinCompile, T>,
private val transform: (String) -> T private val transform: (String) -> T
) { ) {
fun apply(project: Project, task: AbstractCompile) { fun apply(project: Project, task: KotlinCompile) {
if (!project.hasProperty(projectPropName)) return if (!project.hasProperty(projectPropName)) return
setPropertyValue(task, project.property(projectPropName)) setPropertyValue(task, project.property(projectPropName))
} }
fun apply(properties: Properties, task: AbstractCompile) { fun apply(properties: Properties, task: KotlinCompile) {
setPropertyValue(task, properties.getProperty(projectPropName)) setPropertyValue(task, properties.getProperty(projectPropName))
} }
private fun setPropertyValue(task: AbstractCompile, value: Any?) { private fun setPropertyValue(task: KotlinCompile, value: Any?) {
if (value !is String) return if (value !is String) return
val transformedValue = transform(value) ?: return val transformedValue = transform(value) ?: return
task.setProperty(taskPropName, transformedValue) taskProperty.set(task, transformedValue)
} }
} }
@@ -10,6 +10,7 @@ open class KotlinTasksProvider {
return project.tasks.create(name, KotlinCompile::class.java).apply { return project.tasks.create(name, KotlinCompile::class.java).apply {
friendTaskName = taskToFriendTaskMapper[this] friendTaskName = taskToFriendTaskMapper[this]
mapKotlinTaskProperties(project, this) mapKotlinTaskProperties(project, this)
outputs.upToDateWhen { isCacheFormatUpToDate }
} }
} }
@@ -1,7 +1,5 @@
package org.jetbrains.kotlin.gradle package org.jetbrains.kotlin.gradle
import org.jetbrains.kotlin.gradle.util.getFileByName
import org.jetbrains.kotlin.gradle.util.modify
import org.junit.Test import org.junit.Test
import java.io.File import java.io.File
import kotlin.test.assertNotEquals import kotlin.test.assertNotEquals
@@ -43,25 +41,19 @@ class CacheVersionChangedIT : BaseGradleIT() {
val modifiedVersion = "777" val modifiedVersion = "777"
versionFile.writeText(modifiedVersion) versionFile.writeText(modifiedVersion)
// gradle won't call kotlin task if no file is changed
val dummyKtFile = project.projectDir.getFileByName("Dummy.kt")
dummyKtFile.modify { it + " " }
project.build("build", options = options) { project.build("build", options = options) {
assertSuccessful() assertSuccessful()
assertNotEquals(modifiedVersion, versionFile.readText(), "${versionFile.projectPath()} was not rewritten by build") assertNotEquals(modifiedVersion, versionFile.readText(), "${versionFile.projectPath()} was not rewritten by build")
val mainDir = File(project.projectDir, "src/main") val mainDir = File(project.projectDir, "src/main")
val mainKotlinFiles = mainDir.walk().filter { it.isFile && it.extension.equals("kt", ignoreCase = true) } val mainKotlinFiles = mainDir.walk().filter { it.isFile && it.extension.equals("kt", ignoreCase = true) }
val mainKotlinRelativePaths = mainKotlinFiles.map { it.projectPath() }.toList() val mainKotlinRelativePaths = mainKotlinFiles.map(File::projectPath).toList()
assertCompiledKotlinSources(mainKotlinRelativePaths) assertCompiledKotlinSources(mainKotlinRelativePaths)
} }
dummyKtFile.modify { it + " " }
project.build("build", options = options) { project.build("build", options = options) {
assertSuccessful() assertSuccessful()
assertCompiledKotlinSources(listOf(dummyKtFile.projectPath())) assertCompiledKotlinSources(listOf(), weakTesting = false)
} }
} }
} }