Skip to content

Commit

Permalink
fix:update filter
Browse files Browse the repository at this point in the history
  • Loading branch information
cunla committed Mar 7, 2024
1 parent 472dfe6 commit e2298ba
Show file tree
Hide file tree
Showing 7 changed files with 57 additions and 69 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -47,57 +47,40 @@ class WorkflowDataContextService(private val project: Project) {
toolWindow: ToolWindow,
): CompletableFuture<WorkflowRunSelectionContext> {
return repositories.getOrPut(repositoryMapping.remote.url) {
LazyCancellableBackgroundProcessValue.create { indicator ->
LazyCancellableBackgroundProcessValue.create(ProgressManager.getInstance()) { indicator ->
LOG.debug("Creating data context for ${repositoryMapping.remote.url}")
ProgressManager.getInstance().submitIOTask(indicator) {
try {
getContext(checkedDisposable, account, repositoryMapping, toolWindow)
} catch (e: Exception) {
if (e !is ProcessCanceledException)
LOG.warn("Error occurred while creating data context", e)
throw e
try {
val token = if (settingsService.state.useGitHubSettings) {
GHCompatibilityUtil.getOrRequestToken(account, toolWindow.project)
?: throw GithubMissingTokenException(account)
} else {
settingsService.state.apiToken
}
}.successOnEdt { ctx ->
LOG.debug("Registering context for ${repositoryMapping.remote.url}")
Disposer.register(toolWindow.disposable, ctx)
ctx

val requestExecutor = GithubApiRequestExecutor.Factory.getInstance().create(token = token)
val singleRunDataLoader = SingleRunDataLoader(requestExecutor)
if (checkedDisposable.isDisposed) {
throw ProcessCanceledException(
RuntimeException("Skipped creating data context for ${repositoryMapping.remote.url} because it was disposed")
)
}
WorkflowRunSelectionContext(
checkedDisposable,
toolWindow,
account,
singleRunDataLoader,
repositoryMapping,
requestExecutor,
)
} catch (e: Exception) {
if (e !is ProcessCanceledException)
LOG.warn("Error occurred while creating data context", e)
throw e
}
}
}.value
}

@RequiresBackgroundThread
@Throws(IOException::class)
private fun getContext(
checkedDisposable: CheckedDisposable,
account: GithubAccount,
repositoryMapping: GHGitRepositoryMapping,
toolWindow: ToolWindow,
): WorkflowRunSelectionContext {
val token = if (settingsService.state.useGitHubSettings) {
GHCompatibilityUtil.getOrRequestToken(account, toolWindow.project)
?: throw GithubMissingTokenException(account)
} else {
settingsService.state.apiToken
}

val requestExecutor = GithubApiRequestExecutor.Factory.getInstance().create(token = token)
val singleRunDataLoader = SingleRunDataLoader(requestExecutor)
if (checkedDisposable.isDisposed) {
throw ProcessCanceledException(
RuntimeException("Skipped creating data context for ${repositoryMapping.remote.url} because it was disposed")
)
}
return WorkflowRunSelectionContext(
checkedDisposable,
toolWindow,
account,
singleRunDataLoader,
repositoryMapping,
requestExecutor,
)
}

companion object {
private val LOG = logger<WorkflowDataContextService>()
fun getInstance(project: Project) = project.service<WorkflowDataContextService>()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import com.intellij.collaboration.async.CompletableFutureUtil
import com.intellij.collaboration.async.CompletableFutureUtil.handleOnEdt
import com.intellij.collaboration.async.CompletableFutureUtil.submitIOTask
import com.intellij.collaboration.ui.SimpleEventListener
import com.intellij.collaboration.util.ProgressIndicatorsProvider
import com.intellij.openapi.Disposable
import com.intellij.openapi.components.service
import com.intellij.openapi.diagnostic.logger
Expand All @@ -24,7 +25,6 @@ import org.jetbrains.plugins.github.api.GithubApiRequestExecutor
import org.jetbrains.plugins.github.api.GithubApiRequests
import org.jetbrains.plugins.github.api.data.GHUser
import org.jetbrains.plugins.github.api.data.request.GithubRequestPagination
import org.jetbrains.plugins.github.util.NonReusableEmptyProgressIndicator
import java.util.concurrent.CompletableFuture
import java.util.concurrent.ScheduledFuture
import kotlin.properties.Delegates
Expand All @@ -35,6 +35,7 @@ class WorkflowRunListLoader(
private val requestExecutor: GithubApiRequestExecutor,
private val repositoryCoordinates: RepositoryCoordinates,
private var filter: WorkflowRunFilter,
private val indicatorsProvider: ProgressIndicatorsProvider = ProgressIndicatorsProvider(),
) : Disposable {
private val settingsService = toolWindow.project.service<GhActionsSettingsService>()
val workflowRunsListModel = CollectionListModel<WorkflowRun>()
Expand All @@ -50,7 +51,6 @@ class WorkflowRunListLoader(
private val page: Int = 1
private val task: ScheduledFuture<*>
var refreshRuns: Boolean = true
private var progressIndicator = NonReusableEmptyProgressIndicator()
var error: Throwable? by Delegates.observable(null) { _, _, _ ->
errorChangeEventDispatcher.multicaster.eventOccurred()
}
Expand All @@ -62,6 +62,7 @@ class WorkflowRunListLoader(
init {
LOG.debug("Initialize WorkflowRunListLoader for ${repositoryCoordinates.repositoryPath}")
Disposer.register(parentDisposable, this)
Disposer.register(this, indicatorsProvider)
task = ToolbarUtil.executeTaskAtSettingsFrequency(toolWindow.project) {
if (refreshRuns && error == null) loadMore(update = true)
}
Expand All @@ -72,8 +73,7 @@ class WorkflowRunListLoader(
fun loadMore(update: Boolean = false) {
if (canLoadMore() || update) {
loading = true
requestLoadMore(progressIndicator, update).handleOnEdt { list, error ->
if (progressIndicator.isCanceled) return@handleOnEdt
requestLoadMore(update).handleOnEdt { list, error ->
loading = false
if (error != null) {
if (!CompletableFutureUtil.isCancellation(error)) this.error = error
Expand All @@ -85,15 +85,15 @@ class WorkflowRunListLoader(
}
}

private fun requestLoadMore(indicator: ProgressIndicator, update: Boolean): CompletableFuture<List<WorkflowRun>> {
private fun requestLoadMore(update: Boolean): CompletableFuture<List<WorkflowRun>> {
applyIf(repoCollaborators.isEmpty()) {
progressManager.submitIOTask(NonReusableEmptyProgressIndicator()) { updateCollaborators(it) }
progressManager.submitIOTask(indicatorsProvider) { updateCollaborators(it) }
}.applyIf(repoBranches.isEmpty()) {
progressManager.submitIOTask(NonReusableEmptyProgressIndicator()) { updateBranches(it) }
progressManager.submitIOTask(indicatorsProvider) { updateBranches(it) }
}.applyIf(workflowTypes.isEmpty()) {
progressManager.submitIOTask(NonReusableEmptyProgressIndicator()) { updateWorkflowTypes(it) }
progressManager.submitIOTask(indicatorsProvider) { updateWorkflowTypes(it) }
}
lastFuture = progressManager.submitIOTask(indicator) { doLoadMore(indicator, update) }
lastFuture = progressManager.submitIOTask(indicatorsProvider) { doLoadMore(it, update) }
return lastFuture
}

Expand Down Expand Up @@ -163,7 +163,6 @@ class WorkflowRunListLoader(
}

override fun dispose() {
progressIndicator.cancel()
task.cancel(true)
}

Expand All @@ -172,8 +171,6 @@ class WorkflowRunListLoader(
lastFuture = lastFuture.handle { _, _ ->
listOf()
}
progressIndicator.cancel()
progressIndicator = NonReusableEmptyProgressIndicator()
error = null
loading = false
workflowRunsListModel.removeAll()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ class GhActionsMgrToolWindowContent(val toolWindow: ToolWindow) : Disposable {

private var state: GhActionsMgrToolWindowState = GhActionsMgrToolWindowState.UNINITIALIZED
private var currentReposWithPanels: Set<GHGitRepositoryMapping> = emptySet()
private val checkedDisposable = Disposer.newCheckedDisposable(this, "GhActionsMgrToolWindowContent")

init {
val project = toolWindow.project
Expand All @@ -64,7 +63,7 @@ class GhActionsMgrToolWindowContent(val toolWindow: ToolWindow) : Disposable {


fun createContent() {
runInEdtAsync(checkedDisposable) {
ApplicationManager.getApplication().invokeLater {
val projectRepos = ghActionsService.knownRepositories
val countRepos = projectRepos.count {
settingsService.state.customRepos[it.remote.url]?.included ?: false
Expand All @@ -79,7 +78,7 @@ class GhActionsMgrToolWindowContent(val toolWindow: ToolWindow) : Disposable {
}
if (state == nextState && nextState != GhActionsMgrToolWindowState.REPOS) {
LOG.debug("createContent: state is the same, not updating")
return@runInEdtAsync
return@invokeLater
}
LOG.debug("createContent: state changed from $state to $nextState")
state = nextState
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ class WorkflowRunsListPanel(
val searchVm = WfRunsSearchPanelViewModel(scope, context)
scope.launch {
searchVm.searchState.collectLatest {
// context.updateFilter(it.toWorkflowRunFilter())
context.updateFilter(it.toWorkflowRunFilter())
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,22 @@ import com.intellij.openapi.wm.ToolWindow
import com.intellij.platform.ide.progress.runWithModalProgressBlocking
import com.intellij.testFramework.PlatformTestUtil
import com.intellij.testFramework.TestApplicationManager
import com.intellij.testFramework.common.initTestApplication
import com.intellij.testFramework.junit5.RunInEdt
import com.intellij.testFramework.junit5.TestApplication
import com.intellij.testFramework.registerServiceInstance
import com.intellij.testFramework.rules.ProjectModelExtension
import com.intellij.testFramework.waitUntil
import com.intellij.toolWindow.ToolWindowHeadlessManagerImpl
import com.intellij.util.concurrency.annotations.RequiresEdt
import com.intellij.util.ui.UIUtil
import io.mockk.every
import io.mockk.mockk
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.yield
import org.jetbrains.plugins.github.api.GithubServerPath
import org.jetbrains.plugins.github.authentication.accounts.GHAccountManager
Expand All @@ -34,8 +37,10 @@ import org.junit.jupiter.api.TestInfo
import org.junit.jupiter.api.extension.RegisterExtension

@RunInEdt(writeIntent = true)
@TestApplication
abstract class GitHubActionsManagerBaseTest {
init {
initTestApplication()
}

private val host: GithubServerPath = GithubServerPath.from("github.com")
private lateinit var testInfo: TestInfo
Expand All @@ -48,7 +53,7 @@ abstract class GitHubActionsManagerBaseTest {
protected lateinit var toolWindowContent: GhActionsMgrToolWindowContent

@BeforeEach
open fun beforeEach(testInfo: TestInfo) {
open fun setUp(testInfo: TestInfo) {
this.testInfo = testInfo
val toolWindowManager = ToolWindowHeadlessManagerImpl(projectRule.project)
toolWindow = toolWindowManager.doRegisterToolWindow("GitHub Actions")
Expand Down Expand Up @@ -106,6 +111,7 @@ fun executeSomeCoroutineTasksAndDispatchAllInvocationEvents(project: Project) {
runWithModalProgressBlocking(project, "") {
yield()
}
UIUtil.dispatchAllInvocationEvents()
PlatformTestUtil.dispatchAllInvocationEventsInIdeEventQueue()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import com.dsoftware.ghmanager.data.WorkflowDataContextService
import com.dsoftware.ghmanager.ui.GhActionsMgrToolWindowContent
import com.dsoftware.ghmanager.ui.panels.wfruns.WorkflowRunsListPanel
import com.intellij.openapi.components.service
import com.intellij.testFramework.waitUntil
import com.intellij.ui.OnePixelSplitter
import io.mockk.MockKMatcherScope
import io.mockk.every
Expand Down Expand Up @@ -41,8 +42,8 @@ class TestRepoTabControllerWorkflowRunsPanel : GitHubActionsManagerBaseTest() {
}

@BeforeEach
override fun beforeEach(testInfo: TestInfo) {
super.beforeEach(testInfo)
override fun setUp(testInfo: TestInfo) {
super.setUp(testInfo)
mockGhActionsService(setOf("http://github.com/owner/repo"), setOf("account1"))
toolWindowContent = GhActionsMgrToolWindowContent(toolWindow)
executeSomeCoroutineTasksAndDispatchAllInvocationEvents(projectRule.project)
Expand Down Expand Up @@ -132,16 +133,18 @@ class TestRepoTabControllerWorkflowRunsPanel : GitHubActionsManagerBaseTest() {
val workflowDataContextService = projectRule.project.service<WorkflowDataContextService>()
Assertions.assertEquals(1, workflowDataContextService.repositories.size)
executeSomeCoroutineTasksAndDispatchAllInvocationEvents(projectRule.project)
verify(atLeast = 1) {
verify(atLeast = 1, timeout = 3000) {
executorMock.execute(any(), matchApiRequestUrl<WorkflowRuns>("/actions/runs")).hint(WorkflowRuns::class)
executorMock.execute(
any(), matchApiRequestUrl<GithubResponsePage<GithubUserWithPermissions>>("/collaborators")
)
executorMock.execute(any(), matchApiRequestUrl<GithubResponsePage<GithubBranch>>("/branches"))
executorMock.execute(any(), matchApiRequestUrl<WorkflowTypes>("/actions/workflows"))
}
executeSomeCoroutineTasksAndDispatchAllInvocationEvents(projectRule.project)
executeSomeCoroutineTasksAndDispatchAllInvocationEvents(projectRule.project)
Assertions.assertEquals(1, (tabWrapPanel.components[0] as JPanel).componentCount)
Assertions.assertTrue((tabWrapPanel.components[0] as JPanel).components[0] is OnePixelSplitter)
Assertions.assertTrue((tabWrapPanel.components[0] as JPanel).components[0] is OnePixelSplitter, "Expected tab to have OnePixelSplitter")
val splitterComponent = ((tabWrapPanel.components[0] as JPanel).components[0] as OnePixelSplitter)
Assertions.assertEquals(3, splitterComponent.componentCount)
Assertions.assertTrue(splitterComponent.firstComponent is WorkflowRunsListPanel)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ class ToolWindowFactoryTest : GitHubActionsManagerBaseTest() {
private lateinit var requestExecutorfactoryMock: GithubApiRequestExecutor.Factory

@BeforeEach
override fun beforeEach(testInfo: TestInfo) {
super.beforeEach(testInfo)
override fun setUp(testInfo: TestInfo) {
super.setUp(testInfo)
requestExecutorfactoryMock.apply {
every { create(token = any()) } throws Exception("No executor")
}
Expand Down

0 comments on commit e2298ba

Please sign in to comment.