mirror of
https://github.com/ReVanced/revanced-patches.git
synced 2024-11-10 01:01:56 +01:00
fix: parse any kind of patch version
Signed-off-by: oSumAtrIX <johan.melkonyan1@web.de>
This commit is contained in:
parent
81934efb39
commit
66cd88f4d8
11 changed files with 165 additions and 188 deletions
|
@ -53,7 +53,7 @@ tasks {
|
||||||
dependsOn(build)
|
dependsOn(build)
|
||||||
|
|
||||||
classpath = sourceSets["main"].runtimeClasspath
|
classpath = sourceSets["main"].runtimeClasspath
|
||||||
mainClass.set("app.revanced.meta.Meta")
|
mainClass.set("app.revanced.meta.PatchesFileGenerator")
|
||||||
}
|
}
|
||||||
// Dummy task to fix the Gradle semantic-release plugin.
|
// Dummy task to fix the Gradle semantic-release plugin.
|
||||||
// Remove this if you forked it to support building only.
|
// Remove this if you forked it to support building only.
|
||||||
|
|
70
src/main/kotlin/app/revanced/meta/JsonGenerator.kt
Normal file
70
src/main/kotlin/app/revanced/meta/JsonGenerator.kt
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
package app.revanced.meta
|
||||||
|
|
||||||
|
import app.revanced.patcher.extensions.PatchExtensions.compatiblePackages
|
||||||
|
import app.revanced.patcher.extensions.PatchExtensions.dependencies
|
||||||
|
import app.revanced.patcher.extensions.PatchExtensions.description
|
||||||
|
import app.revanced.patcher.extensions.PatchExtensions.include
|
||||||
|
import app.revanced.patcher.extensions.PatchExtensions.options
|
||||||
|
import app.revanced.patcher.extensions.PatchExtensions.patchName
|
||||||
|
import app.revanced.patcher.extensions.PatchExtensions.version
|
||||||
|
import app.revanced.patcher.patch.PatchOption
|
||||||
|
import com.google.gson.GsonBuilder
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
internal class JsonGenerator : PatchesFileGenerator {
|
||||||
|
override fun generate(bundle: PatchBundlePatches) {
|
||||||
|
val patches = bundle.map {
|
||||||
|
JsonPatch(
|
||||||
|
it.patchName,
|
||||||
|
it.description ?: "This patch has no description.",
|
||||||
|
it.version ?: "0.0.0",
|
||||||
|
!it.include,
|
||||||
|
it.options?.map { option ->
|
||||||
|
Option(
|
||||||
|
option.key,
|
||||||
|
option.title,
|
||||||
|
option.description,
|
||||||
|
option.required,
|
||||||
|
option.let { lo ->
|
||||||
|
if (lo is PatchOption.ListOption<*>) {
|
||||||
|
lo.options.toMutableList().toTypedArray()
|
||||||
|
} else null
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}?.toTypedArray() ?: emptyArray(),
|
||||||
|
it.dependencies?.map { dep ->
|
||||||
|
dep.java.patchName
|
||||||
|
}?.toTypedArray() ?: emptyArray(),
|
||||||
|
it.compatiblePackages?.map { pkg ->
|
||||||
|
CompatiblePackage(pkg.name, pkg.versions)
|
||||||
|
}?.toTypedArray() ?: emptyArray()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
val json = File("patches.json")
|
||||||
|
json.writeText(GsonBuilder().serializeNulls().create().toJson(patches))
|
||||||
|
}
|
||||||
|
|
||||||
|
data class JsonPatch(
|
||||||
|
val name: String,
|
||||||
|
val description: String,
|
||||||
|
val version: String,
|
||||||
|
val excluded: Boolean,
|
||||||
|
val options: Array<Option>,
|
||||||
|
val dependencies: Array<String>,
|
||||||
|
val compatiblePackages: Array<CompatiblePackage>,
|
||||||
|
)
|
||||||
|
|
||||||
|
data class CompatiblePackage(
|
||||||
|
val name: String,
|
||||||
|
val versions: Array<String>,
|
||||||
|
)
|
||||||
|
|
||||||
|
data class Option(
|
||||||
|
val key: String,
|
||||||
|
val title: String,
|
||||||
|
val description: String,
|
||||||
|
val required: Boolean,
|
||||||
|
val choices: Array<*>?,
|
||||||
|
)
|
||||||
|
}
|
|
@ -1,27 +0,0 @@
|
||||||
package app.revanced.meta
|
|
||||||
|
|
||||||
import app.revanced.meta.json.generateJson
|
|
||||||
import app.revanced.meta.readme.generateText
|
|
||||||
import app.revanced.patcher.data.Context
|
|
||||||
import app.revanced.patcher.patch.Patch
|
|
||||||
import app.revanced.patcher.util.patch.PatchBundle
|
|
||||||
import java.io.File
|
|
||||||
|
|
||||||
typealias Bundle = List<Class<out Patch<Context>>>
|
|
||||||
|
|
||||||
object Meta {
|
|
||||||
@JvmStatic
|
|
||||||
fun main(args: Array<String>) {
|
|
||||||
val patches = accumulatePatches()
|
|
||||||
if (patches.isEmpty()) throw IllegalStateException("No patches found")
|
|
||||||
|
|
||||||
generateText(patches)
|
|
||||||
generateJson(patches)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun accumulatePatches() = PatchBundle.Jar(
|
|
||||||
File("build/libs/").listFiles()!!.first {
|
|
||||||
it.name.startsWith("revanced-patches-") && it.name.endsWith(".jar")
|
|
||||||
}.absolutePath
|
|
||||||
).loadPatches()
|
|
25
src/main/kotlin/app/revanced/meta/PatchesFileGenerator.kt
Normal file
25
src/main/kotlin/app/revanced/meta/PatchesFileGenerator.kt
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
package app.revanced.meta
|
||||||
|
|
||||||
|
import app.revanced.patcher.data.Context
|
||||||
|
import app.revanced.patcher.patch.Patch
|
||||||
|
import app.revanced.patcher.util.patch.PatchBundle
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
typealias PatchBundlePatches = List<Class<out Patch<Context>>>
|
||||||
|
|
||||||
|
internal interface PatchesFileGenerator {
|
||||||
|
fun generate(bundle: PatchBundlePatches)
|
||||||
|
|
||||||
|
private companion object {
|
||||||
|
@JvmStatic
|
||||||
|
fun main(args: Array<String>) = PatchBundle.Jar(
|
||||||
|
File("build/libs/").listFiles()!!.first {
|
||||||
|
it.name.startsWith("revanced-patches-") && it.name.endsWith(".jar")
|
||||||
|
}.absolutePath
|
||||||
|
).loadPatches().also {
|
||||||
|
if (it.isEmpty()) throw IllegalStateException("No patches found")
|
||||||
|
}.let { bundle ->
|
||||||
|
arrayOf(JsonGenerator(), ReadmeGenerator()).forEach { it.generate(bundle) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
69
src/main/kotlin/app/revanced/meta/ReadmeGenerator.kt
Normal file
69
src/main/kotlin/app/revanced/meta/ReadmeGenerator.kt
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
package app.revanced.meta
|
||||||
|
|
||||||
|
import app.revanced.patcher.data.Context
|
||||||
|
import app.revanced.patcher.extensions.PatchExtensions.compatiblePackages
|
||||||
|
import app.revanced.patcher.extensions.PatchExtensions.description
|
||||||
|
import app.revanced.patcher.extensions.PatchExtensions.patchName
|
||||||
|
import app.revanced.patcher.patch.Patch
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
internal class ReadmeGenerator : PatchesFileGenerator {
|
||||||
|
private companion object {
|
||||||
|
private const val TABLE_HEADER =
|
||||||
|
"| \uD83D\uDC8A Patch | \uD83D\uDCDC Description | \uD83C\uDFF9 Target Version |\n" +
|
||||||
|
"|:--------:|:--------------:|:-----------------:|"
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun generate(bundle: PatchBundlePatches) {
|
||||||
|
val output = StringBuilder()
|
||||||
|
|
||||||
|
mutableMapOf<String, MutableList<Class<out Patch<Context>>>>()
|
||||||
|
.apply {
|
||||||
|
for (patch in bundle) {
|
||||||
|
patch.compatiblePackages?.forEach { pkg ->
|
||||||
|
if (!contains(pkg.name)) put(pkg.name, mutableListOf())
|
||||||
|
this[pkg.name]!!.add(patch)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.entries
|
||||||
|
.sortedByDescending { it.value.size }
|
||||||
|
.forEach { (`package`, patches) ->
|
||||||
|
val mostCommonVersion = buildMap {
|
||||||
|
patches.forEach { patch ->
|
||||||
|
patch.compatiblePackages?.single { compatiblePackage -> compatiblePackage.name == `package` }?.versions?.let {
|
||||||
|
it.forEach { version -> merge(version, 1, Integer::sum) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}.let { commonMap ->
|
||||||
|
commonMap.maxByOrNull { it.value }?.value?.let {
|
||||||
|
// This is not foolproof, because for example v1.0.0-dev.0 will be returned instead of v1.0.0-release.
|
||||||
|
// Unfortunately this can not be solved easily because versioning can be complex.
|
||||||
|
commonMap.entries.filter { mostCommon -> mostCommon.value == it }.maxBy { it.key }.key
|
||||||
|
} ?: "all"
|
||||||
|
}
|
||||||
|
|
||||||
|
output.apply {
|
||||||
|
appendLine("### [\uD83D\uDCE6 `${`package`}`](https://play.google.com/store/apps/details?id=${`package`})")
|
||||||
|
appendLine("<details>\n")
|
||||||
|
appendLine(TABLE_HEADER)
|
||||||
|
patches.forEach { patch ->
|
||||||
|
val recommendedPatchVersion = if (
|
||||||
|
patch.compatiblePackages?.single { it.name == `package` }?.versions?.isNotEmpty() == true
|
||||||
|
) mostCommonVersion else "all"
|
||||||
|
|
||||||
|
appendLine(
|
||||||
|
"| `${patch.patchName}` " +
|
||||||
|
"| ${patch.description} " +
|
||||||
|
"| $recommendedPatchVersion |"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
appendLine("</details>\n")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuilder(File("README-template.md").readText())
|
||||||
|
.replace(Regex("\\{\\{\\s?table\\s?}}"), output.toString())
|
||||||
|
.let(File("README.md")::writeText)
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,48 +0,0 @@
|
||||||
package app.revanced.meta.json
|
|
||||||
|
|
||||||
import app.revanced.meta.Bundle
|
|
||||||
import app.revanced.patcher.extensions.PatchExtensions.compatiblePackages
|
|
||||||
import app.revanced.patcher.extensions.PatchExtensions.dependencies
|
|
||||||
import app.revanced.patcher.extensions.PatchExtensions.description
|
|
||||||
import app.revanced.patcher.extensions.PatchExtensions.include
|
|
||||||
import app.revanced.patcher.extensions.PatchExtensions.options
|
|
||||||
import app.revanced.patcher.extensions.PatchExtensions.patchName
|
|
||||||
import app.revanced.patcher.extensions.PatchExtensions.version
|
|
||||||
import app.revanced.patcher.patch.PatchOption
|
|
||||||
import com.google.gson.GsonBuilder
|
|
||||||
import java.io.File
|
|
||||||
|
|
||||||
private val gson = GsonBuilder().serializeNulls().create()
|
|
||||||
|
|
||||||
fun generateJson(bundle: Bundle) {
|
|
||||||
val patches = bundle.map {
|
|
||||||
JsonPatch(
|
|
||||||
it.patchName,
|
|
||||||
it.description ?: "This patch has no description.",
|
|
||||||
it.version ?: "0.0.0",
|
|
||||||
!it.include,
|
|
||||||
it.options?.map { option ->
|
|
||||||
Option(
|
|
||||||
option.key,
|
|
||||||
option.title,
|
|
||||||
option.description,
|
|
||||||
option.required,
|
|
||||||
option.let { lo ->
|
|
||||||
if (lo is PatchOption.ListOption<*>) {
|
|
||||||
lo.options.toMutableList().toTypedArray()
|
|
||||||
} else null
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}?.toTypedArray() ?: emptyArray(),
|
|
||||||
it.dependencies?.map { dep ->
|
|
||||||
dep.java.patchName
|
|
||||||
}?.toTypedArray() ?: emptyArray(),
|
|
||||||
it.compatiblePackages?.map { pkg ->
|
|
||||||
CompatiblePackage(pkg.name, pkg.versions)
|
|
||||||
}?.toTypedArray() ?: emptyArray()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
val json = File("patches.json")
|
|
||||||
json.writeText(gson.toJson(patches))
|
|
||||||
}
|
|
|
@ -1,26 +0,0 @@
|
||||||
@file:Suppress("ArrayInDataClass") // We don't need it here.
|
|
||||||
|
|
||||||
package app.revanced.meta.json
|
|
||||||
|
|
||||||
data class JsonPatch(
|
|
||||||
val name: String,
|
|
||||||
val description: String,
|
|
||||||
val version: String,
|
|
||||||
val excluded: Boolean,
|
|
||||||
val options: Array<Option>,
|
|
||||||
val dependencies: Array<String>,
|
|
||||||
val compatiblePackages: Array<CompatiblePackage>,
|
|
||||||
)
|
|
||||||
|
|
||||||
data class CompatiblePackage(
|
|
||||||
val name: String,
|
|
||||||
val versions: Array<String>,
|
|
||||||
)
|
|
||||||
|
|
||||||
data class Option(
|
|
||||||
val key: String,
|
|
||||||
val title: String,
|
|
||||||
val description: String,
|
|
||||||
val required: Boolean,
|
|
||||||
val choices: Array<*>?,
|
|
||||||
)
|
|
|
@ -1,10 +0,0 @@
|
||||||
package app.revanced.meta.readme
|
|
||||||
|
|
||||||
import app.revanced.patcher.data.Context
|
|
||||||
import app.revanced.patcher.extensions.PatchExtensions.compatiblePackages
|
|
||||||
import app.revanced.patcher.patch.Patch
|
|
||||||
|
|
||||||
internal fun Class<out Patch<Context>>.getLatestVersion() =
|
|
||||||
this.compatiblePackages?.first()?.versions?.map {
|
|
||||||
SemanticVersion.fromString(it)
|
|
||||||
}?.maxWithOrNull(SemanticVersionComparator)
|
|
|
@ -1,42 +0,0 @@
|
||||||
package app.revanced.meta.readme
|
|
||||||
|
|
||||||
import app.revanced.meta.Bundle
|
|
||||||
import app.revanced.patcher.data.Context
|
|
||||||
import app.revanced.patcher.extensions.PatchExtensions.compatiblePackages
|
|
||||||
import app.revanced.patcher.extensions.PatchExtensions.description
|
|
||||||
import app.revanced.patcher.extensions.PatchExtensions.patchName
|
|
||||||
import app.revanced.patcher.patch.Patch
|
|
||||||
import java.io.File
|
|
||||||
|
|
||||||
private const val TABLE_HEADER =
|
|
||||||
"| \uD83D\uDC8A Patch | \uD83D\uDCDC Description | \uD83C\uDFF9 Target Version |\n" + "|:--------:|:--------------:|:-----------------:|"
|
|
||||||
|
|
||||||
private val TABLE_REGEX = Regex("\\{\\{\\s?table\\s?}}")
|
|
||||||
|
|
||||||
fun generateText(bundle: Bundle) {
|
|
||||||
val output = StringBuilder()
|
|
||||||
val packages = mutableMapOf<String, MutableList<Class<out Patch<Context>>>>()
|
|
||||||
|
|
||||||
for (patch in bundle) {
|
|
||||||
patch.compatiblePackages?.forEach { pkg ->
|
|
||||||
if (!packages.contains(pkg.name)) packages[pkg.name] = mutableListOf()
|
|
||||||
packages[pkg.name]!!.add(patch)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (pkg in packages.entries.sortedByDescending { it.value.size }) {
|
|
||||||
output.appendLine("### [\uD83D\uDCE6 `${pkg.key}`](https://play.google.com/store/apps/details?id=${pkg.key})")
|
|
||||||
output.appendLine("<details>\n")
|
|
||||||
|
|
||||||
output.appendLine(TABLE_HEADER)
|
|
||||||
pkg.value.forEach { output.appendLine("| `${it.patchName}` | ${it.description} | ${it.getLatestVersion() ?: "all"} |") }
|
|
||||||
|
|
||||||
output.appendLine("</details>\n")
|
|
||||||
}
|
|
||||||
|
|
||||||
val readmeTemplate = Template(File("README-template.md").readText())
|
|
||||||
readmeTemplate.replaceVariable(TABLE_REGEX, output.toString())
|
|
||||||
|
|
||||||
val readme = File("README.md")
|
|
||||||
readme.writeText(readmeTemplate.toString())
|
|
||||||
}
|
|
|
@ -1,22 +0,0 @@
|
||||||
package app.revanced.meta.readme
|
|
||||||
|
|
||||||
data class SemanticVersion(val major: Int, val minor: Int, val patch: Int) {
|
|
||||||
companion object {
|
|
||||||
fun fromString(version: String): SemanticVersion {
|
|
||||||
val parts = version.split(".")
|
|
||||||
if (parts.count() != 3) throw IllegalArgumentException("Invalid semantic version")
|
|
||||||
val versionNumbers = parts.map { it.toInt() }
|
|
||||||
return SemanticVersion(versionNumbers[0], versionNumbers[1], versionNumbers[2])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun toString(): String = "$major.$minor.$patch"
|
|
||||||
}
|
|
||||||
|
|
||||||
object SemanticVersionComparator : Comparator<SemanticVersion> {
|
|
||||||
override fun compare(a: SemanticVersion, b: SemanticVersion): Int = when {
|
|
||||||
a.major != b.major -> a.major - b.major
|
|
||||||
a.minor != b.minor -> a.minor - b.minor
|
|
||||||
else -> a.patch - b.patch
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
package app.revanced.meta.readme
|
|
||||||
|
|
||||||
class Template(template: String) {
|
|
||||||
val result = StringBuilder(template)
|
|
||||||
|
|
||||||
fun replaceVariable(regex: Regex, value: String) {
|
|
||||||
val range = regex.find(result)!!.range
|
|
||||||
result.replace(range.first, range.last + 1, value)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun toString(): String = result.toString()
|
|
||||||
}
|
|
Loading…
Reference in a new issue