Compare commits

..

28 Commits

Author SHA1 Message Date
semantic-release-bot
4f1982e3ad chore(release): 4.4.1-dev.1 [skip ci]
## [4.4.1-dev.1](https://github.com/ReVanced/revanced-cli/compare/v4.4.0...v4.4.1-dev.1) (2024-02-21)
2024-02-21 03:58:27 +00:00
oSumAtrIX
f1d7d0dc62 build: Sign release artifacts 2024-02-21 04:52:53 +01:00
oSumAtrIX
40c90f5c1b build: Bump Gradle 2024-02-15 02:34:10 +01:00
oSumAtrIX
30b46bcb0f build(Needs bump): Bump dependencies 2024-02-15 02:34:10 +01:00
oSumAtrIX
b6f63c7d9d docs: Fix blockquote highlights not rendering
As of 14. Nov 2023 GitHub has decided to disable nested highlighted blockquotes: https://github.com/orgs/community/discussions/16925.
2024-02-04 18:35:41 +01:00
oSumAtrIX
b5bd988a1d ci: Use latest Node.js LTS version to fix builds 2024-01-26 22:52:38 +01:00
oSumAtrIX
95c998b0a6 ci: Add dependabot 2024-01-26 01:45:45 +01:00
oSumAtrIX
24a8f6575c build: Bump dependencies 2024-01-26 01:42:04 +01:00
oSumAtrIX
55f0c01e5a docs: Fix grammatic error 2024-01-12 11:45:39 +01:00
oSumAtrIX
ee1e96b2d5 docs: Simplify patch command 2024-01-12 09:42:05 +01:00
oSumAtrIX
0fc1d571e8 docs: Add JRE links to obtain 2024-01-11 23:37:20 +01:00
oSumAtrIX
4933fe0314 build: Bump dependencies 2024-01-10 09:33:54 +01:00
oSumAtrIX
2e2ddac273 chore: Add local.properties to .gitignore 2024-01-10 09:33:54 +01:00
semantic-release-bot
3c264572a2 chore(release): 4.4.0 [skip ci]
# [4.4.0](https://github.com/ReVanced/revanced-cli/compare/v4.3.0...v4.4.0) (2023-12-28)

### Bug Fixes

* Add missing punctuation in command description ([8210351](821035107d))

### Features

