11package com.codacy.intellij.plugin.services.git
22
33import 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
711import com.codacy.intellij.plugin.telemetry.Telemetry
812import com.intellij.openapi.Disposable
913import com.intellij.openapi.components.Service
@@ -21,7 +25,11 @@ const val MAX_LOAD_ATTEMPTS: Int = 5
2125class RepositoryManager (private val project : Project ) {
2226
2327 enum class RepositoryManagerState {
24- NoRepository , NoRemote , Initializing , NeedsAuthentication , Loaded
28+ Initializing ,
29+ NeedsAuthentication ,
30+ NoGitRepository ,
31+ Loaded ,
32+ NoRepository
2533 }
2634
2735 enum class PullRequestState {
@@ -63,7 +71,7 @@ class RepositoryManager(private val project: Project) {
6371 }
6472
6573 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 ) {
6775 override fun run (indicator : com.intellij.openapi.progress.ProgressIndicator ) {
6876 GlobalScope .launch {
6977 currentRepository = gitRepository
@@ -74,7 +82,7 @@ class RepositoryManager(private val project: Project) {
7482 setNewState(RepositoryManagerState .Initializing )
7583 } else {
7684 if (remoteUrl.isNullOrEmpty()) {
77- setNewState(RepositoryManagerState .NoRemote )
85+ setNewState(RepositoryManagerState .NoGitRepository )
7886 Logger .error(" No remote found" )
7987 return @launch
8088 }
@@ -117,13 +125,16 @@ class RepositoryManager(private val project: Project) {
117125 branch = currentHead
118126 pullRequest = null
119127 notifyDidUpdatePullRequest()
120- prState = PullRequestState .NoPullRequest
128+ setNewPullRequestState(PullRequestState .NoPullRequest )
129+
121130 loadPullRequest()
122131 } else {
123132 val currentHeadCommitSHA = GitProvider .getHeadCommitSHA(project)
124133 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+ }
127138 refreshTimeout.startTimeout(10000 ) {
128139 Logger .info(" Pushed all local commits, refreshing pull request..." )
129140 pullRequestInstance!! .refresh()
@@ -132,6 +143,18 @@ class RepositoryManager(private val project: Project) {
132143 }
133144 }
134145
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+
135158 @OptIn(DelicateCoroutinesApi ::class )
136159 private suspend fun loadPullRequest () {
137160 if (loadTimeout.isTimeoutRunning()) loadTimeout.clearTimeout()
@@ -141,17 +164,17 @@ class RepositoryManager(private val project: Project) {
141164 branch = currentRepository?.currentBranch?.name
142165 if (branch.isNullOrBlank()) {
143166 Logger .warn(" No HEAD information found: ${currentRepository?.currentBranch} " )
144- prState = PullRequestState .NoPullRequest
167+ setNewPullRequestState( PullRequestState .NoPullRequest )
145168 return
146169 }
147170
148171 if (branch == repo.defaultBranch.name) {
149172 Logger .info(" Current branch is the default branch: $branch " )
150- prState = PullRequestState .NoPullRequest
173+ setNewPullRequestState( PullRequestState .NoPullRequest )
151174 return
152175 }
153176
154- ProgressManager .getInstance().run (object : Task .Backgroundable (project, " Loading pull request" , false ) {
177+ ProgressManager .getInstance().run (object : Task .Backgroundable (project, " Loading pull request" , false ) {
155178 override fun run (indicator : com.intellij.openapi.progress.ProgressIndicator ) {
156179 GlobalScope .launch {
157180 try {
@@ -162,9 +185,7 @@ class RepositoryManager(private val project: Project) {
162185
163186 if (pr == null ) {
164187 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 )
168189
169190 if (loadAttempts < MAX_LOAD_ATTEMPTS ) {
170191 loadTimeout.startTimeout(LOAD_RETRY_TIME ) {
@@ -185,9 +206,7 @@ class RepositoryManager(private val project: Project) {
185206 notifyDidUpdatePullRequest()
186207 }
187208
188- prState = PullRequestState .Loaded
189- // Evaluate branch state after PR is loaded
190- evaluateBranchState()
209+ setNewPullRequestState(PullRequestState .Loaded )
191210 } catch (e: Exception ) {
192211 Logger .error(" Error loading pull request: ${e.message} " )
193212 }
@@ -208,11 +227,21 @@ class RepositoryManager(private val project: Project) {
208227 val stateChange: Boolean = newState != = state
209228 state = newState
210229 if (stateChange) {
230+ Telemetry .track(RepositoryStateChangeEvent (newState.name))
211231// TODO("execute command setContext")
212232 notifyDidChangeState()
213233 }
214234 }
215235
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+
216245 fun onDidUpdatePullRequest (listener : () -> Unit ): Disposable {
217246 onDidUpdatePullRequestListeners.add(listener)
218247 return Disposable { onDidUpdatePullRequestListeners.remove(listener) }
0 commit comments