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.Error
import app.app.ErrorsManager import app.app.ErrorsManager
import app.app.newErrorNow import app.app.newErrorNow
import app.extensions.dirPath
import kotlinx.coroutines.flow.collect
import org.eclipse.jgit.lib.ObjectId import org.eclipse.jgit.lib.ObjectId
import org.eclipse.jgit.treewalk.FileTreeIterator
import java.io.File import java.io.File
import javax.inject.Inject import javax.inject.Inject
@ -30,6 +33,7 @@ class GitManager @Inject constructor(
private val tagsManager: TagsManager, private val tagsManager: TagsManager,
val errorsManager: ErrorsManager, val errorsManager: ErrorsManager,
val appStateManager: AppStateManager, val appStateManager: AppStateManager,
private val fileChangesWatcher: FileChangesWatcher,
) { ) {
val repositoryName: String val repositoryName: String
get() = safeGit.repository.directory.parentFile.name get() = safeGit.repository.directory.parentFile.name
@ -115,6 +119,9 @@ class GitManager @Inject constructor(
onRepositoryChanged(repository.directory.parent) onRepositoryChanged(repository.directory.parent)
refreshRepositoryInfo() refreshRepositoryInfo()
launch {
watchRepositoryChanges()
}
} catch (ex: Exception) { } catch (ex: Exception) {
ex.printStackTrace() ex.printStackTrace()
onRepositoryChanged(null) 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 { fun loadLog() = managerScope.launch {
coLoadLog() coLoadLog()
} }

View File

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