11package com.gabrielfeo.gradle.enterprise.api
22
3+ import com.gabrielfeo.gradle.enterprise.api.internal.API_MAX_BUILDS
4+ import com.gabrielfeo.gradle.enterprise.api.internal.operator.pagedUntilLastBuild
5+ import com.gabrielfeo.gradle.enterprise.api.internal.operator.withGradleAttributes
36import com.gabrielfeo.gradle.enterprise.api.model.*
47import kotlinx.coroutines.CoroutineScope
8+ import kotlinx.coroutines.DelicateCoroutinesApi
59import kotlinx.coroutines.GlobalScope
6- import kotlinx.coroutines.async
710import kotlinx.coroutines.flow.*
811import retrofit2.await
912
10- private const val API_MAX_BUILDS = 1000
11-
1213/* *
1314 * Gets builds on demand from the API, in as many requests as necessary. It allows
1415 * for queries of any size, as opposed to [GradleEnterpriseApi.getBuilds] which is limited by the
@@ -24,43 +25,17 @@ fun GradleEnterpriseApi.getBuildsFlow(
2425 fromInstant : Long? = null,
2526 fromBuild : String? = null,
2627): Flow <Build > = flow {
27- var lastBuildId: String? = null
28- while (true ) {
29- val call = when (lastBuildId) {
30- null -> getBuilds(
31- since = since, sinceBuild = sinceBuild,
32- fromInstant = fromInstant, fromBuild = fromBuild,
33- maxBuilds = API_MAX_BUILDS ,
34- )
35- else -> getBuilds(fromBuild = lastBuildId, maxBuilds = API_MAX_BUILDS )
36- }
37- val builds = call.await()
38- emitAll(builds.asFlow())
39- when {
40- builds.isEmpty() || builds.size < API_MAX_BUILDS -> break
41- else -> lastBuildId = builds.last().id
42- }
43- }
28+ val firstBuilds = getBuilds(
29+ since = since,
30+ sinceBuild = sinceBuild,
31+ fromInstant = fromInstant,
32+ fromBuild = fromBuild,
33+ maxBuilds = API_MAX_BUILDS ,
34+ ).await()
35+ val pagedBuilds = firstBuilds.asFlow().pagedUntilLastBuild(maxPerRequest = API_MAX_BUILDS )
36+ emitAll(pagedBuilds)
4437}
4538
46- /* *
47- * Joins builds with their [GradleAttributes], which comes from a different endpoint
48- * ([GradleEnterpriseApi.getGradleAttributes]).
49- *
50- * Don't expect client-side filtering to be efficient. Does as many concurrent calls
51- * as it can, requesting attributes in an eager coroutine, in [scope].
52- */
53- fun Flow<Build>.withGradleAttributes (
54- scope : CoroutineScope = GlobalScope ,
55- ): Flow <Pair <Build , GradleAttributes >> =
56- map { build ->
57- build to scope.async {
58- api.getGradleAttributes(build.id).await()
59- }
60- }.buffer(Int .MAX_VALUE ).map { (build, attrs) ->
61- build to attrs.await()
62- }
63-
6439/* *
6540 * Gets [GradleAttributes] of all builds from a given date. Queries [GradleEnterpriseApi.getBuilds]
6641 * first, since it's the only endpoint providing a timeline of builds, then maps each to
@@ -69,7 +44,10 @@ fun Flow<Build>.withGradleAttributes(
6944 * Don't expect client-side filtering to be efficient. Does as many concurrent calls
7045 * as it can, requesting attributes in an eager coroutine, in [scope]. For other params,
7146 * see [getBuildsFlow] and [GradleEnterpriseApi.getBuilds].
47+ *
48+ * @param scope CoroutineScope in which to create coroutines. Defaults to [GlobalScope].
7249 */
50+ @OptIn(DelicateCoroutinesApi ::class )
7351fun GradleEnterpriseApi.getGradleAttributesFlow (
7452 since : Long = 0,
7553 sinceBuild : String? = null,
0 commit comments