Repository navigation
IntelliJ stability update #50
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 4 commits
38e8d2b
226e840
4f6ab88
b7cde80
e61091a
1cbd63b
bdc9c22
2266d28
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,15 +5,18 @@ import com.codacy.intellij.plugin.services.agent.model.Provider | |
| import com.codacy.intellij.plugin.services.api.Api | ||
| import com.codacy.intellij.plugin.services.cli.CodacyCliService | ||
| import com.codacy.intellij.plugin.services.common.Config | ||
| import com.codacy.intellij.plugin.services.common.Logger | ||
| import com.codacy.intellij.plugin.services.common.GitRemoteParser | ||
| import com.codacy.intellij.plugin.services.common.IconUtils | ||
| import com.codacy.intellij.plugin.services.git.GitProvider | ||
| import com.codacy.intellij.plugin.services.git.RepositoryManager | ||
| import com.codacy.intellij.plugin.telemetry.ExtensionInstalledEvent | ||
| import com.codacy.intellij.plugin.telemetry.Telemetry | ||
| import com.intellij.ide.plugins.DynamicPluginListener | ||
| import com.intellij.openapi.Disposable | ||
| import com.intellij.openapi.components.service | ||
| import com.intellij.openapi.project.Project | ||
| import com.intellij.openapi.util.Disposer | ||
| import com.intellij.openapi.startup.StartupActivity | ||
| import com.intellij.openapi.vfs.VirtualFileManager | ||
| import com.intellij.openapi.vfs.newvfs.BulkFileListener | ||
|
|
@@ -26,12 +29,26 @@ class StartupListener : StartupActivity { | |
|
|
||
| companion object { | ||
| private const val MIN_REFRESH_INTERVAL_MS = 5000L | ||
| private val activeScopes = java.util.Collections.synchronizedList(mutableListOf<CoroutineScope>()) | ||
|
|
||
| fun cancelAllScopes() { | ||
| synchronized(activeScopes) { | ||
| activeScopes.forEach { it.cancel() } | ||
| activeScopes.clear() | ||
| } | ||
| } | ||
| } | ||
|
|
||
| private var lastTriggeredTime = 0L | ||
|
|
||
| @OptIn(DelicateCoroutinesApi::class) | ||
| override fun runActivity(project: Project) { | ||
| val scope = CoroutineScope(SupervisorJob() + Dispatchers.IO) | ||
| activeScopes.add(scope) | ||
| Disposer.register(project, Disposable { | ||
| scope.cancel() | ||
| activeScopes.remove(scope) | ||
| }) | ||
|
|
||
| // Check for first installation | ||
| val config = Config.instance | ||
| if (config.state.isFirstRun) { | ||
|
|
@@ -50,7 +67,7 @@ class StartupListener : StartupActivity { | |
| connection.subscribe(GitRepository.GIT_REPO_CHANGE, GitRepositoryChangeListener { repository -> | ||
|
|
||
|
|
||
| val gitResult = initializeGit(project) | ||
| val gitResult = initializeGit(project, scope) | ||
| val repositoryManager = gitResult.first | ||
| val gitInfo = gitResult.second | ||
|
|
||
|
|
@@ -60,19 +77,30 @@ class StartupListener : StartupActivity { | |
|
|
||
| AiAgentService.getService(project) | ||
|
|
||
| GlobalScope.launch { | ||
| Api().listTools() | ||
| scope.launch { | ||
| try { | ||
| service<Api>().listTools() | ||
| } catch (e: Exception) { | ||
| Logger.warn("Failed to load tools: ${e.message}") | ||
| } | ||
| } | ||
|
|
||
| if (repository.currentBranch != null) { | ||
| CoroutineScope(Dispatchers.Default).launch { | ||
| scope.launch { | ||
| repositoryManager.handleStateChange() | ||
| } | ||
| } else { | ||
| repositoryManager.notifyDidChangeConfig() | ||
| } | ||
| }) | ||
|
|
||
| // Perform initial startup initialization without waiting for a git change event | ||
| val gitRepository = GitProvider.getRepository(project) | ||
| if (gitRepository != null) { | ||
| val repositoryManager = project.service<RepositoryManager>() | ||
| scope.launch { repositoryManager.open(gitRepository) } | ||
| } | ||
|
|
||
| connection.subscribe(VirtualFileManager.VFS_CHANGES, object : BulkFileListener { | ||
| private fun handle(events: List<VFileEvent>) { | ||
| val now = System.currentTimeMillis() | ||
|
|
@@ -95,12 +123,11 @@ class StartupListener : StartupActivity { | |
| }) | ||
| } | ||
|
|
||
| @OptIn(DelicateCoroutinesApi::class) | ||
| private fun initializeGit(project: Project): Pair<RepositoryManager, GitRemoteParser.GitRemoteInfo> { | ||
| private fun initializeGit(project: Project, scope: CoroutineScope): Pair<RepositoryManager, GitRemoteParser.GitRemoteInfo> { | ||
| val gitRepository = GitProvider.getRepository(project) | ||
| val repositoryManager = project.service<RepositoryManager>() | ||
| if (gitRepository != null && repositoryManager.currentRepository != gitRepository) | ||
| GlobalScope.launch { repositoryManager.open(gitRepository) } | ||
| scope.launch { repositoryManager.open(gitRepository) } | ||
|
|
||
| val remote = gitRepository?.remotes?.firstOrNull() | ||
| ?: throw IllegalStateException("No remote found in the Git repository") | ||
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -13,7 +13,7 @@ import java.io.InputStreamReader | |
| import java.net.HttpURLConnection | ||
| import java.net.URL | ||
|
|
||
| @Service | ||
| @Service(Service.Level.APP) | ||
| class Api { | ||
|
|
||
| private val config = service<Config>() | ||
|
|
@@ -47,15 +47,13 @@ class Api { | |
| Gson().fromJson(response, responseClass) | ||
| } | ||
| } else { | ||
| Logger.error("Failed to fetch data: HTTP response code $responseCode") | ||
| if (responseCode == HttpURLConnection.HTTP_UNAUTHORIZED) | ||
| config.storeApiToken("") | ||
| throw Exception("Failed to fetch data: HTTP response code $responseCode") | ||
| } | ||
|
Comment on lines
49
to
53
|
||
| } | ||
| catch (e: Exception) { | ||
|
lventura-codacy marked this conversation as resolved.
|
||
| Logger.error("Failed to fetch data: ${e.message}") | ||
| responseClass.newInstance() | ||
| throw Exception("Failed to fetch data: ${e.message}", e) | ||
| } | ||
|
lventura-codacy marked this conversation as resolved.
|
||
| } | ||
| } | ||
|
|
@@ -131,7 +129,7 @@ class Api { | |
| return try { | ||
| makeRequest(endpointUrl, GetUserProfileResponse::class.java).data | ||
| } catch (e: Exception) { | ||
| Logger.error("Failed to fetch user profile: ${e.message}") | ||
| Logger.warn("Failed to fetch user profile: ${e.message}") | ||
| null | ||
| } | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,6 +7,7 @@ import com.codacy.intellij.plugin.services.git.RepositoryManager.RepositoryManag | |
| import kotlinx.coroutines.* | ||
| import com.intellij.notification.* | ||
| import com.intellij.openapi.components.Service | ||
| import com.intellij.openapi.components.service | ||
| import com.intellij.openapi.fileEditor.FileEditorManager | ||
| import com.intellij.openapi.progress.ProgressManager | ||
| import com.intellij.openapi.progress.Task | ||
|
|
@@ -32,7 +33,7 @@ class PullRequest( | |
| var files: List<FileDetails> = mutableListOf() | ||
| var gates: QualitySettingsData? = null | ||
| private val refreshTimeout: TimeoutManager = TimeoutManager() | ||
| private val api = Api() | ||
| private val api = service<Api>() | ||
| private var repositoryManager: RepositoryManager? = null | ||
|
Comment on lines
35
to
37
|
||
|
|
||
| fun init( | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
initializeGit(project, scope)can throw (e.g., when no Git remote is configured). Since this call is inside the repository change listener without a try/catch, an exception here can abort the listener and spam IDE logs. Wrap this initialization in error handling and fall back to a safe state (e.g., skip starting services / setRepositoryManagertoNoGitRepository).