Skip to content

Commit

Permalink
feat: Add JSON meta
Browse files Browse the repository at this point in the history
  • Loading branch information
Sculas committed Aug 28, 2022
1 parent 2b841f9 commit 4c229d3
Show file tree
Hide file tree
Showing 10 changed files with 184 additions and 59 deletions.
6 changes: 1 addition & 5 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,12 @@ jobs:
java-version: '17'
distribution: 'adopt'
cache: gradle
- name: Setup Node.js
uses: actions/setup-node@v2
with:
node-version: "lts/*"
- name: Setup Android SDK
uses: android-actions/setup-android@v2
- name: Build with Gradle
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: ./gradlew build clean generateReadme
run: ./gradlew build clean
- name: Install Android build-tools
run: sdkmanager "build-tools;32.0.0"
- name: Setup semantic-release
Expand Down
71 changes: 68 additions & 3 deletions README-template.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,72 @@
# 🧩 ReVanced Patches
## 🧩 Patches

Official patches by ReVanced
The official Patch bundle provided by ReVanced and the community.

## 📜 List of available patches
> Looking for the JSON variant of this? [Click here](patches.json).
{{ table }}

## 📝 JSON Format

This section explains the JSON format for the [patches.json](patches.json) file.

The file contains an array of objects, each object representing a patch. The object contains the following properties:

| key | description |
|-------------------------------|------------------------------------------------------------------------------------------------------------------|
| `name` | The name of the patch. |
| `description` | The description of the patch. |
| `version` | The version of the patch. |
| `excluded` | Whether a patch is excluded by default. If `true`, the patch must never be included by default. |
| `dependencies` | An array of dependencies, which are patch names. |
| `compatiblePackages` | An array of packages compatible with this patch. |
| `compatiblePackages.name` | The name of the package. |
| `compatiblePackages.versions` | An array of versions of the package compatible with this patch. If empty, all versions are seemingly compatible. |

Example:

```json
[
{
"name": "remember-video-quality",
"description": "Adds the ability to remember the video quality you chose in the video quality flyout.",
"version": "0.0.1",
"excluded": false,
"dependencies": [
"integrations",
"video-id-hook"
],
"compatiblePackages": [
{
"name": "com.google.android.youtube",
"versions": [
"17.22.36",
"17.24.35",
"17.26.35",
"17.27.39",
"17.28.34",
"17.29.34",
"17.32.35"
]
}
]
},
{
"name": "client-spoof",
"description": "Spoofs the YouTube or Vanced client to prevent playback issues.",
"version": "0.0.1",
"excluded": false,
"dependencies": [],
"compatiblePackages": [
{
"name": "com.google.android.youtube",
"versions": []
},
{
"name": "com.vanced.android.youtube",
"versions": []
}
]
}
]
```
11 changes: 7 additions & 4 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ dependencies {

implementation("app.revanced:revanced-patcher:3.3.3")
implementation("app.revanced:multidexlib2:2.5.2.r2")

// Required for meta
implementation("com.google.code.gson:gson:2.9.1")
}

tasks {
Expand All @@ -48,19 +51,19 @@ tasks {
}
}
}
register<JavaExec>("generateReadme") {
description = "Generate README.md"
register<JavaExec>("generateMeta") {
description = "Generate metadata for this bundle"
dependsOn(build)

classpath = sourceSets["main"].runtimeClasspath
mainClass.set("app.revanced.meta.readme.Generator")
mainClass.set("app.revanced.meta.Meta")
}
// Dummy task to fix the Gradle semantic-release plugin.
// Remove this if you forked it to support building only.
// Tracking issue: https://github.com/KengoTODA/gradle-semantic-release-plugin/issues/435
register<DefaultTask>("publish") {
group = "publish"
description = "Dummy task"
dependsOn(named("generateBundle"), named("generateReadme"))
dependsOn(named("generateBundle"), named("generateMeta"))
}
}
27 changes: 27 additions & 0 deletions src/main/kotlin/app/revanced/meta/Meta.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package app.revanced.meta

import app.revanced.meta.json.generateJson
import app.revanced.meta.readme.generateText
import app.revanced.patcher.data.Data
import app.revanced.patcher.patch.Patch
import app.revanced.patcher.util.patch.impl.JarPatchBundle
import java.io.File

typealias Bundle = List<Class<out Patch<Data>>>

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() = JarPatchBundle(
File("build/libs/").listFiles()!!.first {
it.name.startsWith("revanced-patches-") && it.name.endsWith(".jar")
}.absolutePath
).loadPatches()
33 changes: 33 additions & 0 deletions src/main/kotlin/app/revanced/meta/json/Generator.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
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.patchName
import app.revanced.patcher.extensions.PatchExtensions.version
import com.google.gson.Gson
import java.io.File

private val gson = Gson()

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.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))
}
17 changes: 17 additions & 0 deletions src/main/kotlin/app/revanced/meta/json/JsonPatch.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
@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 dependencies: Array<String>,
val compatiblePackages: Array<CompatiblePackage>,
)

