[gitlab] Fix missing items in changelist due to pagination links missing (IJPL-183235)

#IJPL-183235 Fixed

(cherry picked from commit db052c949fc3bd734000ec4b66dd352e61040deb)


(cherry picked from commit c68493b635b4a44597325dd8c3b1133bbc9880f1)

IJ-CR-161095

GitOrigin-RevId: 39edbd3bd9d59e7231b8efab1458b4c477ad8f9b
This commit is contained in:
Chris Lemaire
2025-04-16 14:28:45 +00:00
committed by intellij-monorepo-bot
parent 46b55e0720
commit b69afb1170
4 changed files with 38 additions and 12 deletions

View File

@@ -8,12 +8,15 @@ import com.intellij.collaboration.util.URIUtil
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.fold
import org.jetbrains.annotations.ApiStatus
import java.net.URI
import java.net.http.HttpResponse
object ApiPageUtil {
fun <T> createGQLPagesFlow(reversed: Boolean = false,
loader: suspend (GraphQLRequestPagination) -> GraphQLPagedResponseDataDTO<T>?): Flow<GraphQLPagedResponseDataDTO<T>> =
fun <T> createGQLPagesFlow(
reversed: Boolean = false,
loader: suspend (GraphQLRequestPagination) -> GraphQLPagedResponseDataDTO<T>?,
): Flow<GraphQLPagedResponseDataDTO<T>> =
flow {
var pagination: GraphQLRequestPagination? = GraphQLRequestPagination.DEFAULT
while (pagination != null) {
@@ -57,6 +60,24 @@ object ApiPageUtil {
}
}
}
/**
* Prefer not to use this method!
* This is a last resort if Link headers are missing and you need paginated info.
* It's recommended to use the Link header in all other cases though.
*
* Careful: starts pagination at page=1 and increments from there.
*/
@ApiStatus.Internal
fun <T> createPagesFlowByPagination(loader: suspend (page: Int) -> HttpResponse<out List<T>>): Flow<HttpResponse<out List<T>>> =
flow {
var page = 1
do {
val data = loader(page++)
if (data.body().isNotEmpty()) emit(data)
}
while (data.body().isNotEmpty())
}
}
suspend fun <T> Flow<Iterable<T>>.foldToList(): List<T> = foldToList { it }

View File

@@ -4,6 +4,7 @@ package org.jetbrains.plugins.gitlab.mergerequest.api.request
import com.intellij.collaboration.api.json.loadJsonList
import com.intellij.collaboration.api.json.loadJsonValue
import com.intellij.collaboration.util.resolveRelative
import com.intellij.collaboration.util.withQuery
import org.jetbrains.plugins.gitlab.api.*
import org.jetbrains.plugins.gitlab.api.dto.GitLabCommitDetailedRestDTO
import org.jetbrains.plugins.gitlab.api.dto.GitLabCommitRestDTO
@@ -29,7 +30,7 @@ suspend fun GitLabApi.Rest.loadMergeRequestCommits(uri: URI): HttpResponse<out L
}
data class GitLabChangesHolderDTO(
val changes: List<GitLabDiffDTO>
val changes: List<GitLabDiffDTO>,
)
@SinceGitLab("9.0", deprecatedIn = "15.7", note = "Deprecated in favour of /diffs")
@@ -60,14 +61,15 @@ suspend fun GitLabApi.Rest.loadMergeRequestDiffs(uri: URI): HttpResponse<out Lis
}
@SinceGitLab("15.7")
suspend fun GitLabApi.getMergeRequestDiffsURI(project: GitLabProjectCoordinates, mrIid: String): URI {
suspend fun GitLabApi.getMergeRequestDiffsURI(project: GitLabProjectCoordinates, mrIid: String, page: Int): URI {
val metadata = getMetadataOrNull()
requireNotNull(metadata)
return project.restApiUri
.resolveRelative("merge_requests")
.resolveRelative(mrIid)
.resolveRelative("diffs")
.resolveRelative("merge_requests")
.resolveRelative(mrIid)
.resolveRelative("diffs")
.withQuery("page=$page")
}
@SinceGitLab("7.0")
@@ -87,8 +89,10 @@ fun getCommitDiffsURI(project: GitLabProjectCoordinates, commitSha: String): URI
.resolveRelative("diff")
@SinceGitLab("7.0")
suspend fun GitLabApi.Rest.loadCommit(project: GitLabProjectCoordinates,
commitSha: String): HttpResponse<out GitLabCommitDetailedRestDTO> {
suspend fun GitLabApi.Rest.loadCommit(
project: GitLabProjectCoordinates,
commitSha: String,
): HttpResponse<out GitLabCommitDetailedRestDTO> {
val uri = project.restApiUri
.resolveRelative("repository")
.resolveRelative("commits")

View File

@@ -107,8 +107,9 @@ class GitLabMergeRequestChangesImpl(
}.map { it.body().changes }.foldToList(GitLabDiffDTO::toPatch)
}
else {
ApiPageUtil.createPagesFlowByLinkHeader(api.getMergeRequestDiffsURI(glProject, mergeRequestDetails.iid)) {
api.rest.loadMergeRequestDiffs(it)
// doesn't send back Link headers...
ApiPageUtil.createPagesFlowByPagination { page ->
api.rest.loadMergeRequestDiffs(api.getMergeRequestDiffsURI(glProject, mergeRequestDetails.iid, page))
}.map { it.body() }.foldToList(GitLabDiffDTO::toPatch)
}
}

View File

@@ -66,7 +66,7 @@ class GitLabApiTest : GitLabApiTestCase() {
checkVersion(after(v(15, 7)))
requiresAuthentication { api ->
val diffs = api.rest.loadMergeRequestDiffs(api.getMergeRequestDiffsURI(glTest1Coordinates, "2")).body()
val diffs = api.rest.loadMergeRequestDiffs(api.getMergeRequestDiffsURI(glTest1Coordinates, "2", 1)).body()
assertEquals(glTest1Mr2ChangedFiles, diffs.map { it.newPath })
}