[IC] Implement compiler outputs backup logic

#KT-49785 In Progress
This commit is contained in:
Alexander Likhachev
2022-11-17 17:07:14 +01:00
committed by Space Team
parent 3806105821
commit 1a5d2a7b7e
@@ -13,6 +13,7 @@ import java.io.Closeable
import java.io.File import java.io.File
import java.nio.file.Files import java.nio.file.Files
import java.nio.file.Path import java.nio.file.Path
import java.nio.file.StandardCopyOption
interface CompilationTransaction : Closeable { interface CompilationTransaction : Closeable {
fun registerAddedOrChangedFile(outputFile: Path) fun registerAddedOrChangedFile(outputFile: Path)
@@ -28,7 +29,9 @@ class DummyCompilationTransaction : CompilationTransaction {
} }
override fun deleteFile(outputFile: Path) { override fun deleteFile(outputFile: Path) {
Files.delete(outputFile) if (Files.exists(outputFile)) {
Files.delete(outputFile)
}
} }
override fun markAsSuccessful() { override fun markAsSuccessful() {
@@ -45,19 +48,53 @@ class RecoverableCompilationTransaction(
private val reporter: BuildReporter, private val reporter: BuildReporter,
private val stashDir: Path, private val stashDir: Path,
) : CompilationTransaction { ) : CompilationTransaction {
private val fileRelocationRegistry = hashMapOf<Path, Path?>()
private var filesCounter = 0
private var successful = false private var successful = false
override fun registerAddedOrChangedFile(outputFile: Path) { override fun registerAddedOrChangedFile(outputFile: Path) {
reporter.warn { "$outputFile is being added or changed" } if (fileRelocationIsAlreadyRegisteredFor(outputFile)) return
if (Files.exists(outputFile)) {
stashFile(outputFile)
} else {
reporter.warn { "Marking the $outputFile file as newly added" }
fileRelocationRegistry[outputFile] = null
}
} }
override fun deleteFile(outputFile: Path) { override fun deleteFile(outputFile: Path) {
reporter.warn { "Deleting $outputFile" } if (fileRelocationIsAlreadyRegisteredFor(outputFile)) {
Files.delete(outputFile) reporter.warn { "Deleting $outputFile" }
if (Files.exists(outputFile)) {
Files.delete(outputFile)
}
return
}
stashFile(outputFile)
} }
private fun stashFile(outputFile: Path) {
val relocatedFilePath = getNextRelocatedFilePath()
reporter.warn { "Moving $outputFile to the stash as $relocatedFilePath" }
fileRelocationRegistry[outputFile] = relocatedFilePath
Files.move(outputFile, relocatedFilePath)
}
private fun getNextRelocatedFilePath(): Path = stashDir.resolve("$filesCounter.backup").also { filesCounter++ }
private fun fileRelocationIsAlreadyRegisteredFor(outputFile: Path) = outputFile in fileRelocationRegistry
private fun revertChanges() { private fun revertChanges() {
reporter.warn { "Reverting changes" } reporter.warn { "Reverting changes" }
for ((originPath, relocatedPath) in fileRelocationRegistry) {
if (relocatedPath == null) {
if (Files.exists(originPath)) {
Files.delete(originPath)
}
continue
}
Files.move(relocatedPath, originPath, StandardCopyOption.REPLACE_EXISTING)
}
} }
private fun cleanupStash() { private fun cleanupStash() {
@@ -77,6 +114,7 @@ class RecoverableCompilationTransaction(
cleanupStash() cleanupStash()
} else { } else {
revertChanges() revertChanges()
cleanupStash()
} }
} }
} }