Added status update when file system changes (excluding ignored dirs)

This commit is contained in:
Abdelilah El Aissaoui 2021-11-28 03:15:18 +01:00
parent 4abd9e331d
commit ca3a55ce21
3 changed files with 91 additions and 11 deletions

View File

@ -0,0 +1,52 @@
package app.git
import kotlinx.coroutines.flow.flow
import java.io.IOException
import java.nio.file.*
import java.nio.file.StandardWatchEventKinds.*
import java.nio.file.attribute.BasicFileAttributes
import javax.inject.Inject
class FileChangesWatcher @Inject constructor() {
suspend fun watchDirectoryPath(pathStr: String, ignoredDirsPath: List<String>) = flow {
val watchService = FileSystems.getDefault().newWatchService()
val path = Paths.get(pathStr)
path.register(
watchService,
ENTRY_CREATE,
ENTRY_DELETE,
ENTRY_MODIFY
)
// register directory and sub-directories
Files.walkFileTree(path, object : SimpleFileVisitor<Path>() {
@Throws(IOException::class)
override fun preVisitDirectory(dir: Path, attrs: BasicFileAttributes): FileVisitResult {
val isIgnoredDirectory = ignoredDirsPath.any { "$pathStr/$it" == dir.toString() }
return if(!isIgnoredDirectory) {
dir.register(watchService, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY)
FileVisitResult.CONTINUE
} else {
FileVisitResult.SKIP_SUBTREE
}
}
})
var key: WatchKey
while (watchService.take().also { key = it } != null) {
this.emit(Unit)
for (event: WatchEvent<*> in key.pollEvents()) {
println(
"Event kind:" + event.kind()
+ ". File affected: " + event.context() + "."
)
}
key.reset()
}
}
}

View File

@ -15,7 +15,10 @@ import app.AppStateManager
import app.app.Error
import app.app.ErrorsManager
import app.app.newErrorNow
import app.extensions.dirPath
import kotlinx.coroutines.flow.collect
import org.eclipse.jgit.lib.ObjectId
import org.eclipse.jgit.treewalk.FileTreeIterator
import java.io.File
import javax.inject.Inject
@ -30,6 +33,7 @@ class GitManager @Inject constructor(
private val tagsManager: TagsManager,
val errorsManager: ErrorsManager,
val appStateManager: AppStateManager,
private val fileChangesWatcher: FileChangesWatcher,
) {
val repositoryName: String
get() = safeGit.repository.directory.parentFile.name
@ -115,6 +119,9 @@ class GitManager @Inject constructor(
onRepositoryChanged(repository.directory.parent)
refreshRepositoryInfo()
launch {
watchRepositoryChanges()
}
} catch (ex: Exception) {
ex.printStackTrace()
onRepositoryChanged(null)
@ -123,6 +130,21 @@ class GitManager @Inject constructor(
}
}
private suspend fun watchRepositoryChanges() {
val ignored = safeGit.status().call().ignoredNotInIndex.toList()
fileChangesWatcher.watchDirectoryPath(
pathStr = safeGit.repository.directory.parent,
ignoredDirsPath = ignored,
).collect {
safeProcessing {
println("Changes detected, loading status")
statusManager.loadHasUncommitedChanges(safeGit)
statusManager.loadStatus(safeGit)
}
}
}
fun loadLog() = managerScope.launch {
coLoadLog()
}

View File

@ -35,8 +35,10 @@ class StatusManager @Inject constructor() {
}
suspend fun loadStatus(git: Git) = withContext(Dispatchers.IO) {
val previousStatus = _stageStatus.value
_stageStatus.value = StageStatus.Loading
try {
loadHasUncommitedChanges(git)
val staged = git
@ -51,8 +53,12 @@ class StatusManager @Inject constructor() {
.call()
ensureActive()
_stageStatus.value = StageStatus.Loaded(staged, unstaged)
} catch(ex: Exception) {
_stageStatus.value = previousStatus
throw ex
}
}
suspend fun stage(git: Git, diffEntry: DiffEntry) = withContext(Dispatchers.IO) {