Compare commits

...

26 Commits

Author SHA1 Message Date
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
semantic-release-bot
3cef245728 chore(release): 2.9.4 [skip ci]
## [2.9.4](https://github.com/revanced/revanced-cli/compare/v2.9.3...v2.9.4) (2022-08-31)
2022-08-31 18:40:54 +00:00
oSumAtrIX
aa54a2b1a9 build: bump patcher dependency version
Signed-off-by: oSumAtrIX <johan.melkonyan1@web.de>
2022-08-31 20:36:57 +02:00
semantic-release-bot
f8c430be33 chore(release): 2.9.3 [skip ci]
## [2.9.3](https://github.com/revanced/revanced-cli/compare/v2.9.2...v2.9.3) (2022-08-14)
2022-08-14 15:34:54 +00:00
oSumAtrIX
7692c18282 build: bump patcher dependency version 2022-08-14 17:33:14 +02:00
semantic-release-bot
469d0861af chore(release): 2.9.2 [skip ci]
## [2.9.2](https://github.com/revanced/revanced-cli/compare/v2.9.1...v2.9.2) (2022-08-07)
2022-08-07 20:42:09 +00:00
oSumAtrIX
208c5bc5b0 build: bump patcher dependency version 2022-08-07 21:55:15 +02:00
Ankit Majumder
82efd9941f refactor: spelling mistake (#114) 2022-08-06 09:54:37 +02:00
9 changed files with 179 additions and 63 deletions

1
.idea/.gitignore generated vendored
View File

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

View File

@@ -1,3 +1,43 @@
# [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)
## [2.9.2](https://github.com/revanced/revanced-cli/compare/v2.9.1...v2.9.2) (2022-08-07)
## [2.9.1](https://github.com/revanced/revanced-cli/compare/v2.9.0...v2.9.1) (2022-08-04) ## [2.9.1](https://github.com/revanced/revanced-cli/compare/v2.9.0...v2.9.1) (2022-08-04)

View File

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

View File

@@ -1,2 +1,2 @@
kotlin.code.style = official kotlin.code.style = official
version = 2.9.1 version = 2.10.0

View File

@@ -10,7 +10,8 @@ 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.description
import app.revanced.patcher.extensions.PatchExtensions.patchName import app.revanced.patcher.extensions.PatchExtensions.patchName
import app.revanced.patcher.util.patch.implementation.JarPatchBundle import app.revanced.patcher.util.patch.impl.JarPatchBundle
import app.revanced.utils.OptionsLoader
import app.revanced.utils.adb.Adb import app.revanced.utils.adb.Adb
import picocli.CommandLine.* import picocli.CommandLine.*
import java.io.File 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) @Option(names = ["-b", "--bundles"], description = ["One or more bundles of patches"], required = true)
var patchBundles = arrayOf<String>() var patchBundles = arrayOf<String>()
@Option(names = ["--options"], description = ["Configuration file for all patch options"])
var options: File = File("options.toml")
@ArgGroup(exclusive = false) @ArgGroup(exclusive = false)
var listingArgs: ListingArgs? = null var listingArgs: ListingArgs? = null
@@ -109,12 +113,12 @@ internal object MainCommand : Runnable {
@Option(names = ["-p", "--password"], description = ["Overwrite the default password for the signed file"]) @Option(names = ["-p", "--password"], description = ["Overwrite the default password for the signed file"])
var password = "ReVanced" var password = "ReVanced"
@Option(names = ["-t", "--temp-dir"], description = ["Temporal resource cache directory"]) @Option(names = ["-t", "--temp-dir"], description = ["Temporary resource cache directory"])
var cacheDirectory = "revanced-cache" var cacheDirectory = "revanced-cache"
@Option( @Option(
names = ["-c", "--clean"], names = ["-c", "--clean"],
description = ["Clean the temporal resource cache directory. This will be done anyways when running the patcher"] description = ["Clean the temporary resource cache directory. This will be done anyways when running the patcher"]
) )
var clean: Boolean = false var clean: Boolean = false
@@ -123,20 +127,17 @@ internal object MainCommand : Runnable {
} }
override fun run() { override fun run() {
if (args.patchArgs?.listingArgs?.listOnly == true) { if (args.patchArgs?.listingArgs?.listOnly == true) return printListOfPatches()
printListOfPatches() if (args.uninstall) return uninstall()
return
}
if (args.uninstall) {
uninstall()
return
}
val pArgs = this.args.patchArgs?.patchingArgs ?: return val pArgs = this.args.patchArgs?.patchingArgs ?: return
val outputFile = File(pArgs.outputPath) // the file to write to
// the file to write to val allPatches = args.patchArgs!!.patchBundles.flatMap { bundle ->
val outputFile = File(pArgs.outputPath) JarPatchBundle(bundle).loadPatches()
}
OptionsLoader.init(args.patchArgs!!.options, allPatches)
val patcher = app.revanced.patcher.Patcher( val patcher = app.revanced.patcher.Patcher(
PatcherOptions( PatcherOptions(
@@ -157,7 +158,7 @@ internal object MainCommand : Runnable {
val patchedFile = File(pArgs.cacheDirectory).resolve("${outputFile.nameWithoutExtension}_raw.apk") val patchedFile = File(pArgs.cacheDirectory).resolve("${outputFile.nameWithoutExtension}_raw.apk")
// start the patcher // start the patcher
Patcher.start(patcher, patchedFile) Patcher.start(patcher, patchedFile, allPatches)
val cacheDirectory = File(pArgs.cacheDirectory) val cacheDirectory = File(pArgs.cacheDirectory)
@@ -227,7 +228,9 @@ internal object MainCommand : Runnable {
} }
private fun printListOfPatches() { private fun printListOfPatches() {
val logged = mutableListOf<String>()
for (patchBundlePath in args.patchArgs?.patchBundles!!) for (patch in JarPatchBundle(patchBundlePath).loadPatches()) { for (patchBundlePath in args.patchArgs?.patchBundles!!) for (patch in JarPatchBundle(patchBundlePath).loadPatches()) {
if (patch.patchName in logged) continue
for (compatiblePackage in patch.compatiblePackages!!) { for (compatiblePackage in patch.compatiblePackages!!) {
val packageEntryStr = buildString { val packageEntryStr = buildString {
// Add package if flag is set // Add package if flag is set
@@ -250,8 +253,9 @@ internal object MainCommand : Runnable {
append("\t") append("\t")
append(compatibleVersions) append(compatibleVersions)
} }
} }
logged.add(patch.patchName)
logger.info(packageEntryStr) 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.args
import app.revanced.cli.command.MainCommand.logger 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.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
@@ -10,14 +12,14 @@ import java.io.File
import java.nio.file.Files 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, allPatches: List<Class<out Patch<Data>>>) {
val inputFile = args.inputFile val inputFile = args.inputFile
val args = args.patchArgs?.patchingArgs!! val args = args.patchArgs?.patchingArgs!!
// 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() patcher.addPatchesFiltered(allPatches)
// apply patches // apply patches
patcher.applyPatchesVerbose() patcher.applyPatchesVerbose()
@@ -30,7 +32,7 @@ internal object Patcher {
// replace all dex files // replace all dex files
result.dexFiles.forEach { result.dexFiles.forEach {
logger.info("Writing dex file ${it.name}") logger.info("Writing dex file ${it.name}")
outputFileSystem.write(it.name, it.dexFileInputStream.readAllBytes()) outputFileSystem.write(it.name, it.stream.readAllBytes())
} }
if (!args.disableResourcePatching) { if (!args.disableResourcePatching) {

View File

@@ -0,0 +1,62 @@
package app.revanced.utils
import app.revanced.cli.command.MainCommand.logger
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.encodeTo
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 = Map<String, Map<String, Any>>
private const val NULL = "null"
object OptionsLoader {
@JvmStatic
private val mapper = tomlMapper {}
@JvmStatic
fun init(file: File, patches: PatchList) {
if (!file.exists()) file.createNewFile()
val path = file.toPath()
val map = mapper.decodeWithDefaults(
generateDefaults(patches),
TomlValue.from(path)
).also { mapper.encodeTo(path, it) }
readAndSet(map, patches)
}
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) {
try {
patchOptions[key] = value.let {
if (it == NULL) null else it
}
} catch (e: Exception) {
logger.warn("Error while setting option $key for patch $patchName: ${e.message}")
e.printStackTrace()
}
}
}
}
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 ?: NULL)
}
})
}
}
}

View File

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

View File

@@ -6,58 +6,63 @@ import app.revanced.cli.command.MainCommand.logger
import app.revanced.patcher.Patcher import app.revanced.patcher.Patcher
import app.revanced.patcher.data.Data import app.revanced.patcher.data.Data
import app.revanced.patcher.extensions.PatchExtensions.compatiblePackages 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.include
import app.revanced.patcher.extensions.PatchExtensions.patchName import app.revanced.patcher.extensions.PatchExtensions.patchName
import app.revanced.patcher.patch.Patch import app.revanced.patcher.patch.Patch
import app.revanced.patcher.util.patch.implementation.JarPatchBundle
fun Patcher.addPatchesFiltered() { fun Patcher.addPatchesFiltered(allPatches: List<Class<out Patch<Data>>>) {
val packageName = this.data.packageMetadata.packageName val packageName = this.data.packageMetadata.packageName
val packageVersion = this.data.packageMetadata.packageVersion val packageVersion = this.data.packageMetadata.packageVersion
args.patchArgs?.patchBundles!!.forEach { bundle -> val includedPatches = mutableListOf<Class<out Patch<Data>>>()
val includedPatches = mutableListOf<Class<out Patch<Data>>>() allPatches.forEach patchLoop@{ patch ->
JarPatchBundle(bundle).loadPatches().forEach patch@{ patch -> val compatiblePackages = patch.compatiblePackages
val compatiblePackages = patch.compatiblePackages val patchName = patch.patchName
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)) { if (args.excludedPatches.contains(patchName)) {
logger.info("$prefix: Explicitly excluded") logger.info("$prefix: manually excluded")
return@patch return@patchLoop
} else if ((!patch.include || args.defaultExclude) && !args.includedPatches.contains(patchName)) { } else if ((!patch.include || args.defaultExclude) && !args.includedPatches.contains(patchName)) {
logger.info("$prefix: Not explicitly included") logger.info("$prefix: excluded by default")
return@patch 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@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)
} }
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() { fun Patcher.applyPatchesVerbose() {