1
1
package com.codacy.intellij.plugin.services.git
2
2
3
3
import com.codacy.intellij.plugin.services.api.Api
4
- import com.codacy.intellij.plugin.services.api.models.*
5
- import com.codacy.intellij.plugin.services.common.*
6
- import com.codacy.intellij.plugin.telemetry.BranchStateChangeEvent
4
+ import com.codacy.intellij.plugin.services.api.models.RepositoryData
5
+ import com.codacy.intellij.plugin.services.common.Config
6
+ import com.codacy.intellij.plugin.services.common.GitRemoteParser
7
+ import com.codacy.intellij.plugin.services.common.Logger
8
+ import com.codacy.intellij.plugin.services.common.TimeoutManager
9
+ import com.codacy.intellij.plugin.telemetry.PullRequestStateChangeEvent
10
+ import com.codacy.intellij.plugin.telemetry.RepositoryStateChangeEvent
7
11
import com.codacy.intellij.plugin.telemetry.Telemetry
8
12
import com.intellij.openapi.Disposable
9
13
import com.intellij.openapi.components.Service
@@ -21,7 +25,11 @@ const val MAX_LOAD_ATTEMPTS: Int = 5
21
25
class RepositoryManager (private val project : Project ) {
22
26
23
27
enum class RepositoryManagerState {
24
- NoRepository , NoRemote , Initializing , NeedsAuthentication , Loaded
28
+ Initializing ,
29
+ NeedsAuthentication ,
30
+ NoGitRepository ,
31
+ Loaded ,
32
+ NoRepository
25
33
}
26
34
27
35
enum class PullRequestState {
@@ -63,7 +71,7 @@ class RepositoryManager(private val project: Project) {
63
71
}
64
72
65
73
if (currentRepository != gitRepository) {
66
- ProgressManager .getInstance().run (object : Task .Backgroundable (project, " Opening repository" , false ) {
74
+ ProgressManager .getInstance().run (object : Task .Backgroundable (project, " Opening repository" , false ) {
67
75
override fun run (indicator : com.intellij.openapi.progress.ProgressIndicator ) {
68
76
GlobalScope .launch {
69
77
currentRepository = gitRepository
@@ -74,7 +82,7 @@ class RepositoryManager(private val project: Project) {
74
82
setNewState(RepositoryManagerState .Initializing )
75
83
} else {
76
84
if (remoteUrl.isNullOrEmpty()) {
77
- setNewState(RepositoryManagerState .NoRemote )
85
+ setNewState(RepositoryManagerState .NoGitRepository )
78
86
Logger .error(" No remote found" )
79
87
return @launch
80
88
}
@@ -117,13 +125,16 @@ class RepositoryManager(private val project: Project) {
117
125
branch = currentHead
118
126
pullRequest = null
119
127
notifyDidUpdatePullRequest()
120
- prState = PullRequestState .NoPullRequest
128
+ setNewPullRequestState(PullRequestState .NoPullRequest )
129
+
121
130
loadPullRequest()
122
131
} else {
123
132
val currentHeadCommitSHA = GitProvider .getHeadCommitSHA(project)
124
133
val currentHeadAhead: Boolean = GitProvider .isHeadAhead(project)
125
- if (currentHeadCommitSHA != null && pullRequest != null && prState == = PullRequestState .Loaded && currentHeadCommitSHA != = pullRequest?.meta?.headCommitSHA && ! currentHeadAhead) {
126
- if (refreshTimeout.isTimeoutRunning()) refreshTimeout.clearTimeout()
134
+ if (isPrLoadedAndNotCheckedOut(pullRequest, prState, currentHeadCommitSHA, currentHeadAhead)) {
135
+ if (refreshTimeout.isTimeoutRunning()) {
136
+ refreshTimeout.clearTimeout()
137
+ }
127
138
refreshTimeout.startTimeout(10000 ) {
128
139
Logger .info(" Pushed all local commits, refreshing pull request..." )
129
140
pullRequestInstance!! .refresh()
@@ -132,6 +143,18 @@ class RepositoryManager(private val project: Project) {
132
143
}
133
144
}
134
145
146
+ private fun isPrLoadedAndNotCheckedOut (
147
+ pullRequest : PullRequest ? ,
148
+ prState : PullRequestState ,
149
+ currentHeadCommitSHA : String ,
150
+ currentHeadAhead : Boolean
151
+ ): Boolean =
152
+ pullRequest != null &&
153
+ prState == = PullRequestState .Loaded &&
154
+ currentHeadCommitSHA != pullRequest.meta?.headCommitSHA &&
155
+ ! currentHeadAhead
156
+
157
+
135
158
@OptIn(DelicateCoroutinesApi ::class )
136
159
private suspend fun loadPullRequest () {
137
160
if (loadTimeout.isTimeoutRunning()) loadTimeout.clearTimeout()
@@ -141,17 +164,17 @@ class RepositoryManager(private val project: Project) {
141
164
branch = currentRepository?.currentBranch?.name
142
165
if (branch.isNullOrBlank()) {
143
166
Logger .warn(" No HEAD information found: ${currentRepository?.currentBranch} " )
144
- prState = PullRequestState .NoPullRequest
167
+ setNewPullRequestState( PullRequestState .NoPullRequest )
145
168
return
146
169
}
147
170
148
171
if (branch == repo.defaultBranch.name) {
149
172
Logger .info(" Current branch is the default branch: $branch " )
150
- prState = PullRequestState .NoPullRequest
173
+ setNewPullRequestState( PullRequestState .NoPullRequest )
151
174
return
152
175
}
153
176
154
- ProgressManager .getInstance().run (object : Task .Backgroundable (project, " Loading pull request" , false ) {
177
+ ProgressManager .getInstance().run (object : Task .Backgroundable (project, " Loading pull request" , false ) {
155
178
override fun run (indicator : com.intellij.openapi.progress.ProgressIndicator ) {
156
179
GlobalScope .launch {
157
180
try {
@@ -162,9 +185,7 @@ class RepositoryManager(private val project: Project) {
162
185
163
186
if (pr == null ) {
164
187
Logger .info(" No PR found in Codacy for: $branch " )
165
- prState = PullRequestState .NoPullRequest
166
- // Evaluate branch state after PR discovery fails
167
- evaluateBranchState()
188
+ setNewPullRequestState(PullRequestState .NoPullRequest )
168
189
169
190
if (loadAttempts < MAX_LOAD_ATTEMPTS ) {
170
191
loadTimeout.startTimeout(LOAD_RETRY_TIME ) {
@@ -185,9 +206,7 @@ class RepositoryManager(private val project: Project) {
185
206
notifyDidUpdatePullRequest()
186
207
}
187
208
188
- prState = PullRequestState .Loaded
189
- // Evaluate branch state after PR is loaded
190
- evaluateBranchState()
209
+ setNewPullRequestState(PullRequestState .Loaded )
191
210
} catch (e: Exception ) {
192
211
Logger .error(" Error loading pull request: ${e.message} " )
193
212
}
@@ -208,11 +227,21 @@ class RepositoryManager(private val project: Project) {
208
227
val stateChange: Boolean = newState != = state
209
228
state = newState
210
229
if (stateChange) {
230
+ Telemetry .track(RepositoryStateChangeEvent (newState.name))
211
231
// TODO("execute command setContext")
212
232
notifyDidChangeState()
213
233
}
214
234
}
215
235
236
+ fun setNewPullRequestState (newState : PullRequestState ) {
237
+ val stateChange: Boolean = newState != = prState
238
+ prState = newState
239
+ if (stateChange) {
240
+ // Track pull request state change telemetry
241
+ Telemetry .track(PullRequestStateChangeEvent (newState.name))
242
+ }
243
+ }
244
+
216
245
fun onDidUpdatePullRequest (listener : () -> Unit ): Disposable {
217
246
onDidUpdatePullRequestListeners.add(listener)
218
247
return Disposable { onDidUpdatePullRequestListeners.remove(listener) }
0 commit comments