[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.nio.file.Files
import java.nio.file.Path
import java.nio.file.StandardCopyOption
interface CompilationTransaction : Closeable {
fun registerAddedOrChangedFile(outputFile: Path)
@@ -28,7 +29,9 @@ class DummyCompilationTransaction : CompilationTransaction {
}
override fun deleteFile(outputFile: Path) {
Files.delete(outputFile)
if (Files.exists(outputFile)) {
Files.delete(outputFile)
}
}
override fun markAsSuccessful() {
@@ -45,19 +48,53 @@ class RecoverableCompilationTransaction(
private val reporter: BuildReporter,
private val stashDir: Path,
) : CompilationTransaction {
private val fileRelocationRegistry = hashMapOf<Path, Path?>()
private var filesCounter = 0
private var successful = false
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) {
reporter.warn { "Deleting $outputFile" }
Files.delete(outputFile)
if (fileRelocationIsAlreadyRegisteredFor(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() {
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() {
@@ -77,6 +114,7 @@ class RecoverableCompilationTransaction(
cleanupStash()
} else {
revertChanges()
cleanupStash()
}
}
}