diff --git a/docs/1_usage.md b/docs/1_usage.md index 31ee72a3..68911ad3 100644 --- a/docs/1_usage.md +++ b/docs/1_usage.md @@ -13,10 +13,12 @@ java -jar revanced-cli.jar -h ## 📃 List patches ```bash -java -jar revanced-cli.jar list-patches --with-descriptions --with-packages --with-versions --with-options --with-universal-patches revanced-patches.rvp +java -jar revanced-cli.jar list-patches --with-packages --with-versions --with-options revanced-patches.rvp ``` -## 💉 Patch an app with the default list of patches +## 💉 Patch an app + +To patch an app using the default list of patches, use the `patch` command: ```bash java -jar revanced-cli.jar patch -b revanced-patches.rvp input.apk @@ -28,22 +30,37 @@ You can also use multiple patch bundles: java -jar revanced-cli.jar patch -b revanced-patches.rvp -b another-patches.rvp input.apk ``` -To manually include or exclude patches, use the options `-i` and `-e`. -Keep in mind the name of the patch must be an exact match. -You can also use the options `--ii` and `--ie` to include or exclude patches by their index -if two patches have the same name. -To know the indices of patches, use the option `--with-indices` when listing patches: +To change the default set of used patches, use the option `-i` or `-e` to use or disuse specific patches. +You can use the `list-patches` command to see which patches are used by default. + +To only use specific patches, you can use the option `--exclusive` combined with `-i`. +Remember that the options `-i` and `-e` match the patch's name exactly. Here is an example: ```bash -java -jar revanced-cli.jar list-patches --with-indices revanced-patches.rvp +java -jar revanced-cli.jar patch -b revanced-patches.rvp --exclusive -i "Patch name" -i "Another patch name" input.apk ``` -Then you can use the indices to include or exclude patches: +You can also use the options `--ii` and `--ie` to use or disuse patches by their index. +This is useful, if two patches happen to have the same name. +To know the indices of patches, use the command `list-patches`: + +```bash +java -jar revanced-cli.jar list-patches revanced-patches.rvp +``` + +Then you can use the indices to use or disuse patches: ```bash java -jar revanced-cli.jar patch -b revanced-patches.rvp --ii 123 --ie 456 input.apk ``` +You can combine the option `-i`, `-e`, `--ii`, `--ie` and `--exclusive`. Here is an example: + +```bash +java -jar revanced-cli.jar patch -b revanced-patches.rvp --exclusive -i "Patch name" --ii 123 input.apk +``` + + > [!TIP] > You can use the option `-d` to automatically install the patched app after patching. > Make sure ADB is working: @@ -62,7 +79,52 @@ java -jar revanced-cli.jar patch -b revanced-patches.rvp --ii 123 --ie 456 input > adb install input.apk > ``` -## 📦 Install an app manually +Patches can have options you can set using the option `--set-options`. +To know the options of a patch, use the option `--with-options` when listing patches: + +```bash +java -jar revanced-cli.jar list-patches --with-options revanced-patches.rvp +``` + +Each patch can have multiple options. You can set them using the option `--set-options`. +For example, to set the options for the patch with the name `Patch name` +with the key `key1` and `key2` to `value1` and `value2` respectively, use the following command: + +```bash +java -jar revanced-cli.jar patch -b revanced-patches.rvp --set-options "Patch name" -Okey1=value1 -Okey2=value2 input.apk +``` + +If you want to set a value to `null`, you can omit the value: + +```bash +java -jar revanced-cli.jar patch -b revanced-patches.rvp --set-options "Patch name" -Okey1 input.apk +``` + +> [!WARNING] +> The values of options are typed. If you set a value with the wrong type, the patching process will fail. +> The type of the option value can be seen when listing patches with the option `--with-options`. +> +> Example values: +> +> String: `string` +> Boolean: `true`, `false` +> Integer: `123` +> Double: `1.0` +> Float: `1.0f` +> Long: `1234567890`, `1L` +> List: `item1,item2,item3` +> +> In addition to that, you can escape quotes (`\"`, `\'`) and commas (`\,`) to treat values as string literals: +> +> Integer as string: `\'123\'` +> List with an integer, an integer as a string and a string with a comma: `123,\'123\',str\,ing` +> +> Example command with escaped quotes: +> +> ```bash +> java -jar revanced-cli.jar -b revanced-patches.rvp --set-options "Patch name" -OstringKey=\'1\' input.apk +> ``` +## 📦 Install an app manually ```bash java -jar revanced-cli.jar utility install -a input.apk diff --git a/src/main/kotlin/app/revanced/cli/command/ListCompatibleVersions.kt b/src/main/kotlin/app/revanced/cli/command/ListCompatibleVersions.kt index 31f5cfa4..9816fcf2 100644 --- a/src/main/kotlin/app/revanced/cli/command/ListCompatibleVersions.kt +++ b/src/main/kotlin/app/revanced/cli/command/ListCompatibleVersions.kt @@ -1,8 +1,8 @@ package app.revanced.cli.command import app.revanced.library.PackageName -import app.revanced.library.PatchUtils import app.revanced.library.VersionMap +import app.revanced.library.mostCommonCompatibleVersions import app.revanced.patcher.patch.loadPatchesFromJar import picocli.CommandLine import java.io.File @@ -12,7 +12,7 @@ import java.util.logging.Logger name = "list-versions", description = [ "List the most common compatible versions of apps that are compatible " + - "with the patches in the supplied patch bundles.", + "with the patches in the supplied patch bundles.", ], ) internal class ListCompatibleVersions : Runnable { @@ -58,8 +58,7 @@ internal class ListCompatibleVersions : Runnable { val patches = loadPatchesFromJar(patchBundles) - PatchUtils.getMostCommonCompatibleVersions( - patches, + patches.mostCommonCompatibleVersions( packageNames, countUnusedPatches, ).entries.joinToString("\n", transform = ::buildString).let(logger::info) diff --git a/src/main/kotlin/app/revanced/cli/command/ListPatchesCommand.kt b/src/main/kotlin/app/revanced/cli/command/ListPatchesCommand.kt index d3c66a10..079d8c0d 100644 --- a/src/main/kotlin/app/revanced/cli/command/ListPatchesCommand.kt +++ b/src/main/kotlin/app/revanced/cli/command/ListPatchesCommand.kt @@ -95,9 +95,11 @@ internal object ListPatchesCommand : Runnable { } ?: append("Key: $key") values?.let { values -> - appendLine("\nValid values:") + appendLine("\nPossible values:") append(values.map { "${it.value} (${it.key})" }.joinToString("\n").prependIndent("\t")) } + + append("\nType: $type") } fun IndexedValue>.buildString() = diff --git a/src/main/kotlin/app/revanced/cli/command/MainCommand.kt b/src/main/kotlin/app/revanced/cli/command/MainCommand.kt index 4d33a4de..5ceeef15 100644 --- a/src/main/kotlin/app/revanced/cli/command/MainCommand.kt +++ b/src/main/kotlin/app/revanced/cli/command/MainCommand.kt @@ -34,7 +34,6 @@ private object CLIVersionProvider : IVersionProvider { versionProvider = CLIVersionProvider::class, subcommands = [ PatchCommand::class, - OptionsCommand::class, ListPatchesCommand::class, ListCompatibleVersions::class, UtilityCommand::class, diff --git a/src/main/kotlin/app/revanced/cli/command/OptionsCommand.kt b/src/main/kotlin/app/revanced/cli/command/OptionsCommand.kt index dbc1ada3..e69de29b 100644 --- a/src/main/kotlin/app/revanced/cli/command/OptionsCommand.kt +++ b/src/main/kotlin/app/revanced/cli/command/OptionsCommand.kt @@ -1,62 +0,0 @@ -package app.revanced.cli.command - -import app.revanced.library.Options -import app.revanced.library.Options.setOptions -import app.revanced.patcher.patch.loadPatchesFromJar -import picocli.CommandLine -import picocli.CommandLine.Help.Visibility.ALWAYS -import java.io.File -import java.util.logging.Logger - -@CommandLine.Command( - name = "options", - description = ["Generate options file from patches."], -) -internal object OptionsCommand : Runnable { - private val logger = Logger.getLogger(OptionsCommand::class.java.name) - - @CommandLine.Parameters( - description = ["Paths to patch bundles."], - arity = "1..*", - ) - private lateinit var patchBundles: Set - - @CommandLine.Option( - names = ["-p", "--path"], - description = ["Path to patch options JSON file."], - showDefaultValue = ALWAYS, - ) - private var filePath: File = File("options.json") - - @CommandLine.Option( - names = ["-o", "--overwrite"], - description = ["Overwrite existing options file."], - showDefaultValue = ALWAYS, - ) - private var overwrite: Boolean = false - - @CommandLine.Option( - names = ["-u", "--update"], - description = ["Update existing options by adding missing and removing non-existent options."], - showDefaultValue = ALWAYS, - ) - private var update: Boolean = false - - override fun run() = - try { - loadPatchesFromJar(patchBundles).let { patches -> - val exists = filePath.exists() - if (!exists || overwrite) { - if (exists && update) patches.setOptions(filePath) - - Options.serialize(patches, prettyPrint = true).let(filePath::writeText) - } else { - throw OptionsFileAlreadyExistsException() - } - } - } catch (ex: OptionsFileAlreadyExistsException) { - logger.severe("Options file already exists, use --overwrite to override it") - } - - class OptionsFileAlreadyExistsException : Exception() -} diff --git a/src/main/kotlin/app/revanced/cli/command/PatchCommand.kt b/src/main/kotlin/app/revanced/cli/command/PatchCommand.kt index 69f24f16..2cade1da 100644 --- a/src/main/kotlin/app/revanced/cli/command/PatchCommand.kt +++ b/src/main/kotlin/app/revanced/cli/command/PatchCommand.kt @@ -2,21 +2,22 @@ package app.revanced.cli.command import app.revanced.library.ApkUtils import app.revanced.library.ApkUtils.applyTo -import app.revanced.library.Options -import app.revanced.library.Options.setOptions import app.revanced.library.installation.installer.* +import app.revanced.library.setOptions import app.revanced.patcher.Patcher import app.revanced.patcher.PatcherConfig import app.revanced.patcher.patch.Patch import app.revanced.patcher.patch.loadPatchesFromJar import kotlinx.coroutines.runBlocking import picocli.CommandLine +import picocli.CommandLine.ArgGroup import picocli.CommandLine.Help.Visibility.ALWAYS import picocli.CommandLine.Model.CommandSpec import picocli.CommandLine.Spec import java.io.File import java.io.PrintWriter import java.io.StringWriter +import java.util.* import java.util.logging.Logger @CommandLine.Command( @@ -27,7 +28,7 @@ internal object PatchCommand : Runnable { private val logger = Logger.getLogger(PatchCommand::class.java.name) @Spec - lateinit var spec: CommandSpec // injected by picocli + lateinit var spec: CommandSpec private lateinit var apk: File @@ -35,15 +36,15 @@ internal object PatchCommand : Runnable { @CommandLine.Option( names = ["-i", "--include"], - description = ["List of patches to include."], + description = ["List of patches to include by name."], ) private var includedPatches = hashSetOf() @CommandLine.Option( names = ["--ii"], - description = ["List of patches to include by their index in relation to the supplied patch bundles."], + description = ["List of patches to include by their index in the combined list of all supplied patch bundles."], ) - private var includedPatchesByIndex = arrayOf() + private var includedPatchesByIndex = setOf() @CommandLine.Option( names = ["-e", "--exclude"], @@ -53,15 +54,29 @@ internal object PatchCommand : Runnable { @CommandLine.Option( names = ["--ei"], - description = ["List of patches to exclude by their index in relation to the supplied patch bundles."], + description = ["List of patches to exclude by their index in the combined list of all supplied patch bundles."], ) - private var excludedPatchesByIndex = arrayOf() - - @CommandLine.Option( - names = ["--options"], - description = ["Path to patch options JSON file."], - ) - private var optionsFile: File? = null + private var excludedPatchesByIndex = setOf() + + @ArgGroup(exclusive = false, multiplicity = "0..*", heading = "Options:%n") + private lateinit var options: Set