Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,12 @@ class Api {
return makeRequest(endpointUrl, GetRepositoryResponse::class.java)
}

suspend fun listRepositoryBranches(provider: String, remoteOrganizationName: String, repositoryName: String, enabledOnly: Boolean = true): ListRepositoryBranchesResponse {
val enabledParam = if (enabledOnly) "?enabled=true" else ""
val endpointUrl = "repositories/$provider/$remoteOrganizationName/$repositoryName/branches$enabledParam"
return makeRequest(endpointUrl, ListRepositoryBranchesResponse::class.java)
}

suspend fun getUserProfile(): UserProfile? {
val endpointUrl = "user"
return try {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.codacy.intellij.plugin.services.api.models

data class ListRepositoryBranchesResponse(
val data: List<Branch>
)

Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@
NoPullRequest, Loaded
}

enum class BranchState {
OnPullRequestBranch, OnAnalysedBranch, OnAnalysedBranchOutdated, OnUnknownBranch
}

var currentRepository: GitRepository? = null
var repository: RepositoryData? = null
var state: RepositoryManagerState = RepositoryManagerState.Initializing
Expand All @@ -41,6 +45,11 @@
private val config = Config()
private var pullRequestInstance: PullRequest? = null

// Branch state management
private var enabledBranches: List<Branch> = emptyList()
private var branchState: BranchState = BranchState.OnUnknownBranch
private var lastBranchState: BranchState? = null

private var onDidUpdatePullRequestListeners = mutableListOf<() -> Unit>()
private var onDidLoadRepositoryListeners = mutableListOf<() -> Unit>()
private var onDidChangeStateListeners = mutableListOf<() -> Unit>()
Expand Down Expand Up @@ -74,6 +83,17 @@
val (data) = api.getRepository(repo.provider, repo.organization, repo.repository)

repository = data

// Fetch enabled branches
try {
val branchesResponse = api.listRepositoryBranches(repo.provider, repo.organization, repo.repository, true)
enabledBranches = branchesResponse.data
Logger.info("Fetched ${enabledBranches.size} enabled branches")
} catch (e: Exception) {
Logger.error("Failed to fetch enabled branches: ${e.message}")
enabledBranches = emptyList()
}

setNewState(RepositoryManagerState.Loaded)
notifyDidLoadRepository()
loadPullRequest()
Expand All @@ -100,9 +120,9 @@
prState = PullRequestState.NoPullRequest
loadPullRequest()
} else {
val currentHeadCommitSHA: String = GitProvider.getHeadCommitSHA(project)!!
val currentHeadCommitSHA = GitProvider.getHeadCommitSHA(project)
val currentHeadAhead: Boolean = GitProvider.isHeadAhead(project)
if (pullRequest != null && prState === PullRequestState.Loaded && currentHeadCommitSHA !== pullRequest?.meta?.headCommitSHA && !currentHeadAhead) {
if (currentHeadCommitSHA != null && pullRequest != null && prState === PullRequestState.Loaded && currentHeadCommitSHA !== pullRequest?.meta?.headCommitSHA && !currentHeadAhead) {

Check notice on line 125 in src/main/kotlin/com/codacy/intellij/plugin/services/git/RepositoryManager.kt

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

src/main/kotlin/com/codacy/intellij/plugin/services/git/RepositoryManager.kt#L125

This condition is too complex (5). Defined complexity threshold for conditions is set to '4'
if (refreshTimeout.isTimeoutRunning()) refreshTimeout.clearTimeout()
refreshTimeout.startTimeout(10000) {
Logger.info("Pushed all local commits, refreshing pull request...")
Expand Down Expand Up @@ -143,6 +163,8 @@
if (pr == null) {
Logger.info("No PR found in Codacy for: $branch")
prState = PullRequestState.NoPullRequest
// Evaluate branch state after PR discovery fails
evaluateBranchState()

if (loadAttempts < MAX_LOAD_ATTEMPTS) {
loadTimeout.startTimeout(LOAD_RETRY_TIME) {
Expand All @@ -164,6 +186,8 @@
}

prState = PullRequestState.Loaded
// Evaluate branch state after PR is loaded
evaluateBranchState()
} catch (e: Exception) {
Logger.error("Error loading pull request: ${e.message}")
}
Expand All @@ -173,8 +197,10 @@
}

fun clear() {

currentRepository = null
enabledBranches = emptyList()
branchState = BranchState.OnUnknownBranch
lastBranchState = null
setNewState(RepositoryManagerState.NoRepository)
}

Expand Down Expand Up @@ -223,4 +249,65 @@
}
}

@OptIn(DelicateCoroutinesApi::class)
private suspend fun evaluateBranchState() {

Check warning on line 253 in src/main/kotlin/com/codacy/intellij/plugin/services/git/RepositoryManager.kt

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

src/main/kotlin/com/codacy/intellij/plugin/services/git/RepositoryManager.kt#L253

Method evaluateBranchState has a cyclomatic complexity of 9 (limit is 7)
if (state != RepositoryManagerState.Loaded || repository == null) return

val currentBranch = currentRepository?.currentBranch?.name
val repo = repository!!

// If no HEAD name, set to OnUnknownBranch
if (currentBranch.isNullOrBlank()) {
Logger.warn("No HEAD information found: ${currentRepository?.currentBranch}")
setBranchState(BranchState.OnUnknownBranch)
return
}

// If PR is loaded, set to OnPullRequestBranch
if (prState == PullRequestState.Loaded) {
setBranchState(BranchState.OnPullRequestBranch)
return
}

// Check if current branch is in enabled branches
val isEnabledBranch = enabledBranches.any { it.name == currentBranch }

if (isEnabledBranch) {
Logger.info("Current branch is an analyzed branch: $currentBranch")

// Get the last analyzed commit for this branch
try {
val analysisResponse = api.getRepositoryWithAnalysis(repo.provider, repo.owner, repo.name)
val lastAnalysedCommit = analysisResponse.data.lastAnalysedCommit
val localHeadCommit = GitProvider.getHeadCommitSHA(project)

if (localHeadCommit != null && lastAnalysedCommit.sha != localHeadCommit) {
Logger.info("Local branch '$currentBranch' is outdated: Local Head ${localHeadCommit.substring(0, 7)} !== Last analysed Head ${lastAnalysedCommit.sha.substring(0, 7)}")
setBranchState(BranchState.OnAnalysedBranchOutdated)
} else {
setBranchState(BranchState.OnAnalysedBranch)
}
} catch (e: Exception) {
Logger.error("Failed to get repository analysis: ${e.message}")
setBranchState(BranchState.OnUnknownBranch)
}
} else {
// Not an enabled branch and no PR loaded
setBranchState(BranchState.OnUnknownBranch)
}
}

private fun setBranchState(newState: BranchState) {
if (branchState != newState) {
val previousState = branchState
branchState = newState
lastBranchState = previousState

// Emit telemetry
Telemetry.track(BranchStateChangeEvent(newState.name))

Logger.info("Branch state changed from $previousState to $newState")
}
}

}