Skip to content

Commit 3128341

Browse files
committed
Fixed crash when watch init has failed
1 parent 1ef596a commit 3128341

File tree

4 files changed

+64
-71
lines changed

4 files changed

+64
-71
lines changed

src/main/kotlin/com/jetpackduba/gitnuro/exceptions/WatcherInitException.kt

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,6 @@
11
package com.jetpackduba.gitnuro.exceptions
22

3-
class WatcherInitException(
4-
code: Int,
5-
message: String = codeToMessage(code),
6-
) : GitnuroException(message)
7-
8-
private fun codeToMessage(code: Int): String {
3+
fun codeToMessage(code: Int): String {
94
return when (code) {
105
1 /*is WatcherInitException.Generic*/, 2 /*is WatcherInitException.Io*/ -> "Could not watch directory. Check if it exists and you have read permissions."
116
3 /*is WatcherInitException.PathNotFound*/ -> "Path not found, check if your repository still exists"

src/main/kotlin/com/jetpackduba/gitnuro/git/FileChangesWatcher.kt

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package com.jetpackduba.gitnuro.git
33
import FileWatcher
44
import WatchDirectoryNotifier
55
import com.jetpackduba.gitnuro.di.TabScope
6-
import com.jetpackduba.gitnuro.exceptions.WatcherInitException
76
import com.jetpackduba.gitnuro.git.workspace.GetIgnoreRulesUseCase
87
import com.jetpackduba.gitnuro.system.systemSeparator
98
import kotlinx.coroutines.CoroutineScope
@@ -25,8 +24,8 @@ class FileChangesWatcher @Inject constructor(
2524
private val getIgnoreRulesUseCase: GetIgnoreRulesUseCase,
2625
private val tabScope: CoroutineScope,
2726
) : AutoCloseable {
28-
private val _changesNotifier = MutableSharedFlow<Boolean>()
29-
val changesNotifier: SharedFlow<Boolean> = _changesNotifier
27+
private val _changesNotifier = MutableSharedFlow<WatcherEvent>()
28+
val changesNotifier: SharedFlow<WatcherEvent> = _changesNotifier
3029
private val fileWatcher = FileWatcher.new()
3130
private var shouldKeepLooping = true
3231

@@ -71,14 +70,16 @@ class FileChangesWatcher @Inject constructor(
7170

7271
if (!areAllPathsIgnored) {
7372
println("Emitting changes $hasGitIgnoreChanged")
74-
_changesNotifier.emit(hasGitDirChanged)
73+
_changesNotifier.emit(WatcherEvent.RepositoryChanged(hasGitDirChanged))
7574
}
7675

7776
}
7877
}
7978

8079
override fun onError(code: Int) {
81-
throw WatcherInitException(code)
80+
tabScope.launch {
81+
_changesNotifier.emit(WatcherEvent.WatchInitError(code))
82+
}
8283
}
8384
}
8485

@@ -90,4 +91,9 @@ class FileChangesWatcher @Inject constructor(
9091
fileWatcher.close()
9192
}
9293

94+
}
95+
96+
sealed interface WatcherEvent {
97+
data class RepositoryChanged(val hasGitDirChanged: Boolean) : WatcherEvent
98+
data class WatchInitError(val code: Int) : WatcherEvent
9399
}

src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/RepositoryOpenViewModel.kt

Lines changed: 41 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ package com.jetpackduba.gitnuro.viewmodels
22

33
import com.jetpackduba.gitnuro.SharedRepositoryStateManager
44
import com.jetpackduba.gitnuro.TaskType
5-
import com.jetpackduba.gitnuro.exceptions.WatcherInitException
5+
import com.jetpackduba.gitnuro.exceptions.codeToMessage
66
import com.jetpackduba.gitnuro.git.*
77
import com.jetpackduba.gitnuro.git.branches.CreateBranchUseCase
88
import com.jetpackduba.gitnuro.git.rebase.RebaseInteractiveState
@@ -110,6 +110,8 @@ class RepositoryOpenViewModel @Inject constructor(
110110
var authorViewModel: AuthorViewModel? = null
111111
private set
112112

113+
private var hasGitDirChanged = false
114+
113115
init {
114116
tabScope.run {
115117
launch {
@@ -119,7 +121,7 @@ class RepositoryOpenViewModel @Inject constructor(
119121
}
120122

121123
launch {
122-
watchRepositoryChanges(tabState.git)
124+
watchRepositoryChanges()
123125
}
124126
}
125127
}
@@ -158,55 +160,53 @@ class RepositoryOpenViewModel @Inject constructor(
158160
* the app by constantly running "git status" or even full refreshes.
159161
*
160162
*/
161-
private suspend fun watchRepositoryChanges(git: Git) = tabScope.launch(Dispatchers.IO) {
162-
var hasGitDirChanged = false
163-
163+
private suspend fun watchRepositoryChanges() = tabScope.launch(Dispatchers.IO) {
164164
launch {
165-
fileChangesWatcher.changesNotifier.collect { latestUpdateChangedGitDir ->
166-
val isOperationRunning = tabState.operationRunning
165+
fileChangesWatcher.changesNotifier.collect { watcherEvent ->
166+
when (watcherEvent) {
167+
is WatcherEvent.RepositoryChanged -> repositoryChanged(watcherEvent.hasGitDirChanged)
168+
is WatcherEvent.WatchInitError -> {
169+
val message = codeToMessage(watcherEvent.code)
170+
errorsManager.addError(
171+
newErrorNow(
172+
exception = Exception(message),
173+
taskType = TaskType.CHANGES_DETECTION,
174+
),
175+
)
167176

168-
if (!isOperationRunning) { // Only update if there isn't any process running
169-
printDebug(TAG, "Detected changes in the repository's directory")
177+
}
178+
}
179+
}
180+
}
181+
}
170182

171-
val currentTimeMillis = System.currentTimeMillis()
183+
private suspend fun CoroutineScope.repositoryChanged(hasGitDirChanged: Boolean) {
184+
val isOperationRunning = tabState.operationRunning
172185

173-
if (
174-
latestUpdateChangedGitDir &&
175-
currentTimeMillis - tabState.lastOperation < MIN_TIME_AFTER_GIT_OPERATION
176-
) {
177-
printDebug(TAG, "Git operation was executed recently, ignoring file system change")
178-
return@collect
179-
}
186+
if (!isOperationRunning) { // Only update if there isn't any process running
187+
printDebug(TAG, "Detected changes in the repository's directory")
180188

181-
if (latestUpdateChangedGitDir) {
182-
hasGitDirChanged = true
183-
}
189+
val currentTimeMillis = System.currentTimeMillis()
184190

185-
if (isActive) {
186-
updateApp(hasGitDirChanged)
187-
}
191+
if (
192+
hasGitDirChanged &&
193+
currentTimeMillis - tabState.lastOperation < MIN_TIME_AFTER_GIT_OPERATION
194+
) {
195+
printDebug(TAG, "Git operation was executed recently, ignoring file system change")
196+
return
197+
}
188198

189-
hasGitDirChanged = false
190-
} else {
191-
printDebug(TAG, "Ignored file events during operation")
192-
}
199+
if (hasGitDirChanged) {
200+
this@RepositoryOpenViewModel.hasGitDirChanged = true
193201
}
194-
}
195202

196-
try {
197-
fileChangesWatcher.watchDirectoryPath(
198-
repository = git.repository,
199-
)
200-
} catch (ex: WatcherInitException) {
201-
val message = ex.message
202-
if (message != null) {
203-
errorsManager.addError(
204-
newErrorNow(
205-
exception = ex,
206-
taskType = TaskType.CHANGES_DETECTION,
207-
),
208-
)
203+
if (isActive) {
204+
updateApp(hasGitDirChanged)
209205
}
206+
207+
this@RepositoryOpenViewModel.hasGitDirChanged = false
208+
} else {
209+
printDebug(TAG, "Ignored file events during operation")
210210
}
211211
}
212212

src/main/kotlin/com/jetpackduba/gitnuro/viewmodels/TabViewModel.kt

Lines changed: 11 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,37 @@
11
package com.jetpackduba.gitnuro.viewmodels
22

3-
import com.jetpackduba.gitnuro.SharedRepositoryStateManager
43
import com.jetpackduba.gitnuro.TaskType
54
import com.jetpackduba.gitnuro.credentials.CredentialsAccepted
65
import com.jetpackduba.gitnuro.credentials.CredentialsState
76
import com.jetpackduba.gitnuro.credentials.CredentialsStateManager
8-
import com.jetpackduba.gitnuro.exceptions.WatcherInitException
9-
import com.jetpackduba.gitnuro.git.*
10-
import com.jetpackduba.gitnuro.git.branches.CreateBranchUseCase
11-
import com.jetpackduba.gitnuro.git.rebase.RebaseInteractiveState
7+
import com.jetpackduba.gitnuro.git.FileChangesWatcher
8+
import com.jetpackduba.gitnuro.git.ProcessingState
9+
import com.jetpackduba.gitnuro.git.RefreshType
10+
import com.jetpackduba.gitnuro.git.TabState
1211
import com.jetpackduba.gitnuro.git.repository.InitLocalRepositoryUseCase
1312
import com.jetpackduba.gitnuro.git.repository.OpenRepositoryUseCase
1413
import com.jetpackduba.gitnuro.git.repository.OpenSubmoduleRepositoryUseCase
15-
import com.jetpackduba.gitnuro.git.stash.StashChangesUseCase
16-
import com.jetpackduba.gitnuro.git.workspace.StageUntrackedFileUseCase
17-
import com.jetpackduba.gitnuro.logging.printDebug
1814
import com.jetpackduba.gitnuro.logging.printLog
1915
import com.jetpackduba.gitnuro.managers.AppStateManager
2016
import com.jetpackduba.gitnuro.managers.ErrorsManager
2117
import com.jetpackduba.gitnuro.managers.newErrorNow
22-
import com.jetpackduba.gitnuro.models.AuthorInfoSimple
23-
import com.jetpackduba.gitnuro.models.errorNotification
24-
import com.jetpackduba.gitnuro.models.positiveNotification
2518
import com.jetpackduba.gitnuro.system.OpenFilePickerUseCase
2619
import com.jetpackduba.gitnuro.system.OpenUrlInBrowserUseCase
2720
import com.jetpackduba.gitnuro.system.PickerType
2821
import com.jetpackduba.gitnuro.ui.IVerticalSplitPaneConfig
2922
import com.jetpackduba.gitnuro.ui.SelectedItem
30-
import com.jetpackduba.gitnuro.ui.TabsManager
3123
import com.jetpackduba.gitnuro.ui.VerticalSplitPaneConfig
3224
import com.jetpackduba.gitnuro.updates.Update
3325
import com.jetpackduba.gitnuro.updates.UpdatesRepository
34-
import kotlinx.coroutines.*
35-
import kotlinx.coroutines.flow.*
26+
import kotlinx.coroutines.CoroutineScope
27+
import kotlinx.coroutines.cancel
28+
import kotlinx.coroutines.flow.MutableStateFlow
29+
import kotlinx.coroutines.flow.SharingStarted
30+
import kotlinx.coroutines.flow.StateFlow
31+
import kotlinx.coroutines.flow.stateIn
32+
import kotlinx.coroutines.launch
3633
import org.eclipse.jgit.api.Git
37-
import org.eclipse.jgit.api.errors.CheckoutConflictException
38-
import org.eclipse.jgit.blame.BlameResult
3934
import org.eclipse.jgit.lib.Repository
40-
import org.eclipse.jgit.lib.RepositoryState
41-
import org.eclipse.jgit.revwalk.RevCommit
42-
import java.awt.Desktop
4335
import java.io.File
4436
import javax.inject.Inject
4537
import javax.inject.Provider

0 commit comments

Comments
 (0)