diff --git a/src/main/kotlin/app/revanced/cli/aligning/Aligning.kt b/src/main/kotlin/app/revanced/cli/aligning/Aligning.kt index da85fc2..ef6d615 100644 --- a/src/main/kotlin/app/revanced/cli/aligning/Aligning.kt +++ b/src/main/kotlin/app/revanced/cli/aligning/Aligning.kt @@ -1,19 +1,12 @@ package app.revanced.cli.aligning -import app.revanced.cli.command.MainCommand import app.revanced.cli.command.MainCommand.logger import app.revanced.utils.signing.align.ZipAligner import java.io.File object Aligning { fun align(inputFile: File, outputFile: File) { - val cacheDirectory = File(MainCommand.args.sArgs?.pArgs?.cacheDirectory) - val alignedOutput = cacheDirectory.resolve("${outputFile.nameWithoutExtension}_aligned.apk") - - logger.info("Aligning ${inputFile.name}") - ZipAligner.align(inputFile, alignedOutput) - - logger.info("Copying ${alignedOutput.name} to ${outputFile.name}") - alignedOutput.copyTo(outputFile, true) - } + logger.info("Aligning ${inputFile.name} to ${outputFile.name}") + ZipAligner.align(inputFile, outputFile) } +} diff --git a/src/main/kotlin/app/revanced/cli/command/MainCommand.kt b/src/main/kotlin/app/revanced/cli/command/MainCommand.kt index d0b057b..8d0737d 100644 --- a/src/main/kotlin/app/revanced/cli/command/MainCommand.kt +++ b/src/main/kotlin/app/revanced/cli/command/MainCommand.kt @@ -44,18 +44,18 @@ internal object MainCommand : Runnable { var deploy: String? = null @ArgGroup(exclusive = false) - var sArgs: StartPatcherArgs? = null + var patchArgs: PatchArgs? = null } - class StartPatcherArgs { + class PatchArgs { @Option(names = ["-b", "--bundles"], description = ["One or more bundles of patches"], required = true) var patchBundles = arrayOf() @ArgGroup(exclusive = false) - var lArgs: ListingArgs? = null + var listingArgs: ListingArgs? = null @ArgGroup(exclusive = false) - var pArgs: PatchingArgs? = null + var patchingArgs: PatchingArgs? = null } class ListingArgs { @@ -79,7 +79,10 @@ internal object MainCommand : Runnable { @Option(names = ["-e", "--exclude"], description = ["Explicitly exclude patches"]) var excludedPatches = arrayOf() - @Option(names = ["--exclusive"], description = ["Only installs the patches you include, not including any patch by default"]) + @Option( + names = ["--exclusive"], + description = ["Only installs the patches you include, not including any patch by default"] + ) var defaultExclude = false @Option(names = ["-i", "--include"], description = ["Include patches"]) @@ -120,85 +123,114 @@ internal object MainCommand : Runnable { } override fun run() { - if (args.sArgs?.lArgs?.listOnly == true) { + if (args.patchArgs?.listingArgs?.listOnly == true) { printListOfPatches() return } if (args.uninstall) { - // temporarily get package name using Patcher method - // fix: abstract options in patcher - val patcher = app.revanced.patcher.Patcher( - PatcherOptions( - args.inputFile, - "uninstaller-cache", - false - ) - ) - File("uninstaller-cache").deleteRecursively() - - val adb: Adb? = args.deploy?.let { - Adb(File("placeholder_file"), patcher.data.packageMetadata.packageName, args.deploy!!, false) - } - adb?.uninstall() - + uninstall() return } - val _args = args - val args = args.sArgs?.pArgs ?: return + val pArgs = this.args.patchArgs?.patchingArgs ?: return + + // the file to write to + val outputFile = File(pArgs.outputPath) val patcher = app.revanced.patcher.Patcher( PatcherOptions( - _args.inputFile, - args.cacheDirectory, - !args.disableResourcePatching, - args.aaptPath, + args.inputFile, + pArgs.cacheDirectory, + !pArgs.disableResourcePatching, + pArgs.aaptPath, logger = PatcherLogger ) ) - val outputFile = File(args.outputPath) - - val adb: Adb? = _args.deploy?.let { - Adb(outputFile, patcher.data.packageMetadata.packageName, _args.deploy!!, !args.mount) + // prepare adb + val adb: Adb? = args.deploy?.let { + Adb(outputFile, patcher.data.packageMetadata.packageName, args.deploy!!, !pArgs.mount) } - val patchedFile = File(args.cacheDirectory).resolve("${outputFile.nameWithoutExtension}_raw.apk") + val patchedFile = File(pArgs.cacheDirectory).resolve("${outputFile.nameWithoutExtension}_raw.apk") + + // start the patcher Patcher.start(patcher, patchedFile) - if (!args.mount) { - Signing.start( - patchedFile, - outputFile, + val cacheDirectory = File(pArgs.cacheDirectory) + + // align the file + val alignedFile = cacheDirectory.resolve("${outputFile.nameWithoutExtension}_aligned.apk") + Aligning.align(patchedFile, alignedFile) + + // sign the file + val finalFile = if (!pArgs.mount) { + val signedOutput = cacheDirectory.resolve("${outputFile.nameWithoutExtension}_signed.apk") + Signing.sign( + alignedFile, + signedOutput, SigningOptions( - args.cn, - args.password, - args.keystorePath ?: outputFile.absoluteFile.parentFile + pArgs.cn, + pArgs.password, + pArgs.keystorePath ?: outputFile.absoluteFile.parentFile .resolve("${outputFile.nameWithoutExtension}.keystore") .canonicalPath ) ) - } - else { - Aligning.align(patchedFile, outputFile) - } - if (args.clean) File(args.cacheDirectory).deleteRecursively() + signedOutput + } else + alignedFile + // finally copy to the specified output file + logger.info("Copying ${finalFile.name} to ${outputFile.name}") + finalFile.copyTo(outputFile, overwrite = true) + + // clean up the cache directory if needed + if (pArgs.clean) + cleanUp(pArgs.cacheDirectory) + + // deploy if specified adb?.deploy() - if (args.clean && _args.deploy != null) Files.delete(outputFile.toPath()) + if (pArgs.clean && args.deploy != null) Files.delete(outputFile.toPath()) logger.info("Finished") } + private fun cleanUp(cacheDirectory: String) { + val result = if (File(cacheDirectory).deleteRecursively()) + "Cleaned up cache directory" + else + "Failed to clean up cache directory" + logger.info(result) + } + + private fun uninstall() { + // temporarily get package name using Patcher method + // fix: abstract options in patcher + val patcher = app.revanced.patcher.Patcher( + PatcherOptions( + args.inputFile, + "uninstaller-cache", + false + ) + ) + File("uninstaller-cache").deleteRecursively() + + val adb: Adb? = args.deploy?.let { + Adb(File("placeholder_file"), patcher.data.packageMetadata.packageName, args.deploy!!, false) + } + adb?.uninstall() + } + private fun printListOfPatches() { - for (patchBundlePath in args.sArgs?.patchBundles!!) for (patch in JarPatchBundle(patchBundlePath).loadPatches()) { + for (patchBundlePath in args.patchArgs?.patchBundles!!) for (patch in JarPatchBundle(patchBundlePath).loadPatches()) { for (compatiblePackage in patch.compatiblePackages!!) { val packageEntryStr = buildString { // Add package if flag is set - if (args.sArgs?.lArgs?.withPackages == true) { + if (args.patchArgs?.listingArgs?.withPackages == true) { val packageName = compatiblePackage.name.substringAfterLast(".").padStart(10) append(packageName) append("\t") @@ -207,12 +239,12 @@ internal object MainCommand : Runnable { val patchName = patch.patchName.padStart(25) append(patchName) // Add description if flag is set. - if (args.sArgs?.lArgs?.withDescriptions == true) { + if (args.patchArgs?.listingArgs?.withDescriptions == true) { append("\t") append(patch.description) } // Add compatible versions, if flag is set - if (args.sArgs?.lArgs?.withVersions == true) { + if (args.patchArgs?.listingArgs?.withVersions == true) { val compatibleVersions = compatiblePackage.versions.joinToString(separator = ", ") append("\t") append(compatibleVersions) diff --git a/src/main/kotlin/app/revanced/cli/patcher/Patcher.kt b/src/main/kotlin/app/revanced/cli/patcher/Patcher.kt index 10d3a94..514ce6b 100644 --- a/src/main/kotlin/app/revanced/cli/patcher/Patcher.kt +++ b/src/main/kotlin/app/revanced/cli/patcher/Patcher.kt @@ -12,7 +12,7 @@ import java.nio.file.Files internal object Patcher { internal fun start(patcher: app.revanced.patcher.Patcher, output: File) { val inputFile = args.inputFile - val args = args.sArgs?.pArgs!! + val args = args.patchArgs?.patchingArgs!! // merge files like necessary integrations patcher.mergeFiles() diff --git a/src/main/kotlin/app/revanced/cli/signing/Signing.kt b/src/main/kotlin/app/revanced/cli/signing/Signing.kt index 2d44199..75b750c 100644 --- a/src/main/kotlin/app/revanced/cli/signing/Signing.kt +++ b/src/main/kotlin/app/revanced/cli/signing/Signing.kt @@ -1,28 +1,12 @@ package app.revanced.cli.signing -import app.revanced.cli.command.MainCommand.args import app.revanced.cli.command.MainCommand.logger import app.revanced.utils.signing.Signer -import app.revanced.utils.signing.align.ZipAligner import java.io.File object Signing { - fun start(patchedFile: File, outputFile: File, signingOptions: SigningOptions) { - val cacheDirectory = File(args.sArgs?.pArgs?.cacheDirectory) - val signedOutput = cacheDirectory.resolve("${outputFile.nameWithoutExtension}_signed.apk") - val alignedOutput = cacheDirectory.resolve("${outputFile.nameWithoutExtension}_aligned.apk") - - // align the patchedFile and write to alignedFile - ZipAligner.align(patchedFile, alignedOutput) - - // sign the alignedOutput and write to signedOutput - // the reason is, in case the signer fails - // it does not damage the output file - logger.info("Signing ${alignedOutput.name}") - Signer(signingOptions).signApk(alignedOutput, signedOutput) - - // afterwards copy over the file to the output - logger.info("Copying ${signedOutput.name} to ${outputFile.name}") - signedOutput.copyTo(outputFile, true) + fun sign(alignedFile: File, signedOutput: File, signingOptions: SigningOptions) { + logger.info("Signing ${alignedFile.name} to ${signedOutput.name}") + Signer(signingOptions).signApk(alignedFile, signedOutput) } } diff --git a/src/main/kotlin/app/revanced/utils/patcher/Patcher.kt b/src/main/kotlin/app/revanced/utils/patcher/Patcher.kt index 09c7184..cad7ebc 100644 --- a/src/main/kotlin/app/revanced/utils/patcher/Patcher.kt +++ b/src/main/kotlin/app/revanced/utils/patcher/Patcher.kt @@ -15,7 +15,7 @@ fun Patcher.addPatchesFiltered() { val packageName = this.data.packageMetadata.packageName val packageVersion = this.data.packageMetadata.packageVersion - args.sArgs?.patchBundles!!.forEach { bundle -> + args.patchArgs?.patchBundles!!.forEach { bundle -> val includedPatches = mutableListOf>>() JarPatchBundle(bundle).loadPatches().forEach patch@{ patch -> val compatiblePackages = patch.compatiblePackages @@ -23,7 +23,7 @@ fun Patcher.addPatchesFiltered() { val prefix = "Skipping $patchName" - val args = MainCommand.args.sArgs?.pArgs!! + val args = MainCommand.args.patchArgs?.patchingArgs!! if (args.excludedPatches.contains(patchName)) { logger.info("$prefix: Explicitly excluded") @@ -72,7 +72,7 @@ fun Patcher.applyPatchesVerbose() { } fun Patcher.mergeFiles() { - this.addFiles(args.sArgs?.pArgs!!.mergeFiles) { file -> + this.addFiles(args.patchArgs?.patchingArgs!!.mergeFiles) { file -> logger.info("Merging $file") } } diff --git a/src/main/kotlin/app/revanced/utils/signing/Signer.kt b/src/main/kotlin/app/revanced/utils/signing/Signer.kt index 02a91ae..358395a 100644 --- a/src/main/kotlin/app/revanced/utils/signing/Signer.kt +++ b/src/main/kotlin/app/revanced/utils/signing/Signer.kt @@ -56,7 +56,7 @@ internal class Signer( // TODO: keystore should be saved securely val ks = File(signingOptions.keyStoreFilePath) if (!ks.exists()) newKeystore(ks) else { - logger.info("Found existing keystore: ${ks.nameWithoutExtension}") + logger.info("Found existing keystore: ${ks.name}") } val keyStore = KeyStore.getInstance("BKS", "BC")