From b2055ce07df3ab9a9f3f73ab17d8c2cf02f2ae62 Mon Sep 17 00:00:00 2001 From: oSumAtrIX Date: Fri, 3 Nov 2023 02:00:00 +0100 Subject: [PATCH] feat: Include or exclude patches by their index in relation to supplied patch bundles --- docs/1_usage.md | 15 ++++++ .../cli/command/ListPatchesCommand.kt | 48 ++++++++++++------- .../app/revanced/cli/command/PatchCommand.kt | 18 +++++-- 3 files changed, 60 insertions(+), 21 deletions(-) diff --git a/docs/1_usage.md b/docs/1_usage.md index e9fb42b..1a885b4 100644 --- a/docs/1_usage.md +++ b/docs/1_usage.md @@ -87,10 +87,25 @@ ReVanced CLI is divided into the following fundamental commands: > adb install app.apk > ``` + > [!NOTE] + > You can use the option `--ii` to include or `--ie` to exclude + > patches by their index in relation to supplied patch bundles, + > similarly to the option `--include` and `--exclude`. + > + > This is useful in case two patches have the same name, and you need to include or exclude one of them. + > The index of a patch is calculated by the position of the patch in the list of patches + > from patch bundles supplied using the option `--patch-bundle`. + > + > You can list all patches with their indices using the command `list-patches`. + > + > Keep in mind, that the indices can change based on the order of the patch bundles supplied, + > as well if the patch bundles are updated, because patches can be added or removed. + ```bash java -jar revanced-cli.jar patch \ --patch-bundle revanced-patches.jar \ --include "Some patch" \ + --ii 123 \ --exclude "Some other patch" \ --out patched-app.apk \ --device-serial \ diff --git a/src/main/kotlin/app/revanced/cli/command/ListPatchesCommand.kt b/src/main/kotlin/app/revanced/cli/command/ListPatchesCommand.kt index 52b0e8c..b9e11b0 100644 --- a/src/main/kotlin/app/revanced/cli/command/ListPatchesCommand.kt +++ b/src/main/kotlin/app/revanced/cli/command/ListPatchesCommand.kt @@ -49,6 +49,13 @@ internal object ListPatchesCommand : Runnable { ) private var withUniversalPatches: Boolean = true + @Option( + names = ["-i", "--index"], + description = ["List the index of of each patch in relation to the supplied patch bundles."], + showDefaultValue = ALWAYS + ) + private var withIndex: Boolean = true + @Option( names = ["-f", "--filter-package-name"], description = ["Filter patches by package name."] ) @@ -77,34 +84,39 @@ internal object ListPatchesCommand : Runnable { } } - fun Patch<*>.buildString() = buildString { - append("Name: $name") + fun IndexedValue>.buildString() = let { (index, patch) -> + buildString { + if (withIndex) appendLine("Index: $index") - if (withDescriptions) append("\nDescription: $description") + append("Name: ${patch.name}") - if (withOptions && options.isNotEmpty()) { - appendLine("\nOptions:") - append( - options.values.joinToString("\n\n") { option -> - option.buildString() - }.prependIndent("\t") - ) - } + if (withDescriptions) append("\nDescription: ${patch.description}") - if (withPackages && compatiblePackages != null) { - appendLine("\nCompatible packages:") - append( - compatiblePackages!!.joinToString("\n") { it.buildString() }.prependIndent("\t") - ) + if (withOptions && patch.options.isNotEmpty()) { + appendLine("\nOptions:") + append( + patch.options.values.joinToString("\n\n") { option -> + option.buildString() + }.prependIndent("\t") + ) + } + + if (withPackages && patch.compatiblePackages != null) { + appendLine("\nCompatible packages:") + append(patch.compatiblePackages!!.joinToString("\n") { + it.buildString() + }.prependIndent("\t")) + } } } fun Patch<*>.filterCompatiblePackages(name: String) = compatiblePackages?.any { it.name == name } ?: withUniversalPatches - val patches = PatchBundleLoader.Jar(*patchBundles) + val patches = PatchBundleLoader.Jar(*patchBundles).withIndex().toList() - val filtered = packageName?.let { patches.filter { patch -> patch.filterCompatiblePackages(it) } } ?: patches + val filtered = + packageName?.let { patches.filter { (_, patch) -> patch.filterCompatiblePackages(it) } } ?: patches if (filtered.isNotEmpty()) logger.info(filtered.joinToString("\n\n") { it.buildString() }) } diff --git a/src/main/kotlin/app/revanced/cli/command/PatchCommand.kt b/src/main/kotlin/app/revanced/cli/command/PatchCommand.kt index 8781136..34ba6eb 100644 --- a/src/main/kotlin/app/revanced/cli/command/PatchCommand.kt +++ b/src/main/kotlin/app/revanced/cli/command/PatchCommand.kt @@ -39,11 +39,23 @@ internal object PatchCommand : Runnable { ) private var includedPatches = arrayOf() + @CommandLine.Option( + names = ["--ii"], + description = ["List of patches to include by their index in relation to the supplied patch bundles."] + ) + private var includedPatchesByIndex = arrayOf() + @CommandLine.Option( names = ["-e", "--exclude"], description = ["List of patches to exclude."] ) private var excludedPatches = arrayOf() + @CommandLine.Option( + names = ["--ei"], + description = ["List of patches to exclude by their index in relation to the supplied patch bundles."] + ) + private var excludedPatchesByIndex = arrayOf() + @CommandLine.Option( names = ["--options"], description = ["Path to patch options JSON file."], showDefaultValue = ALWAYS ) @@ -283,10 +295,10 @@ internal object PatchCommand : Runnable { val packageName = context.packageMetadata.packageName val packageVersion = context.packageMetadata.packageVersion - patches.forEach patch@{ patch -> + patches.withIndex().forEach patch@{ (i, patch) -> val patchName = patch.name!! - val explicitlyExcluded = excludedPatches.contains(patchName) + val explicitlyExcluded = excludedPatches.contains(patchName) || excludedPatchesByIndex.contains(i) if (explicitlyExcluded) return@patch logger.info("Excluding $patchName") // Make sure the patch is compatible with the supplied APK files package name and version. @@ -314,7 +326,7 @@ internal object PatchCommand : Runnable { // If the patch is implicitly used, it will be only included if [exclusive] is false. val implicitlyIncluded = !exclusive && patch.use // If the patch is explicitly used, it will be included even if [exclusive] is false. - val explicitlyIncluded = includedPatches.contains(patchName) + val explicitlyIncluded = includedPatches.contains(patchName) || includedPatchesByIndex.contains(i) val included = implicitlyIncluded || explicitlyIncluded if (!included) return@patch logger.info("$patchName excluded") // Case 1.