Avoid storing absolute paths in SyncOutputTask

#KT-16003 fixed
This commit is contained in:
Alexey Tsvetkov
2017-02-07 15:58:02 +03:00
parent 6e0f3b7f1f
commit 62a15e803b
2 changed files with 50 additions and 15 deletions
@@ -17,6 +17,7 @@
package org.jetbrains.kotlin.gradle package org.jetbrains.kotlin.gradle
import org.gradle.api.logging.LogLevel import org.gradle.api.logging.LogLevel
import org.jetbrains.kotlin.com.intellij.openapi.util.io.FileUtil
import org.jetbrains.kotlin.gradle.tasks.USING_EXPERIMENTAL_INCREMENTAL_MESSAGE import org.jetbrains.kotlin.gradle.tasks.USING_EXPERIMENTAL_INCREMENTAL_MESSAGE
import org.jetbrains.kotlin.gradle.util.getFileByName import org.jetbrains.kotlin.gradle.util.getFileByName
import org.jetbrains.kotlin.gradle.util.getFilesByNames import org.jetbrains.kotlin.gradle.util.getFilesByNames
@@ -48,6 +49,29 @@ class KotlinGradleIT: BaseGradleIT() {
} }
} }
@Test
fun testRunningInDifferentDir() {
val wd0 = workingDir
val wd1 = File(wd0, "subdir").apply { mkdirs() }
workingDir = wd1
val project1 = Project("kotlinJavaProject", "3.3")
project1.build("assemble") {
assertSuccessful()
}
val wd2 = FileUtil.createTempDirectory("testRunningInDifferentDir", null)
wd1.copyRecursively(wd2)
wd1.deleteRecursively()
assert(!wd1.exists())
wd0.setWritable(false)
workingDir = wd2
project1.build("test") {
assertSuccessful()
}
}
@Test @Test
fun testKotlinOnlyCompile() { fun testKotlinOnlyCompile() {
val project = Project("kotlinProject", GRADLE_VERSION) val project = Project("kotlinProject", GRADLE_VERSION)
@@ -16,11 +16,9 @@
package org.jetbrains.kotlin.gradle.tasks package org.jetbrains.kotlin.gradle.tasks
import ch.qos.logback.core.util.FileUtil
import org.gradle.api.DefaultTask import org.gradle.api.DefaultTask
import org.gradle.api.tasks.InputFiles import org.gradle.api.tasks.InputFiles
import org.gradle.api.tasks.OutputDirectory import org.gradle.api.tasks.OutputDirectory
import org.gradle.api.tasks.OutputFiles
import org.gradle.api.tasks.TaskAction import org.gradle.api.tasks.TaskAction
import org.gradle.api.tasks.incremental.IncrementalTaskInputs import org.gradle.api.tasks.incremental.IncrementalTaskInputs
import org.gradle.api.tasks.incremental.InputFileDetails import org.gradle.api.tasks.incremental.InputFileDetails
@@ -70,19 +68,32 @@ internal open class SyncOutputTask : DefaultTask() {
// OutputDirectory needed for task to be incremental // OutputDirectory needed for task to be incremental
@get:OutputDirectory @get:OutputDirectory
val workingDir: File by lazy { val workingDir: File by lazy {
File(kotlinTask.taskBuildDirectory, "sync").apply { mkdirs() } File(kotlinTask.taskBuildDirectory, "sync")
} }
private val timestampsFile: File by lazy { private val timestampsFile: File by lazy {
File(workingDir, TIMESTAMP_FILE_NAME) File(workingDir, TIMESTAMP_FILE_NAME)
} }
private val timestamps: MutableMap<File, Long> by lazy { private val timestamps: MutableMap<File, Long> by lazy {
readTimestamps(timestampsFile) readTimestamps(timestampsFile, javaOutputDir)
} }
@Suppress("unused") init {
@get:OutputFiles outputs.upToDateWhen {
val kotlinClassesInJavaOutputDir: Collection<File> for ((file, ts) in timestamps) {
get() = timestamps.keys if (!file.exists()) {
logger.kotlinDebug { "$file does not exist" }
return@upToDateWhen false
}
if (file.lastModified() != ts) {
logger.kotlinDebug { "$file ts is different" }
return@upToDateWhen false
}
}
return@upToDateWhen true
}
}
@Suppress("unused") @Suppress("unused")
@TaskAction @TaskAction
@@ -98,7 +109,7 @@ internal open class SyncOutputTask : DefaultTask() {
processNonIncrementally() processNonIncrementally()
} }
saveTimestamps(timestampsFile, timestamps) saveTimestamps(timestampsFile, timestamps, javaOutputDir)
} }
private fun processNonIncrementally() { private fun processNonIncrementally() {
@@ -166,24 +177,24 @@ internal open class SyncOutputTask : DefaultTask() {
private val TIMESTAMP_FILE_NAME = "kotlin-files-in-java-timestamps.bin" private val TIMESTAMP_FILE_NAME = "kotlin-files-in-java-timestamps.bin"
private fun readTimestamps(file: File): MutableMap<File, Long> { private fun readTimestamps(tsFile: File, filesBaseDir: File): MutableMap<File, Long> {
val result = HashMap<File, Long>() val result = HashMap<File, Long>()
if (!file.isFile) return result if (!tsFile.isFile) return result
ObjectInputStream(file.inputStream()).use { input -> ObjectInputStream(tsFile.inputStream()).use { input ->
val size = input.readInt() val size = input.readInt()
repeat(size) { repeat(size) {
val path = input.readUTF() val path = input.readUTF()
val timestamp = input.readLong() val timestamp = input.readLong()
result[File(path)] = timestamp result[File(filesBaseDir, path)] = timestamp
} }
} }
return result return result
} }
private fun saveTimestamps(snapshotFile: File, timestamps: Map<File, Long>) { private fun saveTimestamps(snapshotFile: File, timestamps: Map<File, Long>, filesBaseDir: File) {
if (!snapshotFile.exists()) { if (!snapshotFile.exists()) {
snapshotFile.parentFile.mkdirs() snapshotFile.parentFile.mkdirs()
snapshotFile.createNewFile() snapshotFile.createNewFile()
@@ -196,7 +207,7 @@ private fun saveTimestamps(snapshotFile: File, timestamps: Map<File, Long>) {
out.writeInt(timestamps.size) out.writeInt(timestamps.size)
for ((file, timestamp) in timestamps) { for ((file, timestamp) in timestamps) {
out.writeUTF(file.canonicalPath) out.writeUTF(file.relativeTo(filesBaseDir).path)
out.writeLong(timestamp) out.writeLong(timestamp)
} }
} }