15
15
*/
16
16
package com.google.firebase.gradle.plugins.report
17
17
18
- import com.google.gson.Gson
19
- import com.google.gson.GsonBuilder
20
- import com.google.gson.JsonArray
21
- import com.google.gson.JsonElement
22
- import com.google.gson.JsonObject
18
+ import kotlinx.serialization.json.Json
19
+ import kotlinx.serialization.json.JsonArray
20
+ import kotlinx.serialization.json.JsonElement
21
+ import kotlinx.serialization.json.JsonObject
23
22
import java.io.FileWriter
24
23
import java.io.IOException
25
24
import java.net.URI
@@ -30,6 +29,8 @@ import java.time.Duration
30
29
import java.util.regex.Matcher
31
30
import java.util.regex.Pattern
32
31
import org.gradle.internal.Pair
32
+ import java.util.stream.Stream
33
+ import kotlin.streams.toList
33
34
34
35
@SuppressWarnings(" NewApi" )
35
36
class UnitTestReport (private val apiToken : String ) {
@@ -40,19 +41,17 @@ class UnitTestReport(private val apiToken: String) {
40
41
val response = request(" commits?per_page=$commitCount " , JsonArray ::class .java)
41
42
val commits =
42
43
response
43
- .getAsJsonArray()
44
- .asList()
45
44
.stream()
46
45
.limit(commitCount.toLong())
47
46
.map { el: JsonElement ->
48
- val obj = el.getAsJsonObject()
47
+ val obj = el as JsonObject
49
48
var pr = - 1
50
49
val matcher: Matcher =
51
- PR_NUMBER_MATCHER .matcher(obj.getAsJsonObject( " commit" ).get( " message" ).asString )
50
+ PR_NUMBER_MATCHER .matcher((obj[ " commit" ] as JsonObject )[ " message" ].toString() )
52
51
if (matcher.find()) {
53
52
pr = matcher.group(1 ).toInt()
54
53
}
55
- ReportCommit (obj.get( " sha" ).asString , pr)
54
+ ReportCommit (obj[ " sha" ].toString() , pr)
56
55
}
57
56
.toList()
58
57
outputReport(commits)
@@ -173,11 +172,11 @@ class UnitTestReport(private val apiToken: String) {
173
172
174
173
private fun parseTestReports (commit : String ): List <TestReport > {
175
174
val runs = request(" actions/runs?head_sha=" + commit)
176
- for (el in runs.getAsJsonArray( " workflow_runs" ) ) {
177
- val run = el.getAsJsonObject()
178
- val name = run.get( " name" ).getAsString ()
175
+ for (el in runs[ " workflow_runs" ] as JsonArray ) {
176
+ val run = el as JsonObject
177
+ val name = run[ " name" ].toString ()
179
178
if (name == " CI Tests" ) {
180
- return parseCITests(run.get( " id" ).getAsString (), commit)
179
+ return parseCITests(run[ " id" ].toString (), commit)
181
180
}
182
181
}
183
182
return listOf ()
@@ -186,9 +185,9 @@ class UnitTestReport(private val apiToken: String) {
186
185
private fun parseCITests (id : String , commit : String ): List <TestReport > {
187
186
val reports: MutableList <TestReport > = ArrayList ()
188
187
val jobs = request(" actions/runs/" + id + " /jobs" )
189
- for (el in jobs.getAsJsonArray( " jobs" ) ) {
190
- val job = el.getAsJsonObject()
191
- val jid = job.get( " name" ).getAsString ()
188
+ for (el in jobs[ " jobs" ] as JsonArray ) {
189
+ val job = el as JsonObject
190
+ val jid = job[ " name" ].toString ()
192
191
if (jid.startsWith(" Unit Tests (:" )) {
193
192
reports.add(parseJob(TestReport .Type .UNIT_TEST , job, commit))
194
193
} else if (jid.startsWith(" Instrumentation Tests (:" )) {
@@ -200,22 +199,21 @@ class UnitTestReport(private val apiToken: String) {
200
199
201
200
private fun parseJob (type : TestReport .Type , job : JsonObject , commit : String ): TestReport {
202
201
var name =
203
- job
204
- .get(" name" )
205
- .getAsString()
202
+ job[" name" ]
203
+ .toString()
206
204
.split(" \\ (:" .toRegex())
207
205
.dropLastWhile { it.isEmpty() }
208
206
.toTypedArray()[1 ]
209
207
name = name.substring(0 , name.length - 1 ) // Remove trailing ")"
210
208
var status = TestReport .Status .OTHER
211
- if (job.get( " status" ).asString == " completed" ) {
212
- if (job.get( " conclusion" ).asString == " success" ) {
209
+ if (job[ " status" ].toString() == " completed" ) {
210
+ if (job[ " conclusion" ].toString() == " success" ) {
213
211
status = TestReport .Status .SUCCESS
214
212
} else {
215
213
status = TestReport .Status .FAILURE
216
214
}
217
215
}
218
- val url = job.get( " html_url" ).getAsString ()
216
+ val url = job[ " html_url" ].toString ()
219
217
return TestReport (name, type, status, commit, url)
220
218
}
221
219
@@ -245,10 +243,14 @@ class UnitTestReport(private val apiToken: String) {
245
243
System .err.println (response)
246
244
System .err.println (body)
247
245
}
248
- val json: T = GSON .fromJson(body, clazz)
246
+ val json = when (clazz) {
247
+ JsonObject ::class .java -> Json .decodeFromString<JsonObject >(body)
248
+ JsonArray ::class .java -> Json .decodeFromString<JsonArray >(body)
249
+ else -> throw IllegalArgumentException ()
250
+ }
249
251
if (json is JsonObject ) {
250
252
// Retrieve and merge objects from other pages, if present
251
- response.headers().firstValue(" Link" ).ifPresent { link: String ->
253
+ return response.headers().firstValue(" Link" ).map { link: String ->
252
254
val parts = link.split(" ," .toRegex()).dropLastWhile { it.isEmpty() }
253
255
for (part in parts) {
254
256
if (part.endsWith(" rel=\" next\" " )) {
@@ -262,17 +264,20 @@ class UnitTestReport(private val apiToken: String) {
262
264
.dropLastWhile { it.isEmpty() }
263
265
.toTypedArray()[1 ]
264
266
val p = request<JsonObject >(URI .create(url), JsonObject ::class .java)
265
- for (key in json.keySet()) {
266
- if (json.get(key).isJsonArray && p.has(key) && p.get(key).isJsonArray) {
267
- json.getAsJsonArray(key).addAll(p.getAsJsonArray(key))
267
+ return @map JsonObject (json.keys.associateWith {
268
+ key: String ->
269
+
270
+ if (json[key] is JsonArray && p.containsKey(key) && p[key] is JsonArray ) {
271
+ JsonArray (Stream .concat((json[key] as JsonArray ).stream(), (p[key] as JsonArray ).stream()).toList())
268
272
}
269
- }
270
- break
273
+ json[key] !!
274
+ })
271
275
}
272
276
}
273
- }
277
+ return @map json
278
+ }.orElse(json) as T
274
279
}
275
- return json
280
+ return json as T
276
281
} catch (e: IOException ) {
277
282
throw RuntimeException (e)
278
283
} catch (e: InterruptedException ) {
@@ -281,8 +286,10 @@ class UnitTestReport(private val apiToken: String) {
281
286
}
282
287
283
288
companion object {
289
+ /*
290
+ * Matches commit names for their PR number generated by GitHub, eg, `foo bar (#1234)`.
291
+ */
284
292
private val PR_NUMBER_MATCHER : Pattern = Pattern .compile(" .*\\ (#([0-9]+)\\ )" )
285
293
private const val URL_PREFIX = " https://api.github.com/repos/firebase/firebase-android-sdk/"
286
- private val GSON : Gson = GsonBuilder ().create()
287
294
}
288
295
}
0 commit comments