|
| 1 | +package dev.isxander.debugify |
| 2 | + |
| 3 | +import com.google.gson.Gson |
| 4 | +import com.google.gson.JsonSyntaxException |
| 5 | +import org.gradle.api.DefaultTask |
| 6 | +import org.gradle.api.GradleException |
| 7 | +import org.gradle.api.provider.ListProperty |
| 8 | +import org.gradle.api.provider.Property |
| 9 | +import org.gradle.api.tasks.Input |
| 10 | +import org.gradle.api.tasks.TaskAction |
| 11 | +import org.gradle.work.DisableCachingByDefault |
| 12 | +import java.net.URI |
| 13 | + |
| 14 | +@DisableCachingByDefault(because = "Checks live Mojira and Minecraft version metadata") |
| 15 | +abstract class CheckBugFixesTask : DefaultTask() { |
| 16 | + @get:Input |
| 17 | + abstract val minecraftVersion: Property<String> |
| 18 | + |
| 19 | + @get:Input |
| 20 | + abstract val bugs: ListProperty<PatchedFileEntry> |
| 21 | + |
| 22 | + @TaskAction |
| 23 | + fun checkBugFixes() { |
| 24 | + val versionManifest = fetchVersionManifest() |
| 25 | + val targetVersion = minecraftVersion.get() |
| 26 | + val targetVersionIndex = versionManifest.indexOfVersion(targetVersion) |
| 27 | + ?: throw GradleException("Minecraft version $targetVersion was not found in Mojang's version manifest") |
| 28 | + |
| 29 | + var resolvedCount = 0 |
| 30 | + var duplicateCount = 0 |
| 31 | + |
| 32 | + bugs.get().filterIsInstance<PatchedFileEntry.Patched>().forEach { entry -> |
| 33 | + val mojiraBug = MojiraBug.fetch(entry.bugId) |
| 34 | + if (mojiraBug == null) { |
| 35 | + logger.warn("Failed to fetch ${entry.bugId}") |
| 36 | + return@forEach |
| 37 | + } |
| 38 | + |
| 39 | + val fixVersions = mojiraBug.fix_versions.orEmpty().map(::normaliseFixVersion) |
| 40 | + when (mojiraBug.resolution) { |
| 41 | + "Fixed", "Won't Fix", "Works As Intended" -> { |
| 42 | + var shouldRemove = true |
| 43 | + val isFutureOrUnknown = fixVersions.isEmpty() || |
| 44 | + fixVersions.any { it == "Future Update" } || |
| 45 | + fixVersions.all { fixVersion -> |
| 46 | + val fixVersionIndex = versionManifest.indexOfVersion(fixVersion) |
| 47 | + fixVersionIndex == null || fixVersionIndex < targetVersionIndex |
| 48 | + } |
| 49 | + |
| 50 | + if (isFutureOrUnknown) { |
| 51 | + shouldRemove = false |
| 52 | + } |
| 53 | + |
| 54 | + val status = buildString { |
| 55 | + append(mojiraBug.resolution) |
| 56 | + if (fixVersions.isNotEmpty()) { |
| 57 | + append(" in ") |
| 58 | + append(fixVersions.joinToString()) |
| 59 | + } |
| 60 | + } |
| 61 | + |
| 62 | + if (shouldRemove) { |
| 63 | + resolvedCount++ |
| 64 | + logger.error("${entry.bugId} (${entry.env.name.lowercase()}): $status") |
| 65 | + } else { |
| 66 | + logger.warn("${entry.bugId} (${entry.env.name.lowercase()}): $status") |
| 67 | + } |
| 68 | + } |
| 69 | + "Duplicate" -> { |
| 70 | + duplicateCount++ |
| 71 | + logger.warn("${entry.bugId} (${entry.env.name.lowercase()}): Duplicate") |
| 72 | + } |
| 73 | + else -> logger.lifecycle("${entry.bugId} (${entry.env.name.lowercase()}): OK!") |
| 74 | + } |
| 75 | + } |
| 76 | + |
| 77 | + if (resolvedCount == 0 && duplicateCount == 0) { |
| 78 | + logger.lifecycle("") |
| 79 | + logger.lifecycle("Nothing to report!") |
| 80 | + return |
| 81 | + } |
| 82 | + |
| 83 | + logger.lifecycle("") |
| 84 | + if (duplicateCount > 0) { |
| 85 | + logger.warn("$duplicateCount ${"bug".pluralise(duplicateCount)} ${if (duplicateCount == 1) "has" else "have"} been marked as duplicate!") |
| 86 | + } |
| 87 | + if (resolvedCount > 0) { |
| 88 | + throw GradleException("$resolvedCount ${"bug".pluralise(resolvedCount)} ${if (resolvedCount == 1) "needs" else "need"} removing!") |
| 89 | + } |
| 90 | + } |
| 91 | + |
| 92 | + private fun fetchVersionManifest(): VersionManifest { |
| 93 | + val url = "https://piston-meta.mojang.com/mc/game/version_manifest_v2.json" |
| 94 | + return try { |
| 95 | + Gson().fromJson(URI(url).toURL().readText(), VersionManifest::class.java) |
| 96 | + } catch (e: JsonSyntaxException) { |
| 97 | + throw GradleException("Failed to parse Minecraft version manifest <$url>", e) |
| 98 | + } catch (e: Exception) { |
| 99 | + throw GradleException("Failed to fetch Minecraft version manifest <$url>", e) |
| 100 | + } |
| 101 | + } |
| 102 | + |
| 103 | + private fun VersionManifest.indexOfVersion(version: String): Int? = |
| 104 | + versions.indexOfFirst { it.id == version }.takeIf { it >= 0 } |
| 105 | + |
| 106 | + private fun normaliseFixVersion(version: String): String = |
| 107 | + version |
| 108 | + .replace(" Pre-release ", "-pre") |
| 109 | + .replace(" Release Candidate ", "-rc") |
| 110 | + .replace(" Snapshot ", "-snapshot-") |
| 111 | + .replace("Minecraft ", "") |
| 112 | + |
| 113 | + private fun String.pluralise(count: Int): String = |
| 114 | + if (count == 1) this else "${this}s" |
| 115 | + |
| 116 | + private data class VersionManifest(val versions: List<Version>) |
| 117 | + |
| 118 | + private data class Version(val id: String) |
| 119 | +} |
0 commit comments