build: Refactor to DSL to bump ReVanced Patcher

BREAKING CHANGE:  The signature of some functions has changed.
This commit is contained in:
oSumAtrIX
2024-06-16 16:02:38 +02:00
parent 8aca650ebc
commit 7f5d6dad7b
8 changed files with 69 additions and 80 deletions

View File

@@ -2,9 +2,8 @@
package app.revanced.library
import app.revanced.library.Options.Patch.Option
import app.revanced.patcher.PatchSet
import app.revanced.patcher.patch.options.PatchOptionException
import app.revanced.patcher.patch.OptionException
import app.revanced.patcher.patch.Patch
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import java.io.File
import java.util.logging.Logger
@@ -23,7 +22,7 @@ object Options {
* @return The JSON string containing the options.
*/
fun serialize(
patches: PatchSet,
patches: Set<app.revanced.patcher.patch.Patch<*>>,
prettyPrint: Boolean = false,
): String =
patches
@@ -35,12 +34,12 @@ object Options {
val optionValue =
try {
option.value
} catch (e: PatchOptionException) {
} catch (e: OptionException) {
logger.warning("Using default option value for the ${patch.name} patch: ${e.message}")
option.default
}
Option(option.key, optionValue)
Patch.Option(option.key, optionValue)
},
)
}
@@ -68,7 +67,7 @@ object Options {
*
* @param json The JSON string containing the options.
*/
fun PatchSet.setOptions(json: String) {
fun Set<app.revanced.patcher.patch.Patch<*>>.setOptions(json: String) {
filter { it.options.any() }.let { patches ->
if (patches.isEmpty()) return
@@ -82,7 +81,7 @@ object Options {
jsonPatchOptions.forEach { (option, value) ->
try {
patch.options[option] = value
} catch (e: PatchOptionException) {
} catch (e: OptionException) {
logger.warning("Could not set option value for the ${patch.name} patch: ${e.message}")
}
}
@@ -97,7 +96,7 @@ object Options {
* @param file The file containing the JSON string containing the options.
* @see setOptions
*/
fun PatchSet.setOptions(file: File) = setOptions(file.readText())
fun Set<app.revanced.patcher.patch.Patch<*>>.setOptions(file: File) = setOptions(file.readText())
/**
* Data class for a patch and its [Option]s.

View File

@@ -1,12 +1,12 @@
package app.revanced.library
import app.revanced.patcher.PatchSet
import app.revanced.patcher.patch.Option
import app.revanced.patcher.patch.Package
import app.revanced.patcher.patch.Patch
import app.revanced.patcher.patch.options.PatchOption
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import java.io.InputStream
import java.io.OutputStream
import kotlin.reflect.jvm.jvmName
import kotlin.reflect.KType
typealias PackageName = String
typealias Version = String
@@ -29,31 +29,29 @@ object PatchUtils {
* @return A map of package names to a map of versions to their count.
*/
fun getMostCommonCompatibleVersions(
patches: PatchSet,
patches: Set<Patch<*>>,
packageNames: Set<String>? = null,
countUnusedPatches: Boolean = false,
): PackageNameMap =
buildMap {
fun filterWantedPackages(compatiblePackages: Iterable<Patch.CompatiblePackage>): Iterable<Patch.CompatiblePackage> {
fun filterWantedPackages(compatiblePackages: Iterable<Package>): Iterable<Package> {
val wantedPackages = packageNames?.toHashSet() ?: return compatiblePackages
return compatiblePackages.filter { it.name in wantedPackages }
return compatiblePackages.filter { (name, _) -> name in wantedPackages }
}
patches
.filter { it.use || countUnusedPatches }
.flatMap { it.compatiblePackages ?: emptyList() }
.let(::filterWantedPackages)
.forEach { compatiblePackage ->
if (compatiblePackage.versions?.isEmpty() == true) {
.forEach { (name, versions) ->
if (versions?.isEmpty() == true) {
return@forEach
}
val versionMap = getOrPut(compatiblePackage.name) { linkedMapOf() }
val versionMap = getOrPut(name) { linkedMapOf() }
compatiblePackage.versions?.let { versions ->
versions.forEach { version ->
versionMap[version] = versionMap.getOrDefault(version, 0) + 1
}
versions?.forEach { version ->
versionMap[version] = versionMap.getOrDefault(version, 0) + 1
}
}
@@ -79,7 +77,7 @@ object PatchUtils {
* @param outputStream The output stream to write the JSON to.
*/
fun serialize(
patches: PatchSet,
patches: Set<Patch<*>>,
transform: (Patch<*>) -> JsonPatch = { patch -> FullJsonPatch.fromPatch(patch) },
prettyPrint: Boolean = false,
outputStream: OutputStream,
@@ -119,10 +117,10 @@ object PatchUtils {
class FullJsonPatch internal constructor(
val name: String?,
val description: String?,
val compatiblePackages: Set<Patch.CompatiblePackage>?,
val dependencies: Set<String>?,
val compatiblePackages: Set<Package>?,
// Cannot serialize dependencies, because they are references to other patches and patch names are nullable.
// val dependencies: Set<String>,
val use: Boolean,
var requiresIntegrations: Boolean,
val options: Map<String, FullJsonPatchOption<*>>,
) : JsonPatch {
companion object {
@@ -131,16 +129,15 @@ object PatchUtils {
patch.name,
patch.description,
patch.compatiblePackages,
buildSet { patch.dependencies?.forEach { add(it.jvmName) } },
// buildSet { patch.dependencies.forEach { add(it.name) } },
patch.use,
patch.requiresIntegrations,
patch.options.mapValues { FullJsonPatchOption.fromPatchOption(it.value) },
)
}
/**
* A JSON representation of a [PatchOption].
* @see PatchOption
* A JSON representation of a [Option].
* @see Option
*/
class FullJsonPatchOption<T> internal constructor(
val key: String,
@@ -149,10 +146,10 @@ object PatchUtils {
val title: String?,
val description: String?,
val required: Boolean,
val valueType: String,
val type: KType,
) {
companion object {
fun fromPatchOption(option: PatchOption<*>) =
fun fromPatchOption(option: Option<*>) =
FullJsonPatchOption(
option.key,
option.default,
@@ -160,7 +157,7 @@ object PatchUtils {
option.title,
option.description,
option.required,
option.valueType,
option.type,
)
}
}

View File

@@ -1,6 +1,6 @@
package app.revanced.library.installation.command
import app.revanced.library.installation.installer.Utils
import app.revanced.library.installation.installer.getDevice
import se.vidstige.jadb.JadbDevice
import se.vidstige.jadb.RemoteFile
import java.io.File
@@ -29,7 +29,7 @@ class AdbShellCommandRunner : ShellCommandRunner {
* @param deviceSerial deviceSerial The device serial. If null, the first connected device will be used.
*/
internal constructor(deviceSerial: String?) {
device = Utils.getDevice(deviceSerial, logger)
device = getDevice(deviceSerial, logger)
}
override fun runCommand(command: String) = device.shellProcessBuilder(command).start().let { process ->

View File

@@ -17,7 +17,7 @@ import se.vidstige.jadb.managers.PackageManager
class AdbInstaller(
deviceSerial: String? = null,
) : Installer<AdbInstallerResult, Installation>() {
private val device = Utils.getDevice(deviceSerial, logger)
private val device = getDevice(deviceSerial, logger)
private val adbShellCommandRunner = AdbShellCommandRunner(device)
private val packageManager = PackageManager(device)

View File

@@ -4,37 +4,31 @@ import se.vidstige.jadb.JadbConnection
import java.util.logging.Logger
/**
* Utility functions for [Installer].
* Gets the device with the given serial.
*
* @see Installer
* @param deviceSerial The device serial. If null, the first connected device will be used.
* @param logger The logger.
* @return The device.
* @throws DeviceNotFoundException If no device with the given serial is found.
*/
internal object Utils {
/**
* Gets the device with the given serial.
*
* @param deviceSerial The device serial. If null, the first connected device will be used.
* @param logger The logger.
* @return The device.
* @throws DeviceNotFoundException If no device with the given serial is found.
*/
internal fun getDevice(
deviceSerial: String? = null,
logger: Logger,
) = with(JadbConnection().devices) {
if (isEmpty()) throw DeviceNotFoundException()
internal fun getDevice(
deviceSerial: String? = null,
logger: Logger,
) = with(JadbConnection().devices) {
if (isEmpty()) throw DeviceNotFoundException()
deviceSerial?.let {
firstOrNull { it.serial == deviceSerial } ?: throw DeviceNotFoundException(
deviceSerial,
)
} ?: first().also {
logger.warning("No device serial supplied. Using device with serial ${it.serial}")
}
}!!
deviceSerial?.let {
firstOrNull { it.serial == deviceSerial } ?: throw DeviceNotFoundException(
deviceSerial,
)
} ?: first().also {
logger.warning("No device serial supplied. Using device with serial ${it.serial}")
}
}!!
class DeviceNotFoundException internal constructor(deviceSerial: String? = null) : Exception(
class DeviceNotFoundException internal constructor(deviceSerial: String? = null) :
Exception(
deviceSerial?.let {
"The device with the ADB device serial \"$deviceSerial\" can not be found"
} ?: "No ADB device found",
)
}