* Log saved patched APK file path ([16109bd](16109bd8bc))
2023-12-28 21:34:45 +00:00
oSumAtrIX
63e8585652 chore: Merge branch dev to main (#305) 2023-12-28 22:33:09 +01:00
oSumAtrIX
8f59d94dc7 docs: Add building instructions 2023-12-21 15:10:02 +01:00
semantic-release-bot
3bcee04a7d chore(release): 4.4.0-dev.2 [skip ci]
# [4.4.0-dev.2](https://github.com/ReVanced/revanced-cli/compare/v4.4.0-dev.1...v4.4.0-dev.2) (2023-12-18)

### Bug Fixes

* Add missing punctuation in command description ([8210351](821035107d))
2023-12-18 18:47:08 +00:00
oSumAtrIX
821035107d fix: Add missing punctuation in command description 2023-12-18 19:45:35 +01:00
oSumAtrIX
8becebaa42 docs: Fix spelling mistakes 2023-12-12 13:43:36 +01:00
oSumAtrIX
fe563fff93 build: Simplify enabling local build cache 2023-12-10 21:57:12 +01:00
semantic-release-bot
2d17459fa3 chore(release): 4.4.0-dev.1 [skip ci]
# [4.4.0-dev.1](https://github.com/ReVanced/revanced-cli/compare/v4.3.0...v4.4.0-dev.1) (2023-12-01)

### Features

* Log saved patched APK file path ([16109bd](16109bd8bc))
2023-12-01 22:54:26 +00:00
oSumAtrIX
16109bd8bc feat: Log saved patched APK file path 2023-12-01 23:53:17 +01:00
semantic-release-bot
09bc652317 chore(release): 4.3.0 [skip ci]
# [4.3.0](https://github.com/ReVanced/revanced-cli/compare/v4.2.0...v4.3.0) (2023-12-01)

### Features

* Add `list-versions` command ([a974b8e](a974b8ea80))
2023-12-01 22:29:44 +00:00
oSumAtrIX
1d051365f3 chore: Merge branch dev to main (#304) 2023-12-01 01:24:43 +01:00
oSumAtrIX
ab7d9d8e1e build: Bump dependencies 2023-12-01 01:22:06 +01:00
oSumAtrIX
5e089ea9af docs: Update to latest GitHub Markdown syntax changes 2023-12-01 01:12:26 +01:00
semantic-release-bot
06c6a97915 chore(release): 4.3.0-dev.1 [skip ci]
# [4.3.0-dev.1](https://github.com/ReVanced/revanced-cli/compare/v4.2.0...v4.3.0-dev.1) (2023-11-27)

### Features

* Add `list-versions` command ([a974b8e](a974b8ea80))
2023-11-27 22:12:44 +00:00
oSumAtrIX
a974b8ea80 feat: Add list-versions command 2023-11-27 23:11:23 +01:00
21 changed files with 904 additions and 4930 deletions

3
.editorconfig Normal file
View File

@@ -0,0 +1,3 @@
[*.{kt,kts}]
ktlint_code_style = intellij_idea
ktlint_standard_no-wildcard-imports = disabled

22
.github/dependabot.yml vendored Normal file
View File

@@ -0,0 +1,22 @@
version: 2
updates:
- package-ecosystem: github-actions
labels: []
directory: /
target-branch: dev
schedule:
interval: monthly
- package-ecosystem: npm
labels: []
directory: /
target-branch: dev
schedule:
interval: monthly
- package-ecosystem: gradle
labels: []
directory: /
target-branch: dev
schedule:
interval: monthly

View File

@@ -24,25 +24,30 @@ jobs:
persist-credentials: false persist-credentials: false
fetch-depth: 0 fetch-depth: 0
- name: Cache Node modules
uses: actions/cache@v3
with:
path: |
node_modules
key: npm-${{ hashFiles('package-lock.json') }}
- name: Cache Gradle - name: Cache Gradle
uses: burrunan/gradle-cache-action@v1 uses: burrunan/gradle-cache-action@v1
- name: Build - name: Build
env: env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# Cleaning is necessary to avoid uploading two identical artifacts with different versions run: ./gradlew build clean
run: ./gradlew clean --no-daemon
- name: Setup semantic-release - name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "lts/*"
cache: 'npm'
- name: Install dependencies
run: npm install run: npm install
- name: Import GPG key
uses: crazy-max/ghaction-import-gpg@v6
with:
gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }}
passphrase: ${{ secrets.GPG_PASSPHRASE }}
fingerprint: ${{ env.GPG_FINGERPRINT }}
- name: Release - name: Release
env: env:
GITHUB_TOKEN: ${{ secrets.REPOSITORY_PUSH_ACCESS }} GITHUB_TOKEN: ${{ secrets.REPOSITORY_PUSH_ACCESS }}

3
.gitignore vendored
View File

@@ -120,3 +120,6 @@ node_modules/
# ReVanced CLI # ReVanced CLI
revanced-cache/ revanced-cache/
options.toml options.toml
# Generated by an Android project (such as ReVanced Integrations)
local.properties

View File

