feat: allow listing patches without other parameters (#42)

* feat: allow listing patches without other parameters

* make `-b` required
This commit is contained in:
bogadana 2022-06-21 00:53:36 +02:00 committed by GitHub
parent 75c3776498
commit b977d7039f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 94 additions and 71 deletions

View File

@ -8,6 +8,7 @@ import app.revanced.patcher.util.patch.implementation.JarPatchBundle
import app.revanced.utils.adb.Adb import app.revanced.utils.adb.Adb
import picocli.CommandLine.Command import picocli.CommandLine.Command
import picocli.CommandLine.Option import picocli.CommandLine.Option
import picocli.CommandLine.ArgGroup
import java.io.File import java.io.File
import java.nio.file.Files import java.nio.file.Files
@ -15,6 +16,28 @@ import java.nio.file.Files
name = "ReVanced-CLI", version = ["1.0.0"], mixinStandardHelpOptions = true, name = "ReVanced-CLI", version = ["1.0.0"], mixinStandardHelpOptions = true,
) )
internal object MainCommand : Runnable { internal object MainCommand : Runnable {
@ArgGroup(exclusive = false, multiplicity="1")
lateinit var args: Args
class Args
{
@Option(names = ["-b", "--bundles"], description = ["One or more bundles of patches"], required = true)
var patchBundles = arrayOf<String>()
@ArgGroup(exclusive = false)
lateinit var lArgs: ListingArgs
@ArgGroup(exclusive = false)
lateinit var pArgs: PatchingArgs
}
class ListingArgs {
@Option(names = ["-l", "--list"], description = ["List patches only"], required = true)
public var listOnly: Boolean = false
}
class PatchingArgs {
@Option(names = ["-a", "--apk"], description = ["Input file to be patched"], required = true) @Option(names = ["-a", "--apk"], description = ["Input file to be patched"], required = true)
lateinit var inputFile: File lateinit var inputFile: File
@ -36,12 +59,6 @@ internal object MainCommand : Runnable {
@Option(names = ["-m", "--merge"], description = ["One or more dex file containers to merge"]) @Option(names = ["-m", "--merge"], description = ["One or more dex file containers to merge"])
var mergeFiles = listOf<File>() var mergeFiles = listOf<File>()
@Option(names = ["-b", "--bundles"], description = ["One or more bundles of patches"])
var patchBundles = arrayOf<String>()
@Option(names = ["-l", "--list"], description = ["List patches only"])
var listOnly: Boolean = false
@Option(names = ["--install"], description = ["If specified, instead of mounting, install"]) @Option(names = ["--install"], description = ["If specified, instead of mounting, install"])
var install: Boolean = false var install: Boolean = false
@ -62,46 +79,52 @@ internal object MainCommand : Runnable {
description = ["Clean the temporal resource cache directory. This will be done anyways when running the patcher"] description = ["Clean the temporal resource cache directory. This will be done anyways when running the patcher"]
) )
var clean: Boolean = false var clean: Boolean = false
}
override fun run() { override fun run() {
if (listOnly) { try
for (patchBundlePath in patchBundles) for (patch in JarPatchBundle(patchBundlePath).loadPatches()) { {
if (args.lArgs.listOnly) {
for (patchBundlePath in args.patchBundles) for (patch in JarPatchBundle(patchBundlePath).loadPatches()) {
println("[available] ${patch.patchName}") println("[available] ${patch.patchName}")
} }
return return
} }
} catch (e: UninitializedPropertyAccessException) {}
val patcher = app.revanced.patcher.Patcher(PatcherOptions(inputFile, cacheDirectory, !disableResourcePatching)) val args = args.pArgs;
val outputFile = File(outputPath) val patcher = app.revanced.patcher.Patcher(PatcherOptions(args.inputFile, args.cacheDirectory, !args.disableResourcePatching))
val adb: Adb? = deploy?.let { val outputFile = File(args.outputPath)
Adb(outputFile, patcher.data.packageMetadata.packageName, deploy!!, install)
val adb: Adb? = args.deploy?.let {
Adb(outputFile, patcher.data.packageMetadata.packageName, args.deploy!!, args.install)
} }
val patchedFile = if (install) File(cacheDirectory).resolve("${outputFile.nameWithoutExtension}_raw.apk") else outputFile val patchedFile = if (args.install) File(args.cacheDirectory).resolve("${outputFile.nameWithoutExtension}_raw.apk") else outputFile
Patcher.start(patcher, patchedFile) Patcher.start(patcher, patchedFile)
println("[aligning & signing]") println("[aligning & signing]")
if (install) { if (args.install) {
Signing.start( Signing.start(
patchedFile, patchedFile,
outputFile, outputFile,
cn, args.cn,
password, args.password,
) )
} }
if (clean) File(cacheDirectory).deleteRecursively() if (args.clean) File(args.cacheDirectory).deleteRecursively()
adb?.let { adb?.let {
println("[deploying]") println("[deploying]")
it.deploy() it.deploy()
} }
if (clean && deploy != null) Files.delete(outputFile.toPath()) if (args.clean && args.deploy != null) Files.delete(outputFile.toPath())
println("[done]") println("[done]")
} }

View File

@ -1,9 +1,6 @@
package app.revanced.cli.patcher package app.revanced.cli.patcher
import app.revanced.cli.command.MainCommand.cacheDirectory import app.revanced.cli.command.MainCommand.args
import app.revanced.cli.command.MainCommand.disableResourcePatching
import app.revanced.cli.command.MainCommand
import app.revanced.cli.command.MainCommand.includedPatches
import app.revanced.utils.filesystem.ZipFileSystemUtils import app.revanced.utils.filesystem.ZipFileSystemUtils
import app.revanced.utils.patcher.addPatchesFiltered import app.revanced.utils.patcher.addPatchesFiltered
import app.revanced.utils.patcher.applyPatchesVerbose import app.revanced.utils.patcher.applyPatchesVerbose
@ -13,16 +10,18 @@ import java.nio.file.Files
internal object Patcher { internal object Patcher {
internal fun start(patcher: app.revanced.patcher.Patcher, output: File) { internal fun start(patcher: app.revanced.patcher.Patcher, output: File) {
val args = args.pArgs;
// merge files like necessary integrations // merge files like necessary integrations
patcher.mergeFiles() patcher.mergeFiles()
// add patches, but filter incompatible or excluded patches // add patches, but filter incompatible or excluded patches
patcher.addPatchesFiltered(includeFilter = includedPatches.isNotEmpty()) patcher.addPatchesFiltered(includeFilter = args.includedPatches.isNotEmpty())
// apply patches // apply patches
patcher.applyPatchesVerbose() patcher.applyPatchesVerbose()
// write output file // write output file
if (output.exists()) Files.delete(output.toPath()) if (output.exists()) Files.delete(output.toPath())
MainCommand.inputFile.copyTo(output) args.inputFile.copyTo(output)
ZipFileSystemUtils(output).use { fileSystem -> ZipFileSystemUtils(output).use { fileSystem ->
// replace all dex files // replace all dex files
@ -32,8 +31,8 @@ internal object Patcher {
} }
// write resources // write resources
if (!disableResourcePatching) { if (!args.disableResourcePatching) {
fileSystem.writePathRecursively(File(cacheDirectory).resolve("build").toPath()) fileSystem.writePathRecursively(File(args.cacheDirectory).resolve("build").toPath())
fileSystem.uncompress(*result.doNotCompress!!.toTypedArray()) fileSystem.uncompress(*result.doNotCompress!!.toTypedArray())
} }
} }

View File

@ -1,13 +1,13 @@
package app.revanced.cli.signing package app.revanced.cli.signing
import app.revanced.cli.command.MainCommand.cacheDirectory import app.revanced.cli.command.MainCommand.args
import app.revanced.utils.signing.Signer import app.revanced.utils.signing.Signer
import app.revanced.utils.signing.align.ZipAligner import app.revanced.utils.signing.align.ZipAligner
import java.io.File import java.io.File
object Signing { object Signing {
fun start(inputFile: File, outputFile: File, cn: String, password: String) { fun start(inputFile: File, outputFile: File, cn: String, password: String) {
val cacheDirectory = File(cacheDirectory) val cacheDirectory = File(args.pArgs.cacheDirectory)
val alignedOutput = cacheDirectory.resolve("${outputFile.nameWithoutExtension}_aligned.apk") val alignedOutput = cacheDirectory.resolve("${outputFile.nameWithoutExtension}_aligned.apk")
val signedOutput = cacheDirectory.resolve("${outputFile.nameWithoutExtension}_signed.apk") val signedOutput = cacheDirectory.resolve("${outputFile.nameWithoutExtension}_signed.apk")

View File

@ -1,8 +1,7 @@
package app.revanced.utils.patcher package app.revanced.utils.patcher
import app.revanced.cli.command.MainCommand import app.revanced.cli.command.MainCommand
import app.revanced.cli.command.MainCommand.debugging import app.revanced.cli.command.MainCommand.args
import app.revanced.cli.command.MainCommand.patchBundles
import app.revanced.patcher.Patcher import app.revanced.patcher.Patcher
import app.revanced.patcher.data.base.Data import app.revanced.patcher.data.base.Data
import app.revanced.patcher.extensions.PatchExtensions.compatiblePackages import app.revanced.patcher.extensions.PatchExtensions.compatiblePackages
@ -17,7 +16,7 @@ fun Patcher.addPatchesFiltered(
val packageName = this.data.packageMetadata.packageName val packageName = this.data.packageMetadata.packageName
val packageVersion = this.data.packageMetadata.packageVersion val packageVersion = this.data.packageMetadata.packageVersion
patchBundles.forEach { bundle -> MainCommand.args.patchBundles.forEach { bundle ->
val includedPatches = mutableListOf<Class<out Patch<Data>>>() val includedPatches = mutableListOf<Class<out Patch<Data>>>()
JarPatchBundle(bundle).loadPatches().forEach patch@{ patch -> JarPatchBundle(bundle).loadPatches().forEach patch@{ patch ->
val compatiblePackages = patch.compatiblePackages val compatiblePackages = patch.compatiblePackages
@ -25,8 +24,10 @@ fun Patcher.addPatchesFiltered(
val prefix = "[skipped] $patchName" val prefix = "[skipped] $patchName"
val args = MainCommand.args.pArgs
if (includeFilter) { if (includeFilter) {
if (!MainCommand.includedPatches.contains(patchName)) { if (!args.includedPatches.contains(patchName)) {
println("$prefix: Explicitly excluded.") println("$prefix: Explicitly excluded.")
return@patch return@patch
} }
@ -42,7 +43,7 @@ fun Patcher.addPatchesFiltered(
return@patch return@patch
} }
if (!(debugging || compatiblePackages.any { it.versions.isEmpty() || it.versions.any { version -> version == packageVersion }})) { if (!(args.debugging || compatiblePackages.any { it.versions.isEmpty() || it.versions.any { version -> version == packageVersion }})) {
println("$prefix: The package version is $packageVersion and is incompatible.") println("$prefix: The package version is $packageVersion and is incompatible.")
return@patch return@patch
} }
@ -67,5 +68,5 @@ fun Patcher.applyPatchesVerbose() {
} }
fun Patcher.mergeFiles() { fun Patcher.mergeFiles() {
this.addFiles(MainCommand.mergeFiles) this.addFiles(MainCommand.args.pArgs.mergeFiles)
} }