diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index f70eea1..766c44d 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -4,7 +4,7 @@ kotlin-test = "1.9.20" kotlinx-coroutines-core = "1.7.3" picocli = "4.7.3" revanced-patcher = "19.0.0" -revanced-library = "1.3.0" +revanced-library = "1.4.0" [libraries] kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlin-test" } diff --git a/src/main/kotlin/app/revanced/cli/command/ListCompatibleVersions.kt b/src/main/kotlin/app/revanced/cli/command/ListCompatibleVersions.kt new file mode 100644 index 0000000..ab21eee --- /dev/null +++ b/src/main/kotlin/app/revanced/cli/command/ListCompatibleVersions.kt @@ -0,0 +1,67 @@ +package app.revanced.cli.command + +import app.revanced.library.PackageName +import app.revanced.library.PatchUtils +import app.revanced.library.VersionMap +import app.revanced.patcher.PatchBundleLoader +import picocli.CommandLine +import java.io.File +import java.util.logging.Logger + +@CommandLine.Command( + name = "list-versions", + description = [ + "List the most common compatible versions of apps that are compatible " + + "with the patches in the supplied patch bundles.", + ], +) +internal class ListCompatibleVersions : Runnable { + private val logger = Logger.getLogger(ListCompatibleVersions::class.java.name) + + @CommandLine.Parameters( + description = ["Paths to patch bundles."], + arity = "1..*", + ) + private lateinit var patchBundles: Array + + @CommandLine.Option( + names = ["-f", "--filter-package-names"], + description = ["Filter patches by package name."], + ) + private var packageNames: Set? = null + + @CommandLine.Option( + names = ["-u", "--count-unused-patches"], + description = ["Count patches that are not used by default."], + showDefaultValue = CommandLine.Help.Visibility.ALWAYS, + ) + private var countUnusedPatches: Boolean = false + + override fun run() { + val patches = PatchBundleLoader.Jar(*patchBundles) + + fun VersionMap.buildVersionsString(): String { + if (isEmpty()) return "Any" + + fun buildPatchesCountString(count: Int) = if (count == 1) "1 patch" else "$count patches" + + return entries.joinToString("\n") { (version, count) -> + "$version (${buildPatchesCountString(count)})" + } + } + + fun buildString(entry: Map.Entry) = + buildString { + val (name, versions) = entry + appendLine("Package name: $name") + appendLine("Most common compatible versions:") + appendLine(versions.buildVersionsString().prependIndent("\t")) + } + + PatchUtils.getMostCommonCompatibleVersions( + patches, + packageNames, + countUnusedPatches, + ).entries.joinToString("\n", transform = ::buildString).let(logger::info) + } +} diff --git a/src/main/kotlin/app/revanced/cli/command/MainCommand.kt b/src/main/kotlin/app/revanced/cli/command/MainCommand.kt index 7a76097..4d33a4d 100644 --- a/src/main/kotlin/app/revanced/cli/command/MainCommand.kt +++ b/src/main/kotlin/app/revanced/cli/command/MainCommand.kt @@ -33,9 +33,10 @@ private object CLIVersionProvider : IVersionProvider { mixinStandardHelpOptions = true, versionProvider = CLIVersionProvider::class, subcommands = [ - ListPatchesCommand::class, PatchCommand::class, OptionsCommand::class, + ListPatchesCommand::class, + ListCompatibleVersions::class, UtilityCommand::class, ], )