@@ -31,7 +31,7 @@
{ {
"assets": [ "assets": [
{ {
"path": "build/libs/*all.jar" "path": "build/libs/*-all*"
} }
], ],
successComment: false successComment: false

View File

@@ -1,3 +1,45 @@
## [4.4.1-dev.1](https://github.com/ReVanced/revanced-cli/compare/v4.4.0...v4.4.1-dev.1) (2024-02-21)
# [4.4.0](https://github.com/ReVanced/revanced-cli/compare/v4.3.0...v4.4.0) (2023-12-28)
### Bug Fixes
* Add missing punctuation in command description ([8210351](https://github.com/ReVanced/revanced-cli/commit/821035107d7264580275f395e9e3fcef91394afd))
### Features
* Log saved patched APK file path ([16109bd](https://github.com/ReVanced/revanced-cli/commit/16109bd8bc6236debf71cbc8db78fe452b2ed00d))
# [4.4.0-dev.2](https://github.com/ReVanced/revanced-cli/compare/v4.4.0-dev.1...v4.4.0-dev.2) (2023-12-18)
### Bug Fixes
* Add missing punctuation in command description ([8210351](https://github.com/ReVanced/revanced-cli/commit/821035107d7264580275f395e9e3fcef91394afd))
# [4.4.0-dev.1](https://github.com/ReVanced/revanced-cli/compare/v4.3.0...v4.4.0-dev.1) (2023-12-01)
### Features
* Log saved patched APK file path ([16109bd](https://github.com/ReVanced/revanced-cli/commit/16109bd8bc6236debf71cbc8db78fe452b2ed00d))
# [4.3.0](https://github.com/ReVanced/revanced-cli/compare/v4.2.0...v4.3.0) (2023-12-01)
### Features
* Add `list-versions` command ([a974b8e](https://github.com/ReVanced/revanced-cli/commit/a974b8ea80acd85f8dc472a3f93b8fd7bea08007))
# [4.3.0-dev.1](https://github.com/ReVanced/revanced-cli/compare/v4.2.0...v4.3.0-dev.1) (2023-11-27)
### Features
* Add `list-versions` command ([a974b8e](https://github.com/ReVanced/revanced-cli/commit/a974b8ea80acd85f8dc472a3f93b8fd7bea08007))
# [4.2.0](https://github.com/ReVanced/revanced-cli/compare/v4.1.0...v4.2.0) (2023-11-26) # [4.2.0](https://github.com/ReVanced/revanced-cli/compare/v4.1.0...v4.2.0) (2023-11-26)

View File

@@ -1,15 +1,29 @@
plugins { plugins {
kotlin("jvm") version "1.9.10" alias(libs.plugins.kotlin)
alias(libs.plugins.shadow) alias(libs.plugins.shadow)
application
`maven-publish`
signing
} }
group = "app.revanced" group = "app.revanced"
application {
mainClass = "app.revanced.cli.command.MainCommandKt"
}
repositories { repositories {
mavenCentral() mavenCentral()
mavenLocal() mavenLocal()
google() google()
maven { url = uri("https://jitpack.io") } maven {
// A repository must be speficied for some reason. "registry" is a dummy.
url = uri("https://maven.pkg.github.com/revanced/registry")
credentials {
username = project.findProperty("gpr.user") as String? ?: System.getenv("GITHUB_ACTOR")
password = project.findProperty("gpr.key") as String? ?: System.getenv("GITHUB_TOKEN")
}
}
} }
dependencies { dependencies {
@@ -36,9 +50,6 @@ tasks {
} }
shadowJar { shadowJar {
manifest {
attributes("Main-Class" to "app.revanced.cli.command.MainCommandKt")
}
minimize { minimize {
exclude(dependency("org.jetbrains.kotlin:.*")) exclude(dependency("org.jetbrains.kotlin:.*"))
exclude(dependency("org.bouncycastle:.*")) exclude(dependency("org.bouncycastle:.*"))
@@ -46,25 +57,29 @@ tasks {
} }
} }
build { publish {
dependsOn(shadowJar) dependsOn(shadowJar)
} }
}
/* // Needed by gradle-semantic-release-plugin.
Dummy task to hack gradle-semantic-release-plugin to release this project. // Tracking: https://github.com/KengoTODA/gradle-semantic-release-plugin/issues/435
Explanation: // The maven-publish is also necessary to make the signing plugin work.
SemVer is a standard for versioning libraries. publishing {
For that reason the semantic-release plugin uses the "publish" task to publish libraries. repositories {
However, this subproject is not a library, and the "publish" task is not available for this subproject. mavenLocal()
Because semantic-release is not designed to handle this case, we need to hack it. }
RE: https://github.com/KengoTODA/gradle-semantic-release-plugin/issues/435 publications {
*/ create<MavenPublication>("revanced-cli-publication") {
from(components["java"])
register<DefaultTask>("publish") { }
group = "publishing"
description = "Dummy task to hack gradle-semantic-release-plugin to release ReVanced CLI"
dependsOn(build)
} }
} }
signing {
useGpgCmd()
sign(publishing.publications["revanced-cli-publication"])
}

View File

@@ -4,8 +4,8 @@ To use ReVanced CLI, you will need to fulfill specific requirements.
## 🤝 Requirements ## 🤝 Requirements
- Java SDK 11 (Azul Zulu JDK or OpenJDK) - Java Runtime Environment 11 ([Azul Zulu JRE](https://www.azul.com/downloads/?version=java-11-lts&package=jdk#zulu) or [OpenJDK](https://jdk.java.net/archive/))
- [Android Debug Bridge (adb)](https://developer.android.com/studio/command-line/adb) if you want to install the patched APK file on your device - [Android Debug Bridge (ADB)](https://developer.android.com/studio/command-line/adb) if you want to install the patched APK file on your device
- An ABI other than ARMv7 such as x86 or x86-64 (or a custom AAPT binary that supports ARMv7) - An ABI other than ARMv7 such as x86 or x86-64 (or a custom AAPT binary that supports ARMv7)
## ⏭️ Whats next ## ⏭️ Whats next

View File

@@ -1,6 +1,6 @@
# 🛠️ Using ReVanced CLI # 🛠️ Using ReVanced CLI
Learn how to ReVanced CLI. Learn how to use ReVanced CLI.
## 🔨 Usage ## 🔨 Usage
@@ -34,8 +34,8 @@ ReVanced CLI is divided into the following fundamental commands:
revanced-patches.jar [<patch-bundle> ...] revanced-patches.jar [<patch-bundle> ...]
``` ```
> [!NOTE] > ** Note**
> A default `options.json` file will be automatically created, if it does not exist > A default `options.json` file will be automatically created if it does not exist
without any need for intervention when using the `patch` command. without any need for intervention when using the `patch` command.
- ### 💉 Patch an app - ### 💉 Patch an app
@@ -43,19 +43,13 @@ ReVanced CLI is divided into the following fundamental commands:
You can patch apps by supplying patch bundles and the app to patch. You can patch apps by supplying patch bundles and the app to patch.
After patching, ReVanced CLI can install the patched app on your device using two methods: After patching, ReVanced CLI can install the patched app on your device using two methods:
> [!NOTE] > **💡 Tip**
> For ReVanced CLI to be able to install the patched app on your device, make sure ADB is working: > For ReVanced CLI to be able to install the patched app on your device, make sure ADB is working:
> >
> ```bash > ```bash
> adb shell exit > adb shell exit
> ``` > ```
> >
> To get your device's serial, run the following command:
>
> ```bash
> adb devices
> ```
>
> If you want to mount the patched app on top of the un-patched app, make sure you have root permissions: > If you want to mount the patched app on top of the un-patched app, make sure you have root permissions:
> >
> ```bash > ```bash
@@ -63,7 +57,7 @@ ReVanced CLI is divided into the following fundamental commands:
> ``` > ```
> >
> [!WARNING] > **⚠️ Warning**
> Some patches may require integrations > Some patches may require integrations
> such as [ReVanced Integrations](https://github.com/revanced/revanced-integrations). > such as [ReVanced Integrations](https://github.com/revanced/revanced-integrations).
> Supply them with the option `--merge`. ReVanced Patcher will automatically determine if they are necessary. > Supply them with the option `--merge`. ReVanced Patcher will automatically determine if they are necessary.
@@ -73,44 +67,44 @@ ReVanced CLI is divided into the following fundamental commands:
```bash ```bash
java -jar revanced-cli.jar patch \ java -jar revanced-cli.jar patch \
--patch-bundle revanced-patches.jar \ --patch-bundle revanced-patches.jar \
--device-serial <device-serial> \ -d \
input.apk input.apk
``` ```
- #### 👾 Patch an app and mount it on top of the un-patched app with root permissions - #### 👾 Patch an app and mount it on top of the un-patched app with root permissions
> [!IMPORTANT] > **❗ Caution**
> Ensure sure the same app you are patching and mounting over is installed on your device: > Ensure that the same app you are patching and mounting over is installed on your device:
> >
> ```bash > ```bash
> adb install app.apk > adb install app.apk
> ``` > ```
> [!NOTE]
> You can use the option `--ii` to include or `--ie` to exclude
> patches by their index in relation to supplied patch bundles,
> similarly to the option `--include` and `--exclude`.
>
> This is useful in case two patches have the same name, and you need to include or exclude one of them.
> The index of a patch is calculated by the position of the patch in the list of patches
> from patch bundles supplied using the option `--patch-bundle`.
>
> You can list all patches with their indices using the command `list-patches`.
>
> Keep in mind, that the indices can change based on the order of the patch bundles supplied,
> as well if the patch bundles are updated, because patches can be added or removed.
```bash ```bash
java -jar revanced-cli.jar patch \ java -jar revanced-cli.jar patch \
--patch-bundle revanced-patches.jar \ --patch-bundle revanced-patches.jar \
--include "Some patch" \ --include "Some patch" \
--ii 123 \ --ii 123 \
--exclude "Some other patch" \ --exclude "Some other patch" \
--device-serial <device-serial> \ -d \
--mount \ --mount \
app.apk app.apk
``` ```
> **💡 Tip**
> You can use the option `--ii` to include or `--ie` to exclude
> patches by their index in relation to supplied patch bundles,
> similarly to the option `--include` and `--exclude`.
>
> This is useful in case two patches have the same name, and you must include or exclude one.
> The patch index is calculated by the position of the patch in the list of patches
> from patch bundles supplied using the option `--patch-bundle`.
>
> You can list all patches with their indices using the command `list-patches`.
>
> Keep in mind that the indices can change based on the order of the patch bundles supplied,
> as well if the patch bundles are updated because patches can be added or removed.
- ### 🗑️ Uninstall an app - ### 🗑️ Uninstall an app
```bash ```bash
@@ -119,7 +113,7 @@ ReVanced CLI is divided into the following fundamental commands:
[<device-serial>] [<device-serial>]
``` ```
> [!NOTE] > **💡 Tip**
> You can unmount an APK file > You can unmount an APK file
by adding the option `--unmount`. by adding the option `--unmount`.
@@ -131,6 +125,6 @@ ReVanced CLI is divided into the following fundamental commands:
[<device-serial>] [<device-serial>]
``` ```
> [!NOTE] > **💡 Tip**
> You can mount an APK file > You can mount an APK file
> by supplying the package name of the app to mount the supplied APK file to over the option `--mount`. > by supplying the app's package name to mount the supplied APK file over the option `-mount`.

26
docs/2_building.md Normal file
View File

@@ -0,0 +1,26 @@
# 🔨️ Building
Build ReVanced CLI from source.
## 📝 Requirements
- Java Development Kit 11 (Azul Zulu JRE or OpenJDK)
## 🏗️ Building
To build ReVanced CLI, follow these steps:
1. Clone the repository:
```bash
git clone git@github.com:ReVanced/revanced-cli.git
cd revanced-cli
```
2. Build the project:
```bash
./gradlew build
```
After the build succeeds, the built JAR file will be located at `build/libs/revanced-cli-<version>-all.jar`.

View File

@@ -1,8 +1,9 @@
# 💻 Documentation and guides of ReVanced CLI # 💻 Documentation and guides of ReVanced CLI
This documentation explains how to use [ReVanced CLI](https://github.com/revanced/revanced-cli). This documentation contains topics around [ReVanced CLI](https://github.com/revanced/revanced-cli).
## 📖 Table of contents ## 📖 Table of contents
1. [💼 Prerequisites](0_prerequisites.md) 1. [💼 Prerequisites](0_prerequisites.md)
2. [🛠️ Using ReVanced CLI](1_usage.md) 2. [🛠️ Using ReVanced CLI](1_usage.md)
3. [🔨 Building ReVanced CLI](2_building.md)

View File

@@ -1,4 +1,4 @@
org.gradle.parallel = true org.gradle.parallel = true
org.gradle.caching = true org.gradle.caching = true
kotlin.code.style = official kotlin.code.style = official
version = 4.2.0 version = 4.4.1-dev.1

View File

@@ -1,13 +1,13 @@
[versions] [versions]
shadow = "8.1.1" shadow = "8.1.1"
kotlin-test = "1.9.20" kotlin = "1.9.22"
kotlinx-coroutines-core = "1.7.3" kotlinx-coroutines-core = "1.7.3"
picocli = "4.7.3" picocli = "4.7.5"
revanced-patcher = "19.0.0" revanced-patcher = "19.3.1"
revanced-library = "1.3.0" revanced-library = "2.0.0"
[libraries] [libraries]
kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlin-test" } kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlin" }
kotlinx-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "kotlinx-coroutines-core" } kotlinx-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "kotlinx-coroutines-core" }
picocli = { module = "info.picocli:picocli", version.ref = "picocli" } picocli = { module = "info.picocli:picocli", version.ref = "picocli" }
revanced-patcher = { module = "app.revanced:revanced-patcher", version.ref = "revanced-patcher" } revanced-patcher = { module = "app.revanced:revanced-patcher", version.ref = "revanced-patcher" }
@@ -15,3 +15,4 @@ revanced-library = { module = "app.revanced:revanced-library", version.ref = "re
[plugins] [plugins]
shadow = { id = "com.github.johnrengelman.shadow", version.ref = "shadow" } shadow = { id = "com.github.johnrengelman.shadow", version.ref = "shadow" }
kotlin = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" }

View File

@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip
distributionSha256Sum=3e1af3ae886920c3ac87f7a91f816c0c7c436f276a6eefdb3da152100fef72ae distributionSha256Sum=9631d53cf3e74bfa726893aee1f8994fee4e060c401335946dba2156f440f24c
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dist zipStorePath=wrapper/dist

5433
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,9 +1,9 @@
{ {
"devDependencies": { "devDependencies": {
"@saithodev/semantic-release-backmerge": "^3.2.1", "@saithodev/semantic-release-backmerge": "^4.0.1",
"@semantic-release/changelog": "^6.0.3", "@semantic-release/changelog": "^6.0.3",
"@semantic-release/git": "^10.0.1", "@semantic-release/git": "^10.0.1",
"gradle-semantic-release-plugin": "^1.8.0", "gradle-semantic-release-plugin": "^1.9.1",
"semantic-release": "^22.0.8" "semantic-release": "^23.0.2"
} }
} }

View File

@@ -2,6 +2,6 @@ rootProject.name = "revanced-cli"
buildCache { buildCache {
local { local {
isEnabled = !System.getenv().containsKey("CI") isEnabled = "CI" !in System.getenv()
} }
} }

View File

@@ -0,0 +1,67 @@
package app.revanced.cli.command
import app.revanced.library.PackageName
import app.revanced.library.PatchUtils
import app.revanced.library.VersionMap
import app.revanced.patcher.PatchBundleLoader
import picocli.CommandLine
import java.io.File
import java.util.logging.Logger
@CommandLine.Command(
name = "list-versions",
description = [
"List the most common compatible versions of apps that are compatible " +
"with the patches in the supplied patch bundles.",
],
)
internal class ListCompatibleVersions : Runnable {
private val logger = Logger.getLogger(ListCompatibleVersions::class.java.name)
@CommandLine.Parameters(
description = ["Paths to patch bundles."],
arity = "1..*",
)
private lateinit var patchBundles: Array<File>
@CommandLine.Option(
names = ["-f", "--filter-package-names"],
description = ["Filter patches by package name."],
)
private var packageNames: Set<String>? = null
@CommandLine.Option(
names = ["-u", "--count-unused-patches"],
description = ["Count patches that are not used by default."],
showDefaultValue = CommandLine.Help.Visibility.ALWAYS,
)
private var countUnusedPatches: Boolean = false
override fun run() {
val patches = PatchBundleLoader.Jar(*patchBundles)
fun VersionMap.buildVersionsString(): String {
if (isEmpty()) return "Any"
fun buildPatchesCountString(count: Int) = if (count == 1) "1 patch" else "$count patches"
return entries.joinToString("\n") { (version, count) ->
"$version (${buildPatchesCountString(count)})"
}
}
fun buildString(entry: Map.Entry<PackageName, VersionMap>) =
buildString {
val (name, versions) = entry
appendLine("Package name: $name")
appendLine("Most common compatible versions:")
appendLine(versions.buildVersionsString().prependIndent("\t"))
}
PatchUtils.getMostCommonCompatibleVersions(
patches,
packageNames,
countUnusedPatches,
).entries.joinToString("\n", transform = ::buildString).let(logger::info)
}
}

View File

@@ -33,9 +33,10 @@ private object CLIVersionProvider : IVersionProvider {
mixinStandardHelpOptions = true, mixinStandardHelpOptions = true,
versionProvider = CLIVersionProvider::class, versionProvider = CLIVersionProvider::class,
subcommands = [ subcommands = [
ListPatchesCommand::class,
PatchCommand::class, PatchCommand::class,
OptionsCommand::class, OptionsCommand::class,
ListPatchesCommand::class,
ListCompatibleVersions::class,
UtilityCommand::class, UtilityCommand::class,
], ],
) )

View File

@@ -1,13 +1,15 @@
package app.revanced.cli.command package app.revanced.cli.command
import app.revanced.library.ApkUtils import app.revanced.library.ApkUtils
import app.revanced.library.ApkUtils.applyTo
import app.revanced.library.ApkUtils.sign
import app.revanced.library.Options import app.revanced.library.Options
import app.revanced.library.Options.setOptions import app.revanced.library.Options.setOptions
import app.revanced.library.adb.AdbManager import app.revanced.library.adb.AdbManager
import app.revanced.patcher.PatchBundleLoader import app.revanced.patcher.PatchBundleLoader
import app.revanced.patcher.PatchSet import app.revanced.patcher.PatchSet
import app.revanced.patcher.Patcher import app.revanced.patcher.Patcher
import app.revanced.patcher.PatcherOptions import app.revanced.patcher.PatcherConfig
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
import picocli.CommandLine import picocli.CommandLine
import picocli.CommandLine.Help.Visibility.ALWAYS import picocli.CommandLine.Help.Visibility.ALWAYS
@@ -30,9 +32,9 @@ internal object PatchCommand : Runnable {
private lateinit var apk: File private lateinit var apk: File
private var integrations = listOf<File>() private var integrations = setOf<File>()
private var patchBundles = emptyList<File>() private var patchBundles = emptySet<File>()
@CommandLine.Option( @CommandLine.Option(
names = ["-i", "--include"], names = ["-i", "--include"],
@@ -91,7 +93,8 @@ internal object PatchCommand : Runnable {
@CommandLine.Option( @CommandLine.Option(
names = ["-d", "--device-serial"], names = ["-d", "--device-serial"],
description = ["ADB device serial to install to. If not supplied, the first connected device will be used."], description = ["ADB device serial to install to. If not supplied, the first connected device will be used."],
fallbackValue = "", // Empty string to indicate that the first connected device should be used. // Empty string to indicate that the first connected device should be used.
fallbackValue = "",
arity = "0..1", arity = "0..1",
) )
private var deviceSerial: String? = null private var deviceSerial: String? = null
@@ -144,6 +147,17 @@ internal object PatchCommand : Runnable {
description = ["Path to temporary resource cache directory."], description = ["Path to temporary resource cache directory."],
) )
private var resourceCachePath: File? = null private var resourceCachePath: File? = null
set(value) {
logger.warning("The --resource-cache option is deprecated. Use --temporary-files-patch instead.")
field = value
temporaryFilesPath = value
}
@CommandLine.Option(
names = ["-t", "--temporary-files-path"],
description = ["Path to temporary files directory."],
)
private var temporaryFilesPath: File? = null
private var aaptBinaryPath: File? = null private var aaptBinaryPath: File? = null
@@ -194,11 +208,11 @@ internal object PatchCommand : Runnable {
required = true, required = true,
) )
@Suppress("unused") @Suppress("unused")
private fun setPatchBundles(patchBundles: Array<File>) { private fun setPatchBundles(patchBundles: Set<File>) {
patchBundles.firstOrNull { !it.exists() }?.let { patchBundles.firstOrNull { !it.exists() }?.let {
throw CommandLine.ParameterException(spec.commandLine(), "Patch bundle ${it.name} does not exist") throw CommandLine.ParameterException(spec.commandLine(), "Patch bundle ${it.name} does not exist")
} }
this.patchBundles = patchBundles.toList() this.patchBundles = patchBundles
} }
@CommandLine.Option( @CommandLine.Option(
@@ -224,9 +238,9 @@ internal object PatchCommand : Runnable {
"${apk.nameWithoutExtension}-patched.${apk.extension}", "${apk.nameWithoutExtension}-patched.${apk.extension}",
) )
val resourceCachePath = val temporaryFilesPath =
resourceCachePath ?: outputFilePath.parentFile.resolve( temporaryFilesPath ?: outputFilePath.parentFile.resolve(
"${outputFilePath.nameWithoutExtension}-resource-cache", "${outputFilePath.nameWithoutExtension}-temporary-files",
) )
val optionsFile = val optionsFile =
@@ -261,11 +275,11 @@ internal object PatchCommand : Runnable {
// endregion // endregion
Patcher( Patcher(
PatcherOptions( PatcherConfig(
apk, apk,
resourceCachePath, temporaryFilesPath,
aaptBinaryPath?.path, aaptBinaryPath?.path,
resourceCachePath.absolutePath, temporaryFilesPath.absolutePath,
true, true,
), ),
).use { patcher -> ).use { patcher ->
@@ -285,7 +299,7 @@ internal object PatchCommand : Runnable {
val patcherResult = val patcherResult =
patcher.apply { patcher.apply {
acceptIntegrations(integrations) acceptIntegrations(integrations)
acceptPatches(filteredPatches.toList()) acceptPatches(filteredPatches)
// Execute patches. // Execute patches.
runBlocking { runBlocking {
@@ -304,15 +318,12 @@ internal object PatchCommand : Runnable {
// region Save // region Save
val alignedFile = apk.copyTo(outputFilePath, overwrite = true)
resourceCachePath.resolve(apk.name).apply {
ApkUtils.copyAligned(apk, this, patcherResult) patcherResult.applyTo(outputFilePath)
}
if (!mount) { if (!mount) {
ApkUtils.sign( outputFilePath.sign(
alignedFile,
outputFilePath,
ApkUtils.SigningOptions( ApkUtils.SigningOptions(
keystoreFilePath, keystoreFilePath,
keyStorePassword, keyStorePassword,
@@ -321,10 +332,10 @@ internal object PatchCommand : Runnable {
signer, signer,
), ),
) )
} else {
alignedFile.renameTo(outputFilePath)
} }
logger.info("Saved to $outputFilePath")
// endregion // endregion
// region Install // region Install
@@ -338,7 +349,7 @@ internal object PatchCommand : Runnable {
if (purge) { if (purge) {
logger.info("Purging temporary files") logger.info("Purging temporary files")
purge(resourceCachePath) purge(temporaryFilesPath)
} }
} }

View File

@@ -4,7 +4,7 @@ import picocli.CommandLine
@CommandLine.Command( @CommandLine.Command(
name = "utility", name = "utility",
description = ["Commands for utility purposes"], description = ["Commands for utility purposes."],
subcommands = [InstallCommand::class, UninstallCommand::class], subcommands = [InstallCommand::class, UninstallCommand::class],
) )
internal object UtilityCommand internal object UtilityCommand