[IC] Implement compiler outputs backup logic
#KT-49785 In Progress
This commit is contained in:
committed by
Space Team
parent
3806105821
commit
1a5d2a7b7e
+42
-4
@@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user