Fixed crash when watch init has failed
This commit is contained in:
parent
1ef596ad3c
commit
3128341b93
@ -1,11 +1,6 @@
|
||||
package com.jetpackduba.gitnuro.exceptions
|
||||
|
||||
class WatcherInitException(
|
||||
code: Int,
|
||||
message: String = codeToMessage(code),
|
||||
) : GitnuroException(message)
|
||||
|
||||
private fun codeToMessage(code: Int): String {
|
||||
fun codeToMessage(code: Int): String {
|
||||
return when (code) {
|
||||
1 /*is WatcherInitException.Generic*/, 2 /*is WatcherInitException.Io*/ -> "Could not watch directory. Check if it exists and you have read permissions."
|
||||
3 /*is WatcherInitException.PathNotFound*/ -> "Path not found, check if your repository still exists"
|
||||
|
@ -3,7 +3,6 @@ package com.jetpackduba.gitnuro.git
|
||||
import FileWatcher
|
||||
import WatchDirectoryNotifier
|
||||
import com.jetpackduba.gitnuro.di.TabScope
|
||||
import com.jetpackduba.gitnuro.exceptions.WatcherInitException
|
||||
import com.jetpackduba.gitnuro.git.workspace.GetIgnoreRulesUseCase
|
||||
import com.jetpackduba.gitnuro.system.systemSeparator
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
@ -25,8 +24,8 @@ class FileChangesWatcher @Inject constructor(
|
||||
private val getIgnoreRulesUseCase: GetIgnoreRulesUseCase,
|
||||
private val tabScope: CoroutineScope,
|
||||
) : AutoCloseable {
|
||||
private val _changesNotifier = MutableSharedFlow<Boolean>()
|
||||
val changesNotifier: SharedFlow<Boolean> = _changesNotifier
|
||||
private val _changesNotifier = MutableSharedFlow<WatcherEvent>()
|
||||
val changesNotifier: SharedFlow<WatcherEvent> = _changesNotifier
|
||||
private val fileWatcher = FileWatcher.new()
|
||||
private var shouldKeepLooping = true
|
||||
|
||||
@ -71,14 +70,16 @@ class FileChangesWatcher @Inject constructor(
|
||||
|
||||
if (!areAllPathsIgnored) {
|
||||
println("Emitting changes $hasGitIgnoreChanged")
|
||||
_changesNotifier.emit(hasGitDirChanged)
|
||||
_changesNotifier.emit(WatcherEvent.RepositoryChanged(hasGitDirChanged))
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
override fun onError(code: Int) {
|
||||
throw WatcherInitException(code)
|
||||
tabScope.launch {
|
||||
_changesNotifier.emit(WatcherEvent.WatchInitError(code))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -91,3 +92,8 @@ class FileChangesWatcher @Inject constructor(
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
sealed interface WatcherEvent {
|
||||
data class RepositoryChanged(val hasGitDirChanged: Boolean) : WatcherEvent
|
||||
data class WatchInitError(val code: Int) : WatcherEvent
|
||||
}
|
@ -2,7 +2,7 @@ package com.jetpackduba.gitnuro.viewmodels
|
||||
|
||||
import com.jetpackduba.gitnuro.SharedRepositoryStateManager
|
||||
import com.jetpackduba.gitnuro.TaskType
|
||||
import com.jetpackduba.gitnuro.exceptions.WatcherInitException
|
||||
import com.jetpackduba.gitnuro.exceptions.codeToMessage
|
||||
import com.jetpackduba.gitnuro.git.*
|
||||
import com.jetpackduba.gitnuro.git.branches.CreateBranchUseCase
|
||||
import com.jetpackduba.gitnuro.git.rebase.RebaseInteractiveState
|
||||
@ -110,6 +110,8 @@ class RepositoryOpenViewModel @Inject constructor(
|
||||
var authorViewModel: AuthorViewModel? = null
|
||||
private set
|
||||
|
||||
private var hasGitDirChanged = false
|
||||
|
||||
init {
|
||||
tabScope.run {
|
||||
launch {
|
||||
@ -119,7 +121,7 @@ class RepositoryOpenViewModel @Inject constructor(
|
||||
}
|
||||
|
||||
launch {
|
||||
watchRepositoryChanges(tabState.git)
|
||||
watchRepositoryChanges()
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -158,55 +160,53 @@ class RepositoryOpenViewModel @Inject constructor(
|
||||
* the app by constantly running "git status" or even full refreshes.
|
||||
*
|
||||
*/
|
||||
private suspend fun watchRepositoryChanges(git: Git) = tabScope.launch(Dispatchers.IO) {
|
||||
var hasGitDirChanged = false
|
||||
|
||||
private suspend fun watchRepositoryChanges() = tabScope.launch(Dispatchers.IO) {
|
||||
launch {
|
||||
fileChangesWatcher.changesNotifier.collect { latestUpdateChangedGitDir ->
|
||||
val isOperationRunning = tabState.operationRunning
|
||||
fileChangesWatcher.changesNotifier.collect { watcherEvent ->
|
||||
when (watcherEvent) {
|
||||
is WatcherEvent.RepositoryChanged -> repositoryChanged(watcherEvent.hasGitDirChanged)
|
||||
is WatcherEvent.WatchInitError -> {
|
||||
val message = codeToMessage(watcherEvent.code)
|
||||
errorsManager.addError(
|
||||
newErrorNow(
|
||||
exception = Exception(message),
|
||||
taskType = TaskType.CHANGES_DETECTION,
|
||||
),
|
||||
)
|
||||
|
||||
if (!isOperationRunning) { // Only update if there isn't any process running
|
||||
printDebug(TAG, "Detected changes in the repository's directory")
|
||||
|
||||
val currentTimeMillis = System.currentTimeMillis()
|
||||
|
||||
if (
|
||||
latestUpdateChangedGitDir &&
|
||||
currentTimeMillis - tabState.lastOperation < MIN_TIME_AFTER_GIT_OPERATION
|
||||
) {
|
||||
printDebug(TAG, "Git operation was executed recently, ignoring file system change")
|
||||
return@collect
|
||||
}
|
||||
|
||||
if (latestUpdateChangedGitDir) {
|
||||
hasGitDirChanged = true
|
||||
}
|
||||
|
||||
if (isActive) {
|
||||
updateApp(hasGitDirChanged)
|
||||
}
|
||||
|
||||
hasGitDirChanged = false
|
||||
} else {
|
||||
printDebug(TAG, "Ignored file events during operation")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
fileChangesWatcher.watchDirectoryPath(
|
||||
repository = git.repository,
|
||||
)
|
||||
} catch (ex: WatcherInitException) {
|
||||
val message = ex.message
|
||||
if (message != null) {
|
||||
errorsManager.addError(
|
||||
newErrorNow(
|
||||
exception = ex,
|
||||
taskType = TaskType.CHANGES_DETECTION,
|
||||
),
|
||||
)
|
||||
private suspend fun CoroutineScope.repositoryChanged(hasGitDirChanged: Boolean) {
|
||||
val isOperationRunning = tabState.operationRunning
|
||||
|
||||
if (!isOperationRunning) { // Only update if there isn't any process running
|
||||
printDebug(TAG, "Detected changes in the repository's directory")
|
||||
|
||||
val currentTimeMillis = System.currentTimeMillis()
|
||||
|
||||
if (
|
||||
hasGitDirChanged &&
|
||||
currentTimeMillis - tabState.lastOperation < MIN_TIME_AFTER_GIT_OPERATION
|
||||
) {
|
||||
printDebug(TAG, "Git operation was executed recently, ignoring file system change")
|
||||
return
|
||||
}
|
||||
|
||||
if (hasGitDirChanged) {
|
||||
this@RepositoryOpenViewModel.hasGitDirChanged = true
|
||||
}
|
||||
|
||||
if (isActive) {
|
||||
updateApp(hasGitDirChanged)
|
||||
}
|
||||
|
||||
this@RepositoryOpenViewModel.hasGitDirChanged = false
|
||||
} else {
|
||||
printDebug(TAG, "Ignored file events during operation")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,45 +1,37 @@
|
||||
package com.jetpackduba.gitnuro.viewmodels
|
||||
|
||||
import com.jetpackduba.gitnuro.SharedRepositoryStateManager
|
||||
import com.jetpackduba.gitnuro.TaskType
|
||||
import com.jetpackduba.gitnuro.credentials.CredentialsAccepted
|
||||
import com.jetpackduba.gitnuro.credentials.CredentialsState
|
||||
import com.jetpackduba.gitnuro.credentials.CredentialsStateManager
|
||||
import com.jetpackduba.gitnuro.exceptions.WatcherInitException
|
||||
import com.jetpackduba.gitnuro.git.*
|
||||
import com.jetpackduba.gitnuro.git.branches.CreateBranchUseCase
|
||||
import com.jetpackduba.gitnuro.git.rebase.RebaseInteractiveState
|
||||
import com.jetpackduba.gitnuro.git.FileChangesWatcher
|
||||
import com.jetpackduba.gitnuro.git.ProcessingState
|
||||
import com.jetpackduba.gitnuro.git.RefreshType
|
||||
import com.jetpackduba.gitnuro.git.TabState
|
||||
import com.jetpackduba.gitnuro.git.repository.InitLocalRepositoryUseCase
|
||||
import com.jetpackduba.gitnuro.git.repository.OpenRepositoryUseCase
|
||||
import com.jetpackduba.gitnuro.git.repository.OpenSubmoduleRepositoryUseCase
|
||||
import com.jetpackduba.gitnuro.git.stash.StashChangesUseCase
|
||||
import com.jetpackduba.gitnuro.git.workspace.StageUntrackedFileUseCase
|
||||
import com.jetpackduba.gitnuro.logging.printDebug
|
||||
import com.jetpackduba.gitnuro.logging.printLog
|
||||
import com.jetpackduba.gitnuro.managers.AppStateManager
|
||||
import com.jetpackduba.gitnuro.managers.ErrorsManager
|
||||
import com.jetpackduba.gitnuro.managers.newErrorNow
|
||||
import com.jetpackduba.gitnuro.models.AuthorInfoSimple
|
||||
import com.jetpackduba.gitnuro.models.errorNotification
|
||||
import com.jetpackduba.gitnuro.models.positiveNotification
|
||||
import com.jetpackduba.gitnuro.system.OpenFilePickerUseCase
|
||||
import com.jetpackduba.gitnuro.system.OpenUrlInBrowserUseCase
|
||||
import com.jetpackduba.gitnuro.system.PickerType
|
||||
import com.jetpackduba.gitnuro.ui.IVerticalSplitPaneConfig
|
||||
import com.jetpackduba.gitnuro.ui.SelectedItem
|
||||
import com.jetpackduba.gitnuro.ui.TabsManager
|
||||
import com.jetpackduba.gitnuro.ui.VerticalSplitPaneConfig
|
||||
import com.jetpackduba.gitnuro.updates.Update
|
||||
import com.jetpackduba.gitnuro.updates.UpdatesRepository
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.flow.*
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.cancel
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.SharingStarted
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.stateIn
|
||||
import kotlinx.coroutines.launch
|
||||
import org.eclipse.jgit.api.Git
|
||||
import org.eclipse.jgit.api.errors.CheckoutConflictException
|
||||
import org.eclipse.jgit.blame.BlameResult
|
||||
import org.eclipse.jgit.lib.Repository
|
||||
import org.eclipse.jgit.lib.RepositoryState
|
||||
import org.eclipse.jgit.revwalk.RevCommit
|
||||
import java.awt.Desktop
|
||||
import java.io.File
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Provider
|
||||
|
Loading…
Reference in New Issue
Block a user