Compare commits

...

22 Commits

Author SHA1 Message Date
semantic-release-bot
37cc77dfc5 chore(release): 2.10.1 [skip ci]
## [2.10.1](https://github.com/revanced/revanced-cli/compare/v2.10.0...v2.10.1) (2022-09-09)
2022-09-09 20:51:44 +00:00
Sculas
075bf406fd refactor: improve OptionsLoader a lot 2022-09-09 22:50:15 +02:00
Sculas
71c81510f7 build: update patcher dependency 2022-09-09 20:59:10 +02:00
semantic-release-bot
51fd16409f chore(release): 2.10.0 [skip ci]
# [2.10.0](https://github.com/revanced/revanced-cli/compare/v2.9.10...v2.10.0) (2022-09-08)

### Features

* Patch Options CLI implementation ([#132](https://github.com/revanced/revanced-cli/issues/132)) ([3f5345a](3f5345af6e))
2022-09-08 20:36:40 +00:00
Sculas
3f5345af6e feat: Patch Options CLI implementation (#132)
* feat: Patch Options CLI implementation

* fix: remove leftover log message
2022-09-08 22:35:09 +02:00
semantic-release-bot
649d9bdb2a chore(release): 2.9.10 [skip ci]
## [2.9.10](https://github.com/revanced/revanced-cli/compare/v2.9.9...v2.9.10) (2022-09-08)

### Bug Fixes

* don't print same patch multiple times ([f4b0469](f4b04698d8))
2022-09-08 20:21:12 +00:00
Sculas
f4b04698d8 fix: don't print same patch multiple times 2022-09-08 22:19:53 +02:00
semantic-release-bot
240ab18eaf chore(release): 2.9.9 [skip ci]
## [2.9.9](https://github.com/revanced/revanced-cli/compare/v2.9.8...v2.9.9) (2022-09-08)
2022-09-08 15:03:24 +00:00
Sculas
096dba2337 build: update patcher dependency 2022-09-08 17:02:02 +02:00
semantic-release-bot
26780f94e5 chore(release): 2.9.8 [skip ci]
## [2.9.8](https://github.com/revanced/revanced-cli/compare/v2.9.7...v2.9.8) (2022-09-08)

### Bug Fixes

* broken deprecation message ([e3e74ac](e3e74ac0e9))
2022-09-08 11:51:01 +00:00
Sculas
faa52e2c68 Merge remote-tracking branch 'origin/main' into main 2022-09-08 13:49:18 +02:00
Sculas
e3e74ac0e9 fix: broken deprecation message 2022-09-08 13:49:03 +02:00
Sculas
de1bdb708c build: update patcher 2022-09-08 13:46:23 +02:00
semantic-release-bot
9b2b933998 chore(release): 2.9.7 [skip ci]
## [2.9.7](https://github.com/revanced/revanced-cli/compare/v2.9.6...v2.9.7) (2022-09-08)
2022-09-08 10:55:29 +00:00
Sculas
fb5a72fdc0 build: remove useless stdlib 2022-09-08 12:53:38 +02:00
Sculas
86c5992630 build: update patcher 2022-09-08 12:53:08 +02:00
Sculas
06d2139ebf refactor: handle deprecation & cleanup 2022-09-08 12:52:00 +02:00
Sculas
15ba4f40cd chore: ignore kotlinc 2022-09-08 12:45:14 +02:00
semantic-release-bot
2d70037913 chore(release): 2.9.6 [skip ci]
## [2.9.6](https://github.com/revanced/revanced-cli/compare/v2.9.5...v2.9.6) (2022-09-07)
2022-09-07 21:17:46 +00:00
Canny
34108b9229 build: bump patcher dependency version (#126) 2022-09-07 23:16:12 +02:00
semantic-release-bot
64a323e7e7 chore(release): 2.9.5 [skip ci]
## [2.9.5](https://github.com/revanced/revanced-cli/compare/v2.9.4...v2.9.5) (2022-09-01)

### Bug Fixes

* mount bind revanced.apk from magisk's mirror ([372470c](372470c77b))
2022-09-01 00:41:46 +00:00
Nguyen Hoang The Vi
372470c77b fix: mount bind revanced.apk from magisk's mirror
Some banking apps detect the mountpoint of youtube base apk to determine device is rooted. So mount bind from magisk's mirror to trigger magisk unmount and let it hidden along with magisk hiding.
2022-09-01 02:40:20 +02:00
9 changed files with 186 additions and 59 deletions

1
.idea/.gitignore generated vendored
View File

@@ -6,3 +6,4 @@
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml
/kotlinc.xml

View File

@@ -1,3 +1,39 @@
## [2.10.1](https://github.com/revanced/revanced-cli/compare/v2.10.0...v2.10.1) (2022-09-09)
# [2.10.0](https://github.com/revanced/revanced-cli/compare/v2.9.10...v2.10.0) (2022-09-08)
### Features
* Patch Options CLI implementation ([#132](https://github.com/revanced/revanced-cli/issues/132)) ([3f5345a](https://github.com/revanced/revanced-cli/commit/3f5345af6e45bfb6c91d52fc089ab18d81fdc998))
## [2.9.10](https://github.com/revanced/revanced-cli/compare/v2.9.9...v2.9.10) (2022-09-08)
### Bug Fixes
* don't print same patch multiple times ([f4b0469](https://github.com/revanced/revanced-cli/commit/f4b04698d8c1717824e86f91da5e01c5021612da))
## [2.9.9](https://github.com/revanced/revanced-cli/compare/v2.9.8...v2.9.9) (2022-09-08)
## [2.9.8](https://github.com/revanced/revanced-cli/compare/v2.9.7...v2.9.8) (2022-09-08)
### Bug Fixes
* broken deprecation message ([e3e74ac](https://github.com/revanced/revanced-cli/commit/e3e74ac0e9a844f9d717a499bca09e575dd90435))
## [2.9.7](https://github.com/revanced/revanced-cli/compare/v2.9.6...v2.9.7) (2022-09-08)
## [2.9.6](https://github.com/revanced/revanced-cli/compare/v2.9.5...v2.9.6) (2022-09-07)
## [2.9.5](https://github.com/revanced/revanced-cli/compare/v2.9.4...v2.9.5) (2022-09-01)
### Bug Fixes
* mount bind revanced.apk from magisk's mirror ([372470c](https://github.com/revanced/revanced-cli/commit/372470c77b82e8601ca523e87a2cfd44f79d0e31))
## [2.9.4](https://github.com/revanced/revanced-cli/compare/v2.9.3...v2.9.4) (2022-08-31)
## [2.9.3](https://github.com/revanced/revanced-cli/compare/v2.9.2...v2.9.3) (2022-08-14)

View File

@@ -23,14 +23,14 @@ repositories {
}
dependencies {
implementation(kotlin("stdlib"))
implementation(kotlin("reflect"))
implementation("app.revanced:revanced-patcher:3.4.0")
implementation("app.revanced:revanced-patcher:4.4.0")
implementation("info.picocli:picocli:4.6.3")
implementation("com.android.tools.build:apksig:7.2.1")
implementation("com.github.revanced:jadb:master-SNAPSHOT") // updated fork
implementation("org.bouncycastle:bcpkix-jdk15on:1.70")
implementation("cc.ekblad:4koma:1.1.0")
}
tasks {

View File

@@ -1,2 +1,2 @@
kotlin.code.style = official
version = 2.9.4
version = 2.10.1

View File

@@ -11,6 +11,7 @@ import app.revanced.patcher.extensions.PatchExtensions.compatiblePackages
import app.revanced.patcher.extensions.PatchExtensions.description
import app.revanced.patcher.extensions.PatchExtensions.patchName
import app.revanced.patcher.util.patch.impl.JarPatchBundle
import app.revanced.utils.OptionsLoader
import app.revanced.utils.adb.Adb
import picocli.CommandLine.*
import java.io.File
@@ -51,6 +52,9 @@ internal object MainCommand : Runnable {
@Option(names = ["-b", "--bundles"], description = ["One or more bundles of patches"], required = true)
var patchBundles = arrayOf<String>()
@Option(names = ["--options"], description = ["Configuration file for all patch options"])
var options: File = File("options.toml")
@ArgGroup(exclusive = false)
var listingArgs: ListingArgs? = null
@@ -123,20 +127,17 @@ internal object MainCommand : Runnable {
}
override fun run() {
if (args.patchArgs?.listingArgs?.listOnly == true) {
printListOfPatches()
return
}
if (args.uninstall) {
uninstall()
return
}
if (args.patchArgs?.listingArgs?.listOnly == true) return printListOfPatches()
if (args.uninstall) return uninstall()
val pArgs = this.args.patchArgs?.patchingArgs ?: return
val outputFile = File(pArgs.outputPath) // the file to write to
// the file to write to
val outputFile = File(pArgs.outputPath)
val allPatches = args.patchArgs!!.patchBundles.flatMap { bundle ->
JarPatchBundle(bundle).loadPatches()
}
OptionsLoader.init(args.patchArgs!!.options, allPatches)
val patcher = app.revanced.patcher.Patcher(
PatcherOptions(
@@ -157,7 +158,7 @@ internal object MainCommand : Runnable {
val patchedFile = File(pArgs.cacheDirectory).resolve("${outputFile.nameWithoutExtension}_raw.apk")
// start the patcher
Patcher.start(patcher, patchedFile)
Patcher.start(patcher, patchedFile, allPatches)
val cacheDirectory = File(pArgs.cacheDirectory)
@@ -227,7 +228,9 @@ internal object MainCommand : Runnable {
}
private fun printListOfPatches() {
val logged = mutableListOf<String>()
for (patchBundlePath in args.patchArgs?.patchBundles!!) for (patch in JarPatchBundle(patchBundlePath).loadPatches()) {
if (patch.patchName in logged) continue
for (compatiblePackage in patch.compatiblePackages!!) {
val packageEntryStr = buildString {
// Add package if flag is set
@@ -250,8 +253,9 @@ internal object MainCommand : Runnable {
append("\t")
append(compatibleVersions)
}
}
logged.add(patch.patchName)
logger.info(packageEntryStr)
}
}

View File

@@ -2,6 +2,8 @@ package app.revanced.cli.patcher
import app.revanced.cli.command.MainCommand.args
import app.revanced.cli.command.MainCommand.logger
import app.revanced.patcher.data.Data
import app.revanced.patcher.patch.Patch
import app.revanced.utils.filesystem.ZipFileSystemUtils
import app.revanced.utils.patcher.addPatchesFiltered
import app.revanced.utils.patcher.applyPatchesVerbose
@@ -10,14 +12,14 @@ import java.io.File
import java.nio.file.Files
internal object Patcher {
internal fun start(patcher: app.revanced.patcher.Patcher, output: File) {
internal fun start(patcher: app.revanced.patcher.Patcher, output: File, allPatches: List<Class<out Patch<Data>>>) {
val inputFile = args.inputFile
val args = args.patchArgs?.patchingArgs!!
// merge files like necessary integrations
patcher.mergeFiles()
// add patches, but filter incompatible or excluded patches
patcher.addPatchesFiltered()
patcher.addPatchesFiltered(allPatches)
// apply patches
patcher.applyPatchesVerbose()

View File

@@ -0,0 +1,77 @@
package app.revanced.utils
import app.revanced.cli.command.MainCommand.logger
import app.revanced.patcher.Patcher
import app.revanced.patcher.data.Data
import app.revanced.patcher.extensions.PatchExtensions.options
import app.revanced.patcher.extensions.PatchExtensions.patchName
import app.revanced.patcher.patch.Patch
import cc.ekblad.toml.encodeToString
import cc.ekblad.toml.model.TomlValue
import cc.ekblad.toml.serialization.from
import cc.ekblad.toml.tomlMapper
import java.io.File
private typealias PatchList = List<Class<out Patch<Data>>>
private typealias OptionsMap = MutableMap<String, MutableMap<String, Any>>
object OptionsLoader {
@JvmStatic
private val mapper = tomlMapper {}
@JvmStatic
fun init(file: File, patches: PatchList) {
if (!file.exists()) file.createNewFile()
val map = mapper.decodeWithDefaults(generateDefaults(patches), TomlValue.from(file.toPath()))
readAndSet(map, patches)
save(map, file)
}
private fun readAndSet(map: OptionsMap, patches: PatchList) {
for ((patchName, options) in map) {
val patch = patches.find { it.patchName == patchName } ?: continue
val patchOptions = patch.options ?: continue
for ((key, value) in options) {
if (value == "null") { // backwards compatibility, subject to removal
options.remove(key)
continue
}
try {
patchOptions[key] = value
} catch (e: Exception) {
logger.error("Error while setting option $key for patch $patchName: ${e.message}")
e.printStackTrace()
}
}
}
}
private fun save(map: OptionsMap, file: File) {
val toml = mapper.encodeToString(map)
file.writeText(
"""
# A list of options for each patch.
# This file does not contain all options by default.
# Run the CLI with the "--list --with-options" flags to see all available options.
# You can also run the CLI with the aforementioned flags and a patch name to see all available options for that patch.
# To set an option, add a line with the format "option = value".
# To remove or reset an option to its default value, delete the line.
# To reset all options to their default values, delete this file.
#
# This file was generated by ReVanced Patcher version ${Patcher.version}.
""".trimIndent() + "\n\n$toml"
)
}
private fun generateDefaults(patches: PatchList) = buildMap {
for (patch in patches) {
val options = patch.options ?: continue
if (!options.iterator().hasNext()) continue
put(patch.patchName, buildMap {
for (option in options) {
put(option.key, option.value ?: continue)
}
} as MutableMap)
}
} as MutableMap
}

View File

@@ -44,12 +44,14 @@ internal object Constants {
internal val CONTENT_MOUNT_SCRIPT =
"""
#!/system/bin/sh
MAGISKTMP="${'$'}(magisk --path)" || MAGISKTMP=/sbin
MIRROR="${'$'}MAGISKTMP/.magisk/mirror"
while [ "${'$'}(getprop sys.boot_completed | tr -d '\r')" != "1" ]; do sleep 1; done
base_path="$PATH_REVANCED_APP"
stock_path=${'$'}( pm path $PLACEHOLDER | grep base | sed 's/package://g' )
chcon u:object_r:apk_data_file:s0 ${'$'}base_path
mount -o bind ${'$'}base_path ${'$'}stock_path
mount -o bind ${'$'}MIRROR${'$'}base_path ${'$'}stock_path
""".trimIndent()
}

View File

@@ -6,58 +6,63 @@ import app.revanced.cli.command.MainCommand.logger
import app.revanced.patcher.Patcher
import app.revanced.patcher.data.Data
import app.revanced.patcher.extensions.PatchExtensions.compatiblePackages
import app.revanced.patcher.extensions.PatchExtensions.deprecated
import app.revanced.patcher.extensions.PatchExtensions.include
import app.revanced.patcher.extensions.PatchExtensions.patchName
import app.revanced.patcher.patch.Patch
import app.revanced.patcher.util.patch.impl.JarPatchBundle
fun Patcher.addPatchesFiltered() {
fun Patcher.addPatchesFiltered(allPatches: List<Class<out Patch<Data>>>) {
val packageName = this.data.packageMetadata.packageName
val packageVersion = this.data.packageMetadata.packageVersion
args.patchArgs?.patchBundles!!.forEach { bundle ->
val includedPatches = mutableListOf<Class<out Patch<Data>>>()
JarPatchBundle(bundle).loadPatches().forEach patch@{ patch ->
val compatiblePackages = patch.compatiblePackages
val patchName = patch.patchName
val includedPatches = mutableListOf<Class<out Patch<Data>>>()
allPatches.forEach patchLoop@{ patch ->
val compatiblePackages = patch.compatiblePackages
val patchName = patch.patchName
val prefix = "Skipping $patchName"
val prefix = "Skipping $patchName, reason"
val args = MainCommand.args.patchArgs?.patchingArgs!!
val args = MainCommand.args.patchArgs?.patchingArgs!!
if (args.excludedPatches.contains(patchName)) {
logger.info("$prefix: Explicitly excluded")
return@patch
} else if ((!patch.include || args.defaultExclude) && !args.includedPatches.contains(patchName)) {
logger.info("$prefix: Not explicitly included")
return@patch
}
if (compatiblePackages == null) logger.warn("$prefix: Missing compatibility annotation. Continuing.")
else {
if (!compatiblePackages.any { it.name == packageName }) {
logger.warn("$prefix: Incompatible with $packageName. This patch is only compatible with ${
compatiblePackages.joinToString(
", "
) { it.name }
}")
return@patch
}
if (!(args.experimental || compatiblePackages.any { it.versions.isEmpty() || it.versions.any { version -> version == packageVersion } })) {
val compatibleWith = compatiblePackages.map { _package ->
"${_package.name}: ${_package.versions.joinToString(", ")}"
}.joinToString(";")
logger.warn("$prefix: Incompatible with version $packageVersion. This patch is only compatible with version $compatibleWith")
return@patch
}
}
logger.trace("Adding $patchName")
includedPatches.add(patch)
if (args.excludedPatches.contains(patchName)) {
logger.info("$prefix: manually excluded")
return@patchLoop
} else if ((!patch.include || args.defaultExclude) && !args.includedPatches.contains(patchName)) {
logger.info("$prefix: excluded by default")
return@patchLoop
}
this.addPatches(includedPatches)
patch.deprecated?.let { (reason, replacement) ->
logger.warn("$prefix: deprecated: $reason")
if (replacement != null) logger.warn("Either use ${replacement.java.patchName} instead or include it manually")
return@patchLoop
}
if (compatiblePackages == null) logger.warn("$prefix: Missing compatibility annotation. Continuing.")
else {
if (!compatiblePackages.any { it.name == packageName }) {
logger.warn("$prefix: incompatible with $packageName. This patch is only compatible with ${
compatiblePackages.joinToString(
", "
) { it.name }
}")
return@patchLoop
}
if (!(args.experimental || compatiblePackages.any { it.versions.isEmpty() || it.versions.any { version -> version == packageVersion } })) {
val compatibleWith = compatiblePackages.joinToString(";") { _package ->
"${_package.name}: ${_package.versions.joinToString(", ")}"
}
logger.warn("$prefix: incompatible with version $packageVersion. This patch is only compatible with version $compatibleWith")
return@patchLoop
}
}
logger.trace("Adding $patchName")
includedPatches.add(patch)
}
this.addPatches(includedPatches)
}
fun Patcher.applyPatchesVerbose() {