Compare commits

..

4 Commits

Author SHA1 Message Date
semantic-release-bot
6a7343afaf chore(release): 2.20.1-dev.1 [skip ci]
## [2.20.1-dev.1](https://github.com/revanced/revanced-cli/compare/v2.20.0...v2.20.1-dev.1) (2023-03-02)

### Bug Fixes

* change permission of gradlew ([6787267](6787267c67))
* correctly word option descriptions ([6050d12](6050d122e6))
2023-03-02 19:20:30 +00:00
oSumAtrIX
6787267c67 fix: change permission of gradlew 2023-03-02 20:19:20 +01:00
oSumAtrIX
6050d122e6 fix: correctly word option descriptions
Signed-off-by: oSumAtrIX <johan.melkonyan1@web.de>
2023-03-02 20:11:55 +01:00
oSumAtrIX
2b6426dfd7 chore: remove project files 2023-03-02 20:11:50 +01:00
17 changed files with 155 additions and 368 deletions

2
.github/config.yml vendored
View File

@@ -1,2 +0,0 @@
firstPRMergeComment: >
Thank you for contributing to ReVanced. Join us on [Discord](https://revanced.app/discord) if you want to receive a contributor role.

View File

@@ -23,20 +23,17 @@ jobs:
# https://github.com/cycjimmy/semantic-release-action#private-packages # https://github.com/cycjimmy/semantic-release-action#private-packages
persist-credentials: false persist-credentials: false
fetch-depth: 0 fetch-depth: 0
- name: Cache - name: Setup JDK
uses: actions/cache@v3 uses: actions/setup-java@v3
with: with:
path: | java-version: '17'
${{ runner.home }}/.gradle/caches distribution: 'zulu'
${{ runner.home }}/.gradle/wrapper cache: gradle
.gradle - name: Setup Node.js
build uses: actions/setup-node@v3
node_modules with:
key: ${{ runner.os }}-gradle-npm-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties', 'package-lock.json') }} node-version: "18"
- name: Build with Gradle cache: 'npm'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: ./gradlew clean --no-daemon
- name: Setup semantic-release - name: Setup semantic-release
run: npm install run: npm install
- name: Release - name: Release

View File

@@ -9,7 +9,6 @@ jobs:
trigger: trigger:
runs-on: ubuntu-latest runs-on: ubuntu-latest
name: Dispatch event to documentation repository name: Dispatch event to documentation repository
if: github.ref == 'refs/heads/main'
steps: steps:
- uses: peter-evans/repository-dispatch@v2 - uses: peter-evans/repository-dispatch@v2
with: with:

View File

@@ -7,13 +7,7 @@
} }
], ],
"plugins": [ "plugins": [
[ "@semantic-release/commit-analyzer",
"@semantic-release/commit-analyzer", {
"releaseRules": [
{ "type": "build", "scope": "revanced-patcher", "release": "patch" }
]
}
],
"@semantic-release/release-notes-generator", "@semantic-release/release-notes-generator",
"@semantic-release/changelog", "@semantic-release/changelog",
"gradle-semantic-release-plugin", "gradle-semantic-release-plugin",

View File

@@ -1,104 +1,10 @@
## [2.21.5](https://github.com/revanced/revanced-cli/compare/v2.21.4...v2.21.5) (2023-07-01)
## [2.21.5-dev.2](https://github.com/revanced/revanced-cli/compare/v2.21.5-dev.1...v2.21.5-dev.2) (2023-07-01)
## [2.21.5-dev.1](https://github.com/revanced/revanced-cli/compare/v2.21.4...v2.21.5-dev.1) (2023-06-27)
## [2.21.4](https://github.com/revanced/revanced-cli/compare/v2.21.3...v2.21.4) (2023-06-21)
### Bug Fixes
* remove duplicate options entries. ([d0fc886](https://github.com/revanced/revanced-cli/commit/d0fc8864286adc2677f91a319a11a90272c1001d))
## [2.21.4-dev.1](https://github.com/revanced/revanced-cli/compare/v2.21.3...v2.21.4-dev.1) (2023-06-18)
### Bug Fixes
* remove duplicate options entries. ([d0fc886](https://github.com/revanced/revanced-cli/commit/d0fc8864286adc2677f91a319a11a90272c1001d))
## [2.21.3](https://github.com/revanced/revanced-cli/compare/v2.21.2...v2.21.3) (2023-06-12)
## [2.21.3-dev.1](https://github.com/revanced/revanced-cli/compare/v2.21.2...v2.21.3-dev.1) (2023-06-07)
## [2.21.2](https://github.com/revanced/revanced-cli/compare/v2.21.1...v2.21.2) (2023-05-24)
## [2.21.2-dev.2](https://github.com/revanced/revanced-cli/compare/v2.21.2-dev.1...v2.21.2-dev.2) (2023-05-15)
## [2.21.2-dev.1](https://github.com/revanced/revanced-cli/compare/v2.21.1...v2.21.2-dev.1) (2023-05-07)
## [2.21.1](https://github.com/revanced/revanced-cli/compare/v2.21.0...v2.21.1) (2023-05-06)
## [2.21.1-dev.1](https://github.com/revanced/revanced-cli/compare/v2.21.0...v2.21.1-dev.1) (2023-05-06)
# [2.21.0](https://github.com/revanced/revanced-cli/compare/v2.20.2...v2.21.0) (2023-05-04)
### Bug Fixes
* **tests:** set order of tests ([2ef48af](https://github.com/revanced/revanced-cli/commit/2ef48af1b339ab729a05d69cb0c8c1ee1e3ab486))
* use working JADB dependency version ([#222](https://github.com/revanced/revanced-cli/issues/222)) ([da2c918](https://github.com/revanced/revanced-cli/commit/da2c91874d5623402febfcc0677ada3d648565e1))
### Features
* add appreciation message for new contributors ([6962fc2](https://github.com/revanced/revanced-cli/commit/6962fc2f4c0f0c96e88a823be64f8ebd1312ee17))
# [2.21.0-dev.1](https://github.com/revanced/revanced-cli/compare/v2.20.2...v2.21.0-dev.1) (2023-05-04)
### Bug Fixes
* **tests:** set order of tests ([2ef48af](https://github.com/revanced/revanced-cli/commit/2ef48af1b339ab729a05d69cb0c8c1ee1e3ab486))
* use working JADB dependency version ([#222](https://github.com/revanced/revanced-cli/issues/222)) ([da2c918](https://github.com/revanced/revanced-cli/commit/da2c91874d5623402febfcc0677ada3d648565e1))
### Features
* add appreciation message for new contributors ([6962fc2](https://github.com/revanced/revanced-cli/commit/6962fc2f4c0f0c96e88a823be64f8ebd1312ee17))
## [2.20.2](https://github.com/revanced/revanced-cli/compare/v2.20.1...v2.20.2) (2023-04-30)
### Bug Fixes
* correct spelling mistake ([31fb316](https://github.com/revanced/revanced-cli/commit/31fb3166d922ae1f568f52e44cbe726dd1c891a4))
## [2.20.2-dev.1](https://github.com/revanced/revanced-cli/compare/v2.20.1...v2.20.2-dev.1) (2023-04-03)
### Bug Fixes
* correct spelling mistake ([31fb316](https://github.com/revanced/revanced-cli/commit/31fb3166d922ae1f568f52e44cbe726dd1c891a4))
## [2.20.1](https://github.com/revanced/revanced-cli/compare/v2.20.0...v2.20.1) (2023-03-14)
### Bug Fixes
* correctly word option descriptions ([ac3a8f6](https://github.com/revanced/revanced-cli/commit/ac3a8f66f77a7218974465eebbfc78a536b76d51))
## [2.20.1-dev.1](https://github.com/revanced/revanced-cli/compare/v2.20.0...v2.20.1-dev.1) (2023-03-05)
### Bug Fixes
* correctly word option descriptions ([ac3a8f6](https://github.com/revanced/revanced-cli/commit/ac3a8f66f77a7218974465eebbfc78a536b76d51))
## [2.20.1-dev.1](https://github.com/revanced/revanced-cli/compare/v2.20.0...v2.20.1-dev.1) (2023-03-03)
### Bug Fixes
* correctly word option descriptions ([ac3a8f6](https://github.com/revanced/revanced-cli/commit/ac3a8f66f77a7218974465eebbfc78a536b76d51))
## [2.20.1-dev.1](https://github.com/revanced/revanced-cli/compare/v2.20.0...v2.20.1-dev.1) (2023-03-02) ## [2.20.1-dev.1](https://github.com/revanced/revanced-cli/compare/v2.20.0...v2.20.1-dev.1) (2023-03-02)
### Bug Fixes ### Bug Fixes
* correctly word option descriptions ([ac3a8f6](https://github.com/revanced/revanced-cli/commit/ac3a8f66f77a7218974465eebbfc78a536b76d51)) * change permission of gradlew ([6787267](https://github.com/revanced/revanced-cli/commit/6787267c67c8829bd18acc530474d29a88f84f9b))
* correctly word option descriptions ([6050d12](https://github.com/revanced/revanced-cli/commit/6050d122e65abd5bb27efdca77d0187b50e3df83))
# [2.20.0](https://github.com/revanced/revanced-cli/compare/v2.19.0...v2.20.0) (2023-01-18) # [2.20.0](https://github.com/revanced/revanced-cli/compare/v2.19.0...v2.20.0) (2023-01-18)

View File

@@ -1,5 +1,5 @@
plugins { plugins {
kotlin("jvm") version "1.8.10" kotlin("jvm") version "1.7.0"
id("com.github.johnrengelman.shadow") version "7.1.2" id("com.github.johnrengelman.shadow") version "7.1.2"
} }
@@ -23,28 +23,17 @@ repositories {
} }
dependencies { dependencies {
implementation("org.jetbrains.kotlin:kotlin-reflect:1.8.20-RC") implementation(kotlin("reflect"))
implementation("app.revanced:revanced-patcher:11.0.3") implementation("app.revanced:revanced-patcher:7.0.0")
implementation("info.picocli:picocli:4.7.1") implementation("info.picocli:picocli:4.7.0")
implementation("com.github.revanced:jadb:2531a28109") // updated fork implementation("com.github.revanced:jadb:master-SNAPSHOT") // updated fork
implementation("com.android.tools.build:apksig:8.1.0-alpha09") implementation("com.android.tools.build:apksig:7.2.2")
implementation("org.bouncycastle:bcpkix-jdk15on:1.70") implementation("org.bouncycastle:bcpkix-jdk15on:1.70")
implementation("com.fasterxml.jackson.module:jackson-module-kotlin:2.14.+") implementation("cc.ekblad:4koma:1.1.0")
testImplementation("org.jetbrains.kotlin:kotlin-test:1.8.20-RC")
}
kotlin {
jvmToolchain(11)
} }
tasks { tasks {
test {
useJUnitPlatform()
testLogging {
events("PASSED", "SKIPPED", "FAILED")
}
}
build { build {
dependsOn(shadowJar) dependsOn(shadowJar)
} }

View File

@@ -1,15 +1,17 @@
# 💼 Prerequisites # 💼 Prerequisites
To use ReVanced CLI, you will need to fulfill certain requirements. To use the ReVanced CLI, you will need to fulfill certain requirements.
## 🤝 Requirements ## 🤝 Requirements
- Java SDK 11 (Azul JDK or OpenJDK) - [Android Debug Bridge (adb)](https://developer.android.com/studio/command-line/adb), the command-line tool that lets
- [Android Debug Bridge (adb)](https://developer.android.com/studio/command-line/adb) if you want to deploy the patched APK file on your device you communicate with a device (optional).
- An ABI other than ARMv7 such as x86 or x86-64 (or a custom AAPT binary that supports ARMv7) - A x86/x86_64 host (or a custom AAPT binary for your architecture)
- Zulu OpenJDK 17
- An APK file (e.g. YouTube v17.49.37 or YouTube Music v5.36.51)
## ⏭️ Whats next ## ⏭️ Whats next
The next section will show, how to use [ReVanced CLI](https://github.com/revanced/revanced-cli). The next section will show, how to use the [ReVanced CLI](https://github.com/revanced/revanced-cli).
Continue: [🛠️ Using ReVanced CLI](1_usage.md) Continue: [🛠️ Using the ReVanced CLI](1_usage.md)

View File

@@ -1,76 +1,76 @@
# 🛠️ Using ReVanced CLI # 🛠️ Using the ReVanced CLI
Learn how to ReVanced CLI. Lean how to use the ReVanced CLI.
## ⚡ Setup ADB ## ⚡ Setup (optional)
1. Ensure that ADB is working 1. Make sure your device is connected
```bash ```bash
adb shell exit adb shell exit
``` ```
If you want to deploy the patched APK file on your device by mounting it on top of the original APK file, you will need root access. This is optional. If you plan to use the root variant, check if you have root access
```bash ```bash
adb shell su -c exit adb shell su -c exit
``` ```
2. Get the name of your device 2. Copy the ADB device name
```bash ```bash
adb devices adb devices
``` ```
## 🔨 Using ReVanced CLI ## 🔨 ReVanced CLI Usage
- ### ⚙️ Show all available options for ReVanced CLI - ### Show all available options for the ReVanced CLI
```bash ```bash
java -jar revanced-cli.jar -h java -jar revanced-cli.jar -h
``` ```
- ### 📃 List all available patches from supplied patch bundles - ### List all available patches from supplied patch bundles
```bash ```bash
java -jar revanced-cli.jar java -jar revanced-cli.jar \
-b revanced-patches.jar \ -b revanced-patches.jar \
-l -l
``` ```
- ### 💉 Use ReVanced CLI to patch an APK file but deploy without root permissions - ### Use the ReVanced CLI without root permissions
This will deploy the patched APK file on your device by installing it.
```bash ```bash
java -jar revanced-cli.jar \ java -jar revanced-cli.jar \
-a input.apk \ -a input.apk \
-o patched-output.apk \ -c \
-b revanced-patches.jar \ -o unpatched-output.apk \
-d device-name -b revanced-patches.jar
``` ```
- ### 👾 Use ReVanced CLI to patch an APK file but deploy with root permissions - ### Mount the patched application with root permissions over the installed application
This will deploy the patched APK file on your device by mounting it on top of the original APK file.
```bash ```bash
adb install input.apk adb install input.apk # make sure the same version is installed
java -jar revanced-cli.jar \ java -jar revanced-cli.jar \
-a input.apk \ -a input.apk \
-o patched-output.apk \ -c \
-b revanced-patches.jar \ -d device-name \
-e vanced-microg-support \ -o patched-output.apk \
-d device-name \ -b revanced-patches.jar \
--mount -e microg-support \
--mount
``` ```
> **Note**: Some patches from [ReVanced Patches](https://github.com/revanced/revanced-patches) also require [ReVanced Integrations](https://github.com/revanced/revanced-integrations). Supply them with the option `-m`. ReVanced Patcher will merge ReVanced Integrations automatically, depending on if the supplied patches require them. > **Note**:
>
- ### ⚙️ Supply options to patches using ReVanced CLI > - If you want to exclude patches, you can use the option `-e`. In the case of YouTube, you can exclude
the `microg-support` patch from [ReVanced Patches](https://github.com/revanced/revanced-patches) with the
Some patches provide options. Currently, ReVanced CLI will generate and consume an `options.json` file at the location that is specified in `-o`. If the option is not specified, the options file will be generated in the current working directory. option `-e microg-support` when mounting for example.
>
The options file contains all options from supplied patch bundles. > - Some patches from [ReVanced Patches](https://github.com/revanced/revanced-patches) also might require
[ReVanced Integrations](https://github.com/revanced/revanced-integrations). Supply them with the option `-m`.
> **Note**: The `options.json` file will be generated at the first time you use ReVanced CLI to patch an APK file for now. This will be changed in the future. > The integrations will be merged, if necessary automatically, if supplied.
>
> - If you supplied a device with the option `-d`, the patched application will be automatically installed on the
device.

View File

@@ -1,8 +1,8 @@
# 💻 Documentation and guides of ReVanced CLI # 💻 Documentation and guides of ReVanced CLI
This documentation explains how to use [ReVanced CLI](https://github.com/revanced/revanced-cli). This documentation explain, how to use the [ReVanced CLI](https://github.com/revanced/revanced-cli).
## 📖 Table of contents ## 📖 Table of contents
1. [💼 Prerequisites](0_prerequisites.md) 1. [💼 Prerequisites](0_prerequisites.md)
2. [🛠️ Using ReVanced CLI](1_usage.md) 2. [🛠️ Using the ReVanced CLI](1_usage.md)

View File

@@ -1,2 +1,2 @@
kotlin.code.style = official kotlin.code.style = official
version = 2.21.5 version = 2.20.1-dev.1

View File

@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.1.1-all.zip distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-all.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

View File

@@ -7,24 +7,16 @@ import app.revanced.cli.patcher.logging.impl.PatcherLogger
import app.revanced.cli.signing.Signing import app.revanced.cli.signing.Signing
import app.revanced.cli.signing.SigningOptions import app.revanced.cli.signing.SigningOptions
import app.revanced.patcher.PatcherOptions import app.revanced.patcher.PatcherOptions
import app.revanced.patcher.data.Context
import app.revanced.patcher.extensions.PatchExtensions.compatiblePackages import app.revanced.patcher.extensions.PatchExtensions.compatiblePackages
import app.revanced.patcher.extensions.PatchExtensions.description import app.revanced.patcher.extensions.PatchExtensions.description
import app.revanced.patcher.extensions.PatchExtensions.patchName import app.revanced.patcher.extensions.PatchExtensions.patchName
import app.revanced.patcher.patch.Patch
import app.revanced.patcher.util.patch.PatchBundle import app.revanced.patcher.util.patch.PatchBundle
import app.revanced.utils.Options import app.revanced.utils.OptionsLoader
import app.revanced.utils.Options.setOptions
import app.revanced.utils.adb.Adb import app.revanced.utils.adb.Adb
import picocli.CommandLine.* import picocli.CommandLine.*
import java.io.File import java.io.File
import java.nio.file.Files import java.nio.file.Files
/**
* Alias for return type of [PatchBundle.loadPatches].
*/
internal typealias PatchList = List<Class<out Patch<Context>>>
private class CLIVersionProvider : IVersionProvider { private class CLIVersionProvider : IVersionProvider {
override fun getVersion() = arrayOf( override fun getVersion() = arrayOf(
MainCommand::class.java.`package`.implementationVersion ?: "unknown" MainCommand::class.java.`package`.implementationVersion ?: "unknown"
@@ -63,8 +55,8 @@ internal object MainCommand : Runnable {
@Option(names = ["-b", "--bundle"], description = ["One or more bundles of patches"], required = true) @Option(names = ["-b", "--bundle"], description = ["One or more bundles of patches"], required = true)
var patchBundles = arrayOf<String>() var patchBundles = arrayOf<String>()
@Option(names = ["--options"], description = ["Path to patch options JSON file"]) @Option(names = ["--options"], description = ["Configuration file for all patch options"])
var optionsFile: File = File("options.json") var options: File = File("options.toml")
@ArgGroup(exclusive = false) @ArgGroup(exclusive = false)
var listingArgs: ListingArgs? = null var listingArgs: ListingArgs? = null
@@ -142,10 +134,7 @@ internal object MainCommand : Runnable {
PatchBundle.Jar(bundle).loadPatches() PatchBundle.Jar(bundle).loadPatches()
} }
args.patchArgs!!.optionsFile.let { OptionsLoader.init(args.patchArgs!!.options, allPatches)
if (it.exists()) allPatches.setOptions(it, logger)
else Options.serialize(allPatches, prettyPrint = true).let(it::writeText)
}
val patcher = app.revanced.patcher.Patcher( val patcher = app.revanced.patcher.Patcher(
PatcherOptions( PatcherOptions(

View File

@@ -1,7 +1,8 @@
package app.revanced.cli.patcher package app.revanced.cli.patcher
import app.revanced.cli.command.PatchList
import app.revanced.patcher.PatcherResult import app.revanced.patcher.PatcherResult
import app.revanced.patcher.data.Context
import app.revanced.patcher.patch.Patch
import app.revanced.utils.patcher.addPatchesFiltered import app.revanced.utils.patcher.addPatchesFiltered
import app.revanced.utils.patcher.applyPatchesVerbose import app.revanced.utils.patcher.applyPatchesVerbose
import app.revanced.utils.patcher.mergeFiles import app.revanced.utils.patcher.mergeFiles
@@ -9,7 +10,7 @@ import app.revanced.utils.patcher.mergeFiles
internal object Patcher { internal object Patcher {
internal fun start( internal fun start(
patcher: app.revanced.patcher.Patcher, patcher: app.revanced.patcher.Patcher,
allPatches: PatchList allPatches: List<Class<out Patch<Context>>>
): PatcherResult { ): PatcherResult {
// merge files like necessary integrations // merge files like necessary integrations
patcher.mergeFiles() patcher.mergeFiles()

View File

@@ -1,107 +0,0 @@
package app.revanced.utils
import app.revanced.cli.command.PatchList
import app.revanced.cli.logging.CliLogger
import app.revanced.patcher.extensions.PatchExtensions.options
import app.revanced.patcher.extensions.PatchExtensions.patchName
import app.revanced.patcher.patch.NoSuchOptionException
import app.revanced.utils.Options.PatchOption.Option
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import java.io.File
internal object Options {
private var mapper = jacksonObjectMapper()
/**
* Serializes the options for the patches in the list.
*
* @param patches The list of patches to serialize.
* @param prettyPrint Whether to pretty print the JSON.
* @return The JSON string containing the options.
* @see PatchList
*/
fun serialize(patches: PatchList, prettyPrint: Boolean = false): String = patches
.filter { it.options?.any() == true }
.map { patch ->
PatchOption(
patch.patchName,
patch.options!!.map { option -> Option(option.key, option.value) }
)
}
// See https://github.com/revanced/revanced-patches/pull/2434/commits/60e550550b7641705e81aa72acfc4faaebb225e7.
.distinctBy { it.patchName }
.let {
if (prettyPrint)
mapper.writerWithDefaultPrettyPrinter().writeValueAsString(it)
else
mapper.writeValueAsString(it)
}
/**
* Deserializes the options for the patches in the list.
*
* @param json The JSON string containing the options.
* @return The list of [PatchOption]s.
* @see PatchOption
* @see PatchList
*/
@Suppress("MemberVisibilityCanBePrivate")
fun deserialize(json: String): Array<PatchOption> = mapper.readValue(json, Array<PatchOption>::class.java)
/**
* Sets the options for the patches in the list.
*
* @param json The JSON string containing the options.
* @param logger The logger to use for logging.
*/
fun PatchList.setOptions(json: String, logger: CliLogger? = null) {
filter { it.options?.any() == true }.let { patches ->
if (patches.isEmpty()) return
val patchOptions = deserialize(json)
patches.forEach { patch ->
patchOptions.find { option -> option.patchName == patch.patchName }?.let {
it.options.forEach { option ->
try {
patch.options?.set(option.key, option.value)
?: logger?.warn("${patch.patchName} has no options")
} catch (e: NoSuchOptionException) {
logger?.error(e.message ?: "Unknown error")
}
}
}
}
}
}
/**
* Sets the options for the patches in the list.
*
* @param file The file containing the JSON string containing the options.
* @param logger The logger to use for logging.
* @see setOptions
*/
fun PatchList.setOptions(file: File, logger: CliLogger? = null) = setOptions(file.readText(), logger)
/**
* Data class for a patch and its [Option]s.
*
* @property patchName The name of the patch.
* @property options The [Option]s for the patch.
*/
internal data class PatchOption(
val patchName: String,
val options: List<Option>
) {
/**
* Data class for patch option.
*
* @property key The name of the option.
* @property value The value of the option.
*/
internal data class Option(val key: String, val value: Any?)
}
}

View File

@@ -0,0 +1,77 @@
package app.revanced.utils
import app.revanced.cli.command.MainCommand.logger
import app.revanced.patcher.Patcher
import app.revanced.patcher.data.Context
import app.revanced.patcher.extensions.PatchExtensions.options
import app.revanced.patcher.extensions.PatchExtensions.patchName
import app.revanced.patcher.patch.Patch
import cc.ekblad.toml.encodeToString
import cc.ekblad.toml.model.TomlValue
import cc.ekblad.toml.serialization.from
import cc.ekblad.toml.tomlMapper
import java.io.File
private typealias PatchList = List<Class<out Patch<Context>>>
private typealias OptionsMap = MutableMap<String, MutableMap<String, Any>>
object OptionsLoader {
@JvmStatic
private val mapper = tomlMapper {}
@JvmStatic
fun init(file: File, patches: PatchList) {
if (!file.exists()) file.createNewFile()
val map = mapper.decodeWithDefaults(generateDefaults(patches), TomlValue.from(file.toPath()))
readAndSet(map, patches)
save(map, file)
}
private fun readAndSet(map: OptionsMap, patches: PatchList) {
for ((patchName, options) in map) {
val patch = patches.find { it.patchName == patchName } ?: continue
val patchOptions = patch.options ?: continue
for ((key, value) in options) {
if (value == "null") { // backwards compatibility, subject to removal
options.remove(key)
continue
}
try {
patchOptions[key] = value
} catch (e: Exception) {
logger.error("Error while setting option $key for patch $patchName: ${e.message}")
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" or set the value if the option already exists.
# To 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 {
for (patch in patches) {
val options = patch.options ?: continue
if (!options.iterator().hasNext()) continue
put(patch.patchName, buildMap {
for (option in options) {
put(option.key, option.value ?: continue)
}
} as MutableMap)
}
} as MutableMap
}

View File

@@ -3,7 +3,6 @@ package app.revanced.utils.patcher
import app.revanced.cli.command.MainCommand import app.revanced.cli.command.MainCommand
import app.revanced.cli.command.MainCommand.args import app.revanced.cli.command.MainCommand.args
import app.revanced.cli.command.MainCommand.logger import app.revanced.cli.command.MainCommand.logger
import app.revanced.cli.command.PatchList
import app.revanced.patcher.Patcher import app.revanced.patcher.Patcher
import app.revanced.patcher.data.Context import app.revanced.patcher.data.Context
import app.revanced.patcher.extensions.PatchExtensions.compatiblePackages import app.revanced.patcher.extensions.PatchExtensions.compatiblePackages
@@ -11,7 +10,7 @@ import app.revanced.patcher.extensions.PatchExtensions.include
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
fun Patcher.addPatchesFiltered(allPatches: PatchList) { fun Patcher.addPatchesFiltered(allPatches: List<Class<out Patch<Context>>>) {
val packageName = this.context.packageMetadata.packageName val packageName = this.context.packageMetadata.packageName
val packageVersion = this.context.packageMetadata.packageVersion val packageVersion = this.context.packageMetadata.packageVersion
@@ -38,7 +37,7 @@ fun Patcher.addPatchesFiltered(allPatches: PatchList) {
val compatibleWith = compatiblePackages.joinToString(";") { _package -> val compatibleWith = compatiblePackages.joinToString(";") { _package ->
"${_package.name}: ${_package.versions.joinToString(", ")}" "${_package.name}: ${_package.versions.joinToString(", ")}"
} }
logger.warn("$prefix: Incompatible with version $packageVersion. This patch is only compatible with $compatibleWith") logger.warn("$prefix: Incompatible with version $packageVersion. This patch is only compatible with version $compatibleWith")
return@patchLoop return@patchLoop
} }
} }

View File

@@ -1,57 +0,0 @@
package app.revanced.patcher.options
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.data.Context
import app.revanced.patcher.patch.*
import app.revanced.utils.Options
import app.revanced.utils.Options.setOptions
import org.junit.jupiter.api.MethodOrderer
import org.junit.jupiter.api.Order
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.TestMethodOrder
class PatchOptionsTestPatch : BytecodePatch() {
override fun execute(context: BytecodeContext): PatchResult {
return PatchResultSuccess()
}
companion object : OptionsContainer() {
var key1 by option(
PatchOption.StringOption(
"key1", null, "title1", "description1"
)
)
var key2 by option(
PatchOption.BooleanOption(
"key2", true, "title2", "description2"
)
)
}
}
@TestMethodOrder(MethodOrderer.OrderAnnotation::class)
internal object PatchOptionOptionsTest {
private var patches = listOf(PatchOptionsTestPatch::class.java as Class<out Patch<Context>>)
@Test
@Order(1)
fun serializeTest() {
assert(SERIALIZED_JSON == Options.serialize(patches))
}
@Test
@Order(2)
fun loadOptionsTest() {
patches.setOptions(CHANGED_JSON)
assert(PatchOptionsTestPatch.key1 == "test")
assert(PatchOptionsTestPatch.key2 == false)
}
private const val SERIALIZED_JSON =
"[{\"patchName\":\"PatchOptionsTestPatch\",\"options\":[{\"key\":\"key1\",\"value\":null},{\"key\":\"key2\",\"value\":true}]}]"
private const val CHANGED_JSON =
"[{\"patchName\":\"PatchOptionsTestPatch\",\"options\":[{\"key\":\"key1\",\"value\":\"test\"},{\"key\":\"key2\",\"value\":false}]}]"
}