refactor: improve OptionsLoader a lot

This commit is contained in:
Sculas 2022-09-09 22:50:15 +02:00
parent 71c81510f7
commit 075bf406fd
No known key found for this signature in database
GPG Key ID: 1530BFF96D1EEB89

View File

@ -1,20 +1,19 @@
package app.revanced.utils package app.revanced.utils
import app.revanced.cli.command.MainCommand.logger import app.revanced.cli.command.MainCommand.logger
import app.revanced.patcher.Patcher
import app.revanced.patcher.data.Data import app.revanced.patcher.data.Data
import app.revanced.patcher.extensions.PatchExtensions.options import app.revanced.patcher.extensions.PatchExtensions.options
import app.revanced.patcher.extensions.PatchExtensions.patchName import app.revanced.patcher.extensions.PatchExtensions.patchName
import app.revanced.patcher.patch.Patch import app.revanced.patcher.patch.Patch
import cc.ekblad.toml.encodeTo import cc.ekblad.toml.encodeToString
import cc.ekblad.toml.model.TomlValue import cc.ekblad.toml.model.TomlValue
import cc.ekblad.toml.serialization.from import cc.ekblad.toml.serialization.from
import cc.ekblad.toml.tomlMapper import cc.ekblad.toml.tomlMapper
import java.io.File import java.io.File
private typealias PatchList = List<Class<out Patch<Data>>> private typealias PatchList = List<Class<out Patch<Data>>>
private typealias OptionsMap = Map<String, Map<String, Any>> private typealias OptionsMap = MutableMap<String, MutableMap<String, Any>>
private const val NULL = "null"
object OptionsLoader { object OptionsLoader {
@JvmStatic @JvmStatic
@ -23,12 +22,9 @@ object OptionsLoader {
@JvmStatic @JvmStatic
fun init(file: File, patches: PatchList) { fun init(file: File, patches: PatchList) {
if (!file.exists()) file.createNewFile() if (!file.exists()) file.createNewFile()
val path = file.toPath() val map = mapper.decodeWithDefaults(generateDefaults(patches), TomlValue.from(file.toPath()))
val map = mapper.decodeWithDefaults(
generateDefaults(patches),
TomlValue.from(path)
).also { mapper.encodeTo(path, it) }
readAndSet(map, patches) readAndSet(map, patches)
save(map, file)
} }
private fun readAndSet(map: OptionsMap, patches: PatchList) { private fun readAndSet(map: OptionsMap, patches: PatchList) {
@ -36,27 +32,46 @@ object OptionsLoader {
val patch = patches.find { it.patchName == patchName } ?: continue val patch = patches.find { it.patchName == patchName } ?: continue
val patchOptions = patch.options ?: continue val patchOptions = patch.options ?: continue
for ((key, value) in options) { for ((key, value) in options) {
if (value == "null") { // backwards compatibility, subject to removal
options.remove(key)
continue
}
try { try {
patchOptions[key] = value.let { patchOptions[key] = value
if (it == NULL) null else it
}
} catch (e: Exception) { } catch (e: Exception) {
logger.warn("Error while setting option $key for patch $patchName: ${e.message}") logger.error("Error while setting option $key for patch $patchName: ${e.message}")
e.printStackTrace() e.printStackTrace()
} }
} }
} }
} }
private fun save(map: OptionsMap, file: File) {
val toml = mapper.encodeToString(map)
file.writeText(
"""
# A list of options for each patch.
# This file does not contain all options by default.
# Run the CLI with the "--list --with-options" flags to see all available options.
# You can also run the CLI with the aforementioned flags and a patch name to see all available options for that patch.
# To set an option, add a line with the format "option = value".
# To remove or reset an option to its default value, delete the line.
# To reset all options to their default values, delete this file.
#
# This file was generated by ReVanced Patcher version ${Patcher.version}.
""".trimIndent() + "\n\n$toml"
)
}
private fun generateDefaults(patches: PatchList) = buildMap { private fun generateDefaults(patches: PatchList) = buildMap {
for (patch in patches) { for (patch in patches) {
val options = patch.options ?: continue val options = patch.options ?: continue
if (!options.iterator().hasNext()) continue if (!options.iterator().hasNext()) continue
put(patch.patchName, buildMap { put(patch.patchName, buildMap {
for (option in options) { for (option in options) {
put(option.key, option.value ?: NULL) put(option.key, option.value ?: continue)
} }
}) } as MutableMap)
} }
} } as MutableMap
} }