Compare commits

..

No commits in common. "v5.0.2-dev.2" and "main" have entirely different histories.

4 changed files with 65 additions and 82 deletions

View File

@ -1,17 +1,3 @@
## [5.0.2-dev.2](https://github.com/ReVanced/revanced-cli/compare/v5.0.2-dev.1...v5.0.2-dev.2) (2025-04-25)
### Bug Fixes
* Do not print patch description if null ([bba90fe](https://github.com/ReVanced/revanced-cli/commit/bba90fede85e4632efb9509e5bcf9091a9435549))
## [5.0.2-dev.1](https://github.com/ReVanced/revanced-cli/compare/v5.0.1...v5.0.2-dev.1) (2025-04-20)
### Bug Fixes
* Group `mount` and `install` options into an argument group ([#364](https://github.com/ReVanced/revanced-cli/issues/364)) ([0c53a2d](https://github.com/ReVanced/revanced-cli/commit/0c53a2d1d75d3d934d134594751fe6cd0b000d1a))
## [5.0.1](https://github.com/ReVanced/revanced-cli/compare/v5.0.0...v5.0.1) (2025-04-14) ## [5.0.1](https://github.com/ReVanced/revanced-cli/compare/v5.0.0...v5.0.1) (2025-04-14)

View File

@ -1,4 +1,4 @@
org.gradle.parallel = true org.gradle.parallel = true
org.gradle.caching = true org.gradle.caching = true
kotlin.code.style = official kotlin.code.style = official
version = 5.0.2-dev.2 version = 5.0.1

View File

@ -85,55 +85,58 @@ internal object ListPatchesCommand : Runnable {
} }
} }
fun PatchOption<*>.buildString() = buildString { fun PatchOption<*>.buildString() =
appendLine("Title: $title")
description?.let { appendLine("Description: $it") }
appendLine("Required: $required")
default?.let {
appendLine("Key: $key")
append("Default: $it")
} ?: append("Key: $key")
values?.let { values ->
appendLine("\nPossible values:")
append(values.map { "${it.value} (${it.key})" }.joinToString("\n").prependIndent("\t"))
}
append("\nType: $type")
}
fun IndexedValue<Patch<*>>.buildString() = let { (index, patch) ->
buildString { buildString {
if (withIndex) appendLine("Index: $index") appendLine("Title: $title")
description?.let { appendLine("Description: $it") }
appendLine("Required: $required")
default?.let {
appendLine("Key: $key")
append("Default: $it")
} ?: append("Key: $key")
append("Name: ${patch.name}") values?.let { values ->
appendLine("\nPossible values:")
if (withDescriptions) patch.description?.let { append("\nDescription: $it") } append(values.map { "${it.value} (${it.key})" }.joinToString("\n").prependIndent("\t"))
append("\nEnabled: ${patch.use}")
if (withOptions && patch.options.isNotEmpty()) {
appendLine("\nOptions:")
append(
patch.options.values.joinToString("\n\n") { option ->
option.buildString()
}.prependIndent("\t"),
)
} }
if (withPackages && patch.compatiblePackages != null) { append("\nType: $type")
appendLine("\nCompatible packages:") }
append(
patch.compatiblePackages!!.joinToString("\n") { fun IndexedValue<Patch<*>>.buildString() =
it.buildString() let { (index, patch) ->
}.prependIndent("\t"), buildString {
) if (withIndex) appendLine("Index: $index")
append("Name: ${patch.name}")
if (withDescriptions) append("\nDescription: ${patch.description}")
append("\nEnabled: ${patch.use}")
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 { (compatiblePackageName, _) -> compatiblePackageName == name } fun Patch<*>.filterCompatiblePackages(name: String) =
?: withUniversalPatches compatiblePackages?.any { (compatiblePackageName, _) -> compatiblePackageName == name }
?: withUniversalPatches
val patches = loadPatchesFromJar(patchesFiles).withIndex().toList() val patches = loadPatchesFromJar(patchesFiles).withIndex().toList()

View File

@ -115,27 +115,21 @@ internal object PatchCommand : Runnable {
this.outputFilePath = outputFilePath?.absoluteFile this.outputFilePath = outputFilePath?.absoluteFile
} }
@ArgGroup(exclusive = false, multiplicity = "0..1") @CommandLine.Option(
internal var installation: Installation? = null names = ["-i", "--install"],
description = ["Serial of the ADB device to install to. If not specified, the first connected device will be used."],
// Empty string to indicate that the first connected device should be used.
fallbackValue = "",
arity = "0..1",
)
private var deviceSerial: String? = null
internal class Installation { @CommandLine.Option(
@CommandLine.Option( names = ["--mount"],
names = ["-i", "--install"], description = ["Install the patched APK file by mounting."],
required = true, showDefaultValue = ALWAYS,
description = ["Serial of the ADB device to install to. If not specified, the first connected device will be used."], )
fallbackValue = "", // Empty string is used to select the first of connected devices. private var mount: Boolean = false
arity = "0..1",
)
internal var deviceSerial: String? = null
@CommandLine.Option(
names = ["--mount"],
required = false,
description = ["Install the patched APK file by mounting."],
showDefaultValue = ALWAYS,
)
internal var mount: Boolean = false
}
@CommandLine.Option( @CommandLine.Option(
names = ["--keystore"], names = ["--keystore"],
@ -251,11 +245,11 @@ internal object PatchCommand : Runnable {
keyStoreFilePath ?: outputFilePath.parentFile keyStoreFilePath ?: outputFilePath.parentFile
.resolve("${outputFilePath.nameWithoutExtension}.keystore") .resolve("${outputFilePath.nameWithoutExtension}.keystore")
val installer = if (installation?.deviceSerial != null) { val installer = if (deviceSerial != null) {
val deviceSerial = installation?.deviceSerial!!.ifEmpty { null } val deviceSerial = deviceSerial!!.ifEmpty { null }
try { try {
if (installation?.mount == true) { if (mount) {
AdbRootInstaller(deviceSerial) AdbRootInstaller(deviceSerial)
} else { } else {
AdbInstaller(deviceSerial) AdbInstaller(deviceSerial)
@ -338,7 +332,7 @@ internal object PatchCommand : Runnable {
apk.copyTo(temporaryFilesPath.resolve(apk.name), overwrite = true).apply { apk.copyTo(temporaryFilesPath.resolve(apk.name), overwrite = true).apply {
patcherResult.applyTo(this) patcherResult.applyTo(this)
}.let { patchedApkFile -> }.let { patchedApkFile ->
if (installation?.mount != true) { if (!mount) {
ApkUtils.signApk( ApkUtils.signApk(
patchedApkFile, patchedApkFile,
outputFilePath, outputFilePath,
@ -361,7 +355,7 @@ internal object PatchCommand : Runnable {
// region Install. // region Install.
installation?.deviceSerial?.let { deviceSerial?.let {
runBlocking { runBlocking {
when (val result = installer!!.install(Installer.Apk(outputFilePath, packageName))) { when (val result = installer!!.install(Installer.Apk(outputFilePath, packageName))) {
RootInstallerResult.FAILURE -> logger.severe("Failed to mount the patched APK file") RootInstallerResult.FAILURE -> logger.severe("Failed to mount the patched APK file")