mirror of
https://github.com/ReVanced/revanced-cli.git
synced 2026-01-11 13:56:18 +00:00
feat: use separate command to list patches
This commit is contained in:
@@ -30,12 +30,15 @@ Learn how to ReVanced CLI.
|
|||||||
java -jar revanced-cli.jar -h
|
java -jar revanced-cli.jar -h
|
||||||
```
|
```
|
||||||
|
|
||||||
- ### 📃 List all available patches from supplied patch bundles
|
- ### 📃 List patches from supplied patch bundles
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
java -jar revanced-cli.jar
|
java -jar revanced-cli.jar \
|
||||||
-b revanced-patches.jar \
|
list-patches \
|
||||||
-l # Names of all patches will be in kebab-case
|
--with-packages \
|
||||||
|
--with-versions \
|
||||||
|
--with-options \
|
||||||
|
revanced-patches.jar
|
||||||
```
|
```
|
||||||
|
|
||||||
- ### 💉 Use ReVanced CLI to patch an APK file but deploy without root permissions
|
- ### 💉 Use ReVanced CLI to patch an APK file but deploy without root permissions
|
||||||
|
|||||||
@@ -0,0 +1,94 @@
|
|||||||
|
package app.revanced.cli.command
|
||||||
|
|
||||||
|
import app.revanced.patcher.PatchBundleLoader
|
||||||
|
import app.revanced.patcher.annotation.Package
|
||||||
|
import app.revanced.patcher.extensions.PatchExtensions.compatiblePackages
|
||||||
|
import app.revanced.patcher.extensions.PatchExtensions.description
|
||||||
|
import app.revanced.patcher.extensions.PatchExtensions.options
|
||||||
|
import app.revanced.patcher.extensions.PatchExtensions.patchName
|
||||||
|
import app.revanced.patcher.patch.PatchClass
|
||||||
|
import app.revanced.patcher.patch.PatchOption
|
||||||
|
import picocli.CommandLine
|
||||||
|
import picocli.CommandLine.Help.Visibility.ALWAYS
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
|
||||||
|
@CommandLine.Command(name = "list-patches", description = ["List patches from supplied patch bundles"])
|
||||||
|
class ListPatchesCommand : Runnable {
|
||||||
|
@CommandLine.Parameters(
|
||||||
|
description = ["Paths to patch bundles"],
|
||||||
|
arity = "1..*"
|
||||||
|
)
|
||||||
|
lateinit var patchBundles: Array<File>
|
||||||
|
|
||||||
|
@CommandLine.Option(
|
||||||
|
names = ["-d", "--with-descriptions"],
|
||||||
|
description = ["List their descriptions"],
|
||||||
|
showDefaultValue = ALWAYS
|
||||||
|
)
|
||||||
|
var withDescriptions: Boolean = true
|
||||||
|
|
||||||
|
@CommandLine.Option(
|
||||||
|
names = ["-p", "--with-packages"],
|
||||||
|
description = ["List the packages the patches are compatible with"],
|
||||||
|
showDefaultValue = ALWAYS
|
||||||
|
)
|
||||||
|
var withPackages: Boolean = false
|
||||||
|
|
||||||
|
@CommandLine.Option(
|
||||||
|
names = ["-v", "--with-versions"],
|
||||||
|
description = ["List the versions of the packages the patches are compatible with"],
|
||||||
|
showDefaultValue = ALWAYS
|
||||||
|
)
|
||||||
|
var withVersions: Boolean = false
|
||||||
|
|
||||||
|
@CommandLine.Option(
|
||||||
|
names = ["-o", "--with-options"],
|
||||||
|
description = ["List the options of the patches"],
|
||||||
|
showDefaultValue = ALWAYS
|
||||||
|
)
|
||||||
|
var withOptions: Boolean = false
|
||||||
|
|
||||||
|
override fun run() {
|
||||||
|
fun Package.buildString() = buildString {
|
||||||
|
if (withVersions && versions.isNotEmpty()) {
|
||||||
|
appendLine("Package name: $name")
|
||||||
|
appendLine("Compatible versions:")
|
||||||
|
append(versions.joinToString("\n") { version -> version }.prependIndent("\t"))
|
||||||
|
} else
|
||||||
|
append("Package name: $name")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun PatchOption<*>.buildString() = buildString {
|
||||||
|
appendLine("Title: $title")
|
||||||
|
appendLine("Description: $description")
|
||||||
|
|
||||||
|
value?.let {
|
||||||
|
appendLine("Key: $key")
|
||||||
|
append("Value: $it")
|
||||||
|
} ?: append("Key: $key")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun PatchClass.buildString() = buildString {
|
||||||
|
append("Name: $patchName")
|
||||||
|
|
||||||
|
if (withDescriptions) append("\nDescription: $description")
|
||||||
|
|
||||||
|
if (withOptions && options != null) {
|
||||||
|
appendLine("\nOptions:")
|
||||||
|
append(
|
||||||
|
options!!.joinToString("\n\n") { option -> option.buildString() }.prependIndent("\t")
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (withPackages && compatiblePackages != null) {
|
||||||
|
appendLine("\nCompatible packages:")
|
||||||
|
append(
|
||||||
|
compatiblePackages!!.joinToString("\n") { it.buildString() }.prependIndent("\t")
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MainCommand.logger.info(PatchBundleLoader.Jar(*patchBundles).joinToString("\n\n") { it.buildString() })
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -9,7 +9,6 @@ import app.revanced.patcher.PatchBundleLoader
|
|||||||
import app.revanced.patcher.Patcher
|
import app.revanced.patcher.Patcher
|
||||||
import app.revanced.patcher.PatcherOptions
|
import app.revanced.patcher.PatcherOptions
|
||||||
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.include
|
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.PatchClass
|
import app.revanced.patcher.patch.PatchClass
|
||||||
@@ -17,9 +16,13 @@ import app.revanced.utils.Options
|
|||||||
import app.revanced.utils.Options.setOptions
|
import app.revanced.utils.Options.setOptions
|
||||||
import app.revanced.utils.adb.AdbManager
|
import app.revanced.utils.adb.AdbManager
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
|
import picocli.CommandLine
|
||||||
import picocli.CommandLine.*
|
import picocli.CommandLine.*
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
CommandLine(MainCommand).execute(*args)
|
||||||
|
}
|
||||||
|
|
||||||
internal typealias PatchList = List<PatchClass>
|
internal typealias PatchList = List<PatchClass>
|
||||||
|
|
||||||
@@ -31,13 +34,15 @@ private class CLIVersionProvider : IVersionProvider {
|
|||||||
|
|
||||||
@Command(
|
@Command(
|
||||||
name = "ReVanced CLI",
|
name = "ReVanced CLI",
|
||||||
|
description = ["Command line application to use ReVanced"],
|
||||||
mixinStandardHelpOptions = true,
|
mixinStandardHelpOptions = true,
|
||||||
versionProvider = CLIVersionProvider::class
|
versionProvider = CLIVersionProvider::class,
|
||||||
|
subcommands = [ListPatchesCommand::class]
|
||||||
)
|
)
|
||||||
internal object MainCommand : Runnable {
|
internal object MainCommand : Runnable {
|
||||||
val logger = DefaultCliLogger()
|
val logger = DefaultCliLogger()
|
||||||
|
|
||||||
@ArgGroup(exclusive = false, multiplicity = "1")
|
// @ArgGroup(exclusive = false, multiplicity = "1")
|
||||||
lateinit var args: Args
|
lateinit var args: Args
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -63,9 +68,6 @@ 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 = emptyList<File>()
|
var patchBundles = emptyList<File>()
|
||||||
|
|
||||||
@ArgGroup(exclusive = false)
|
|
||||||
var listingArgs: ListingArgs? = null
|
|
||||||
|
|
||||||
@ArgGroup(exclusive = false)
|
@ArgGroup(exclusive = false)
|
||||||
var patchingArgs: PatchingArgs? = null
|
var patchingArgs: PatchingArgs? = null
|
||||||
|
|
||||||
@@ -140,27 +142,12 @@ internal object MainCommand : Runnable {
|
|||||||
)
|
)
|
||||||
var aaptBinaryPath = File("")
|
var aaptBinaryPath = File("")
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Arguments for printing patches to the console.
|
|
||||||
*/
|
|
||||||
class ListingArgs {
|
|
||||||
@Option(names = ["-l", "--list"], description = ["List patches"], required = true)
|
|
||||||
var listOnly: Boolean = false
|
|
||||||
|
|
||||||
@Option(names = ["--with-versions"], description = ["List patches and their compatible versions"])
|
|
||||||
var withVersions: Boolean = false
|
|
||||||
|
|
||||||
@Option(names = ["--with-packages"], description = ["List patches and their compatible packages"])
|
|
||||||
var withPackages: Boolean = false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun run() {
|
override fun run() {
|
||||||
val patchArgs = args.patchArgs
|
val patchArgs = args.patchArgs
|
||||||
|
|
||||||
if (patchArgs?.listingArgs?.listOnly == true) return printListOfPatches()
|
|
||||||
if (args.packageName != null) return uninstall()
|
if (args.packageName != null) return uninstall()
|
||||||
|
|
||||||
val patchingArgs = patchArgs?.patchingArgs ?: return
|
val patchingArgs = patchArgs?.patchingArgs ?: return
|
||||||
@@ -266,41 +253,6 @@ internal object MainCommand : Runnable {
|
|||||||
}.uninstall(args.packageName!!)
|
}.uninstall(args.packageName!!)
|
||||||
} ?: logger.error("No device serial specified")
|
} ?: logger.error("No device serial specified")
|
||||||
|
|
||||||
private fun printListOfPatches() {
|
|
||||||
val logged = mutableListOf<String>()
|
|
||||||
for (patch in PatchBundleLoader.Jar(*args.patchArgs!!.patchBundles.toTypedArray())) {
|
|
||||||
if (patch.patchName in logged) continue
|
|
||||||
for (compatiblePackage in patch.compatiblePackages ?: continue) {
|
|
||||||
val packageEntryStr = buildString {
|
|
||||||
// Add package if flag is set
|
|
||||||
if (args.patchArgs?.listingArgs?.withPackages == true) {
|
|
||||||
val packageName = compatiblePackage.name.padStart(25)
|
|
||||||
append(packageName)
|
|
||||||
append("\t")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add patch name
|
|
||||||
val patchName = patch.patchName.lowercase().replace(" ", "-").padStart(25)
|
|
||||||
append(patchName)
|
|
||||||
|
|
||||||
// Add description if flag is set.
|
|
||||||
append("\t")
|
|
||||||
append(patch.description)
|
|
||||||
|
|
||||||
// Add compatible versions, if flag is set
|
|
||||||
if (args.patchArgs?.listingArgs?.withVersions == true) {
|
|
||||||
val compatibleVersions = compatiblePackage.versions.joinToString(separator = ", ")
|
|
||||||
append("\t")
|
|
||||||
append(compatibleVersions)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
logged.add(patch.patchName)
|
|
||||||
logger.info(packageEntryStr)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun Patcher.filterPatchSelection(patches: PatchList) = buildList {
|
private fun Patcher.filterPatchSelection(patches: PatchList) = buildList {
|
||||||
val packageName = context.packageMetadata.packageName
|
val packageName = context.packageMetadata.packageName
|
||||||
val packageVersion = context.packageMetadata.packageVersion
|
val packageVersion = context.packageMetadata.packageVersion
|
||||||
@@ -374,4 +326,8 @@ internal object MainCommand : Runnable {
|
|||||||
add(patch)
|
add(patch)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
CommandLine(MainCommand).execute(*args)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
package app.revanced.cli.main
|
|
||||||
|
|
||||||
import app.revanced.cli.command.MainCommand
|
|
||||||
import picocli.CommandLine
|
|
||||||
|
|
||||||
internal fun main(args: Array<String>) {
|
|
||||||
CommandLine(MainCommand).execute(*args)
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user