mirror of
https://github.com/ReVanced/revanced-cli.git
synced 2026-01-11 13:56:18 +00:00
Compare commits
34 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
51fd16409f | ||
|
|
3f5345af6e | ||
|
|
649d9bdb2a | ||
|
|
f4b04698d8 | ||
|
|
240ab18eaf | ||
|
|
096dba2337 | ||
|
|
26780f94e5 | ||
|
|
faa52e2c68 | ||
|
|
e3e74ac0e9 | ||
|
|
de1bdb708c | ||
|
|
9b2b933998 | ||
|
|
fb5a72fdc0 | ||
|
|
86c5992630 | ||
|
|
06d2139ebf | ||
|
|
15ba4f40cd | ||
|
|
2d70037913 | ||
|
|
34108b9229 | ||
|
|
64a323e7e7 | ||
|
|
372470c77b | ||
|
|
3cef245728 | ||
|
|
aa54a2b1a9 | ||
|
|
f8c430be33 | ||
|
|
7692c18282 | ||
|
|
469d0861af | ||
|
|
208c5bc5b0 | ||
|
|
82efd9941f | ||
|
|
48e9043517 | ||
|
|
c3d8fecad0 | ||
|
|
d96eb847d7 | ||
|
|
c8e793efab | ||
|
|
63a8aa315d | ||
|
|
491874bb51 | ||
|
|
cb887ead2c | ||
|
|
cd36e710d6 |
1
.idea/.gitignore
generated
vendored
1
.idea/.gitignore
generated
vendored
@@ -6,3 +6,4 @@
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
||||
/kotlinc.xml
|
||||
|
||||
58
CHANGELOG.md
58
CHANGELOG.md
@@ -1,3 +1,61 @@
|
||||
# [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)
|
||||
|
||||
|
||||
### Reverts
|
||||
|
||||
* feat: remove extra zipalign step ([c3d8fec](https://github.com/revanced/revanced-cli/commit/c3d8fecad0ed9d583b9f1f79bc271e0535d87be2))
|
||||
|
||||
# [2.9.0](https://github.com/revanced/revanced-cli/compare/v2.8.3...v2.9.0) (2022-08-03)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* remove extra zipalign step ([#106](https://github.com/revanced/revanced-cli/issues/106)) ([c8e793e](https://github.com/revanced/revanced-cli/commit/c8e793efab8eed39b2cb564bee80ef6e0b2a7d03))
|
||||
|
||||
## [2.8.3](https://github.com/revanced/revanced-cli/compare/v2.8.2...v2.8.3) (2022-08-03)
|
||||
|
||||
## [2.8.2](https://github.com/revanced/revanced-cli/compare/v2.8.1...v2.8.2) (2022-08-02)
|
||||
|
||||
## [2.8.1](https://github.com/revanced/revanced-cli/compare/v2.8.0...v2.8.1) (2022-08-02)
|
||||
|
||||
|
||||
|
||||
@@ -23,14 +23,14 @@ repositories {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(kotlin("stdlib"))
|
||||
implementation(kotlin("reflect"))
|
||||
|
||||
implementation("app.revanced:revanced-patcher:2.9.0")
|
||||
implementation("app.revanced:revanced-patcher:4.2.3")
|
||||
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 {
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
kotlin.code.style = official
|
||||
version = 2.8.1
|
||||
version = 2.10.0
|
||||
|
||||
@@ -10,7 +10,8 @@ import app.revanced.patcher.PatcherOptions
|
||||
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.implementation.JarPatchBundle
|
||||
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
|
||||
|
||||
@@ -109,12 +113,12 @@ internal object MainCommand : Runnable {
|
||||
@Option(names = ["-p", "--password"], description = ["Overwrite the default password for the signed file"])
|
||||
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"
|
||||
|
||||
@Option(
|
||||
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
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -30,7 +32,7 @@ internal object Patcher {
|
||||
// replace all dex files
|
||||
result.dexFiles.forEach {
|
||||
logger.info("Writing dex file ${it.name}")
|
||||
outputFileSystem.write(it.name, it.dexFileInputStream.readAllBytes())
|
||||
outputFileSystem.write(it.name, it.stream.readAllBytes())
|
||||
}
|
||||
|
||||
if (!args.disableResourcePatching) {
|
||||
|
||||
62
src/main/kotlin/app/revanced/utils/OptionsLoader.kt
Normal file
62
src/main/kotlin/app/revanced/utils/OptionsLoader.kt
Normal 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)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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()
|
||||
}
|
||||
|
||||
@@ -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.implementation.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() {
|
||||
|
||||
Reference in New Issue
Block a user