data class CompatiblePackage(
val name: String,
val versions: Array<String>,
)
9 changes: 4 additions & 5 deletions src/main/kotlin/app/revanced/meta/readme/Extensions.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ import app.revanced.patcher.data.Data
import app.revanced.patcher.extensions.PatchExtensions.compatiblePackages
import app.revanced.patcher.patch.Patch

internal fun Class<out Patch<Data>>.getLatestVersion(): SemanticVersion? =
this.compatiblePackages?.first()?.versions?.map { SemanticVersion.fromString(it) }
?.maxWithOrNull(
SemanticVersionComparator
)
internal fun Class<out Patch<Data>>.getLatestVersion() =
this.compatiblePackages?.first()?.versions?.map {
SemanticVersion.fromString(it)
}?.maxWithOrNull(SemanticVersionComparator)
59 changes: 24 additions & 35 deletions src/main/kotlin/app/revanced/meta/readme/Generator.kt
Original file line number Diff line number Diff line change
@@ -1,55 +1,44 @@
package app.revanced.meta.readme

import app.revanced.meta.Bundle
import app.revanced.patcher.data.Data
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 app.revanced.patcher.util.patch.impl.JarPatchBundle
import java.io.File

object Generator {
private const val TABLE_HEADER =
"| \uD83D\uDC8A Patch | \uD83D\uDCDC Description | \uD83C\uDFF9 Target Version |\n" +
"|:--------:|:--------------:|:-----------------:|"
private const val TABLE_HEADER =
"| \uD83D\uDC8A Patch | \uD83D\uDCDC Description | \uD83C\uDFF9 Target Version |\n" + "|:--------:|:--------------:|:-----------------:|"

@JvmStatic
fun main(args: Array<String>) {
val buildDir = File("build/libs/")
val buildJar =
buildDir.listFiles()?.first { it.name.startsWith("revanced-patches-") && it.name.endsWith(".jar") }!!
private val TABLE_REGEX = Regex("\\{\\{\\s?table\\s?}}")

val bundle = JarPatchBundle(buildJar.absolutePath).loadPatches()
fun generateText(bundle: Bundle) {
val output = StringBuilder()
val packages = mutableMapOf<String, MutableList<Class<out Patch<Data>>>>()

val output = StringBuilder()

val packages = mutableMapOf<String, MutableList<Class<out Patch<Data>>>>()

bundle.map {
val packageName = it.compatiblePackages?.first()?.name!!
if (!packages.contains(packageName)) {
packages[packageName] = mutableListOf()
}

packages[packageName]?.add(it)
bundle.map {
val packageName = it.compatiblePackages?.first()?.name!!
if (!packages.contains(packageName)) {
packages[packageName] = mutableListOf()
}

for (pkg in packages) {
output.appendLine("### \uD83D\uDCE6 `${pkg.key}`")
output.appendLine("<details>\n")
packages[packageName]?.add(it)
}

output.appendLine(TABLE_HEADER)
pkg.value.forEach { output.appendLine("| `${it.patchName}` | ${it.description} | ${it.getLatestVersion() ?: "all"} |") }
for (pkg in packages) {
output.appendLine("### \uD83D\uDCE6 `${pkg.key}`")
output.appendLine("<details>\n")

output.appendLine("</details>\n")
}
output.appendLine(TABLE_HEADER)
pkg.value.forEach { output.appendLine("| `${it.patchName}` | ${it.description} | ${it.getLatestVersion() ?: "all"} |") }

val readMeTemplateFile = File("README-template.md")
val readmeTemplate = Template(readMeTemplateFile.readText())
output.appendLine("</details>\n")
}

readmeTemplate.replaceVariable("table", output.toString())
val readmeTemplate = Template(File("README-template.md").readText())
readmeTemplate.replaceVariable(TABLE_REGEX, output.toString())

val readme = File("README.md")
readme.writeText(readmeTemplate.toString())
}
val readme = File("README.md")
readme.writeText(readmeTemplate.toString())
}
4 changes: 1 addition & 3 deletions src/main/kotlin/app/revanced/meta/readme/SemanticVersion.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,8 @@ package app.revanced.meta.readme
data class SemanticVersion(val major: Int, val minor: Int, val patch: Int) {
companion object {
fun fromString(version: String): SemanticVersion {
var parts = version.split(".")

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])
}
Expand Down
6 changes: 2 additions & 4 deletions src/main/kotlin/app/revanced/meta/readme/Template.kt
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
package app.revanced.meta.readme

class Template(template: String) {
val result: StringBuilder = StringBuilder(template)
val result = StringBuilder(template)

fun replaceVariable(name: String, value: String) {
val regex = Regex("\\{\\{\\s?$name\\s?}}")
fun replaceVariable(regex: Regex, value: String) {
val range = regex.find(result)!!.range

result.replace(range.first, range.last + 1, value)
}

Expand Down

0 comments on commit 4c229d3

Please sign in to comment.