diff --git a/CHANGELOG.md b/CHANGELOG.md index cb23fd3..92b969b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,28 @@ +# [4.1.0-dev.3](https://github.com/ReVanced/revanced-cli/compare/v4.1.0-dev.2...v4.1.0-dev.3) (2023-11-03) + +# [4.1.0-dev.2](https://github.com/ReVanced/revanced-cli/compare/v4.1.0-dev.1...v4.1.0-dev.2) (2023-11-03) + + +### Features + +* Include or exclude patches by their index in relation to supplied patch bundles ([b2055ce](https://github.com/ReVanced/revanced-cli/commit/b2055ce07df3ab9a9f3f73ab17d8c2cf02f2ae62)) + + +### Performance Improvements + +* Use a `HashSet` to check for included and excluded patches ([616d14f](https://github.com/ReVanced/revanced-cli/commit/616d14f0097c1ee7ba6dc07be417590f6418e8e5)) + +# [4.1.0-dev.1](https://github.com/ReVanced/revanced-cli/compare/v4.0.3-dev.2...v4.1.0-dev.1) (2023-11-03) + + +### Features + +* List patches which are compatible with any app ([#297](https://github.com/ReVanced/revanced-cli/issues/297)) ([0139dfe](https://github.com/ReVanced/revanced-cli/commit/0139dfe0bfa06a13f56dc03e7718aaf644029614)) + +## [4.0.3-dev.2](https://github.com/ReVanced/revanced-cli/compare/v4.0.3-dev.1...v4.0.3-dev.2) (2023-10-30) + +## [4.0.3-dev.1](https://github.com/ReVanced/revanced-cli/compare/v4.0.2...v4.0.3-dev.1) (2023-10-23) + ## [4.0.2](https://github.com/ReVanced/revanced-cli/compare/v4.0.1...v4.0.2) (2023-10-12) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 8eeb27a..e3d551b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -39,7 +39,7 @@ Continuing the legacy of Vanced

-# 📙 ReVanced CLI contribution guidelines +# 👋 Contribution guidelines This document describes how to contribute to ReVanced CLI. @@ -76,4 +76,4 @@ If you encounter a bug while using ReVanced CLI, open an issue using the it will be merged into the `dev` branch and will be included in the next release of ReVanced CLI ❤️ Thank you for considering contributing to ReVanced CLI, -ReVanced \ No newline at end of file +ReVanced diff --git a/build.gradle.kts b/build.gradle.kts index 536d172..fc12ab7 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - kotlin("jvm") version "1.9.0" + kotlin("jvm") version "1.9.10" alias(libs.plugins.shadow) } 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/gradle.properties b/gradle.properties index dc74906..18b12a1 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ org.gradle.parallel = true org.gradle.caching = true kotlin.code.style = official -version = 4.0.2 +version = 4.1.0-dev.3 diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 213e17a..b6a699c 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -3,14 +3,14 @@ shadow = "8.1.1" kotlin-test = "1.8.20-RC" kotlinx-coroutines-core = "1.7.3" picocli = "4.7.3" -revanced-patcher = "17.0.0" -revanced-library = "1.1.3" +revanced-patcher = "19.0.0" +revanced-library = "1.2.0" [libraries] kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlin-test" } kotlinx-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "kotlinx-coroutines-core" } picocli = { module = "info.picocli:picocli", version.ref = "picocli" } -revanced-patcher = { module = "app.revanced.revanced-patcher:revanced-patcher", version.ref = "revanced-patcher" } +revanced-patcher = { module = "app.revanced:revanced-patcher", version.ref = "revanced-patcher" } revanced-library = { module = "app.revanced:revanced-library", version.ref = "revanced-library" } [plugins] diff --git a/src/main/kotlin/app/revanced/cli/command/ListPatchesCommand.kt b/src/main/kotlin/app/revanced/cli/command/ListPatchesCommand.kt index 3c3aac2..b9e11b0 100644 --- a/src/main/kotlin/app/revanced/cli/command/ListPatchesCommand.kt +++ b/src/main/kotlin/app/revanced/cli/command/ListPatchesCommand.kt @@ -42,6 +42,20 @@ internal object ListPatchesCommand : Runnable { ) private var withOptions: Boolean = false + @Option( + names = ["-u", "--with-universal-patches"], + description = ["List patches which are compatible with any app."], + showDefaultValue = ALWAYS + ) + 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."] ) @@ -58,41 +72,51 @@ internal object ListPatchesCommand : Runnable { fun PatchOption<*>.buildString() = buildString { appendLine("Title: $title") - appendLine("Description: $description") - - value?.let { + description?.let { appendLine("Description: $it") } + default?.let { appendLine("Key: $key") - append("Value: $it") + append("Default: $it") } ?: append("Key: $key") - } - fun Patch<*>.buildString() = buildString { - append("Name: $name") - - if (withDescriptions) append("\nDescription: $description") - - if (withOptions && options.isNotEmpty()) { - appendLine("\nOptions:") - append( - options.values.joinToString("\n\n") { option -> - option.buildString() - }.prependIndent("\t") - ) - } - - if (withPackages && compatiblePackages != null) { - appendLine("\nCompatible packages:") - append( - compatiblePackages!!.joinToString("\n") { it.buildString() }.prependIndent("\t") - ) + values?.let { values -> + appendLine("\nValid values:") + append(values.map { "${it.value} (${it.key})" }.joinToString("\n").prependIndent("\t")) } } - fun Patch<*>.anyPackageName(name: String) = compatiblePackages?.any { it.name == name } == true + fun IndexedValue>.buildString() = let { (index, patch) -> + buildString { + if (withIndex) appendLine("Index: $index") - val patches = PatchBundleLoader.Jar(*patchBundles) + append("Name: ${patch.name}") - val filtered = packageName?.let { patches.filter { patch -> patch.anyPackageName(it) } } ?: patches + if (withDescriptions) append("\nDescription: ${patch.description}") + + 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).withIndex().toList() + + 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..0603783 100644 --- a/src/main/kotlin/app/revanced/cli/command/PatchCommand.kt +++ b/src/main/kotlin/app/revanced/cli/command/PatchCommand.kt @@ -37,12 +37,24 @@ internal object PatchCommand : Runnable { @CommandLine.Option( names = ["-i", "--include"], description = ["List of patches to include."] ) - private var includedPatches = arrayOf() + private var includedPatches = hashSetOf() + + @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() + private var excludedPatches = hashSetOf() + + @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 @@ -188,7 +200,7 @@ internal object PatchCommand : Runnable { // Warn if a patch can not be found in the supplied patch bundles. if (warn) patches.map { it.name }.toHashSet().let { availableNames -> - arrayOf(*includedPatches, *excludedPatches).filter { name -> + (includedPatches + excludedPatches).filter { name -> !availableNames.contains(name) } }.let { unknownPatches -> @@ -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.