Skip to content

chore: Merge branch dev to main #366

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 6 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions .github/workflows/build_pull_request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Cache Gradle
uses: burrunan/gradle-cache-action@v1
Expand Down
17 changes: 11 additions & 6 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,12 @@ jobs:
name: Release
permissions:
contents: write
id-token: write
attestations: write
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
# Make sure the release step uses its own credentials:
# https://github.com/cycjimmy/semantic-release-action#private-packages
persist-credentials: false
fetch-depth: 0

- name: Cache Gradle
uses: burrunan/gradle-cache-action@v1
Expand All @@ -47,6 +44,14 @@ jobs:
fingerprint: ${{ vars.GPG_FINGERPRINT }}

- name: Release
uses: cycjimmy/semantic-release-action@v4
id: release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: npm exec semantic-release

- name: Attest
if: steps.release.outputs.new_release_published == 'true'
uses: actions/attest-build-provenance@v2
with:
subject-name: 'ReVanced CLI ${{ steps.release.outputs.new_release_git_tag }}'
subject-path: build/libs/revanced-cli*.jar
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
## [5.0.2-dev.2](https://github.com/ReVanced/revanced-cli/compare/v5.0.2-dev.1...v5.0.2-dev.2) (2025-04-25)


### Bug Fixes

* Do not print patch description if null ([bba90fe](https://github.com/ReVanced/revanced-cli/commit/bba90fede85e4632efb9509e5bcf9091a9435549))

## [5.0.2-dev.1](https://github.com/ReVanced/revanced-cli/compare/v5.0.1...v5.0.2-dev.1) (2025-04-20)


### Bug Fixes

* Group `mount` and `install` options into an argument group ([#364](https://github.com/ReVanced/revanced-cli/issues/364)) ([0c53a2d](https://github.com/ReVanced/revanced-cli/commit/0c53a2d1d75d3d934d134594751fe6cd0b000d1a))

## [5.0.1](https://github.com/ReVanced/revanced-cli/compare/v5.0.0...v5.0.1) (2025-04-14)


Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
org.gradle.parallel = true
org.gradle.caching = true
kotlin.code.style = official
version = 5.0.1
version = 5.0.2-dev.2
89 changes: 43 additions & 46 deletions src/main/kotlin/app/revanced/cli/command/ListPatchesCommand.kt
Original file line number Diff line number Diff line change
Expand Up @@ -85,58 +85,55 @@ internal object ListPatchesCommand : Runnable {
}
}

fun PatchOption<*>.buildString() =
fun PatchOption<*>.buildString() = buildString {
appendLine("Title: $title")
description?.let { appendLine("Description: $it") }
appendLine("Required: $required")
default?.let {
appendLine("Key: $key")
append("Default: $it")
} ?: append("Key: $key")

values?.let { values ->
appendLine("\nPossible values:")
append(values.map { "${it.value} (${it.key})" }.joinToString("\n").prependIndent("\t"))
}

append("\nType: $type")
}

fun IndexedValue<Patch<*>>.buildString() = let { (index, patch) ->
buildString {
appendLine("Title: $title")
description?.let { appendLine("Description: $it") }
appendLine("Required: $required")
default?.let {
appendLine("Key: $key")
append("Default: $it")
} ?: append("Key: $key")

values?.let { values ->
appendLine("\nPossible values:")
append(values.map { "${it.value} (${it.key})" }.joinToString("\n").prependIndent("\t"))
}
if (withIndex) appendLine("Index: $index")

append("\nType: $type")
}
append("Name: ${patch.name}")

fun IndexedValue<Patch<*>>.buildString() =
let { (index, patch) ->
buildString {
if (withIndex) appendLine("Index: $index")

append("Name: ${patch.name}")

if (withDescriptions) append("\nDescription: ${patch.description}")

append("\nEnabled: ${patch.use}")

if (withOptions && patch.options.isNotEmpty()) {
appendLine("\nOptions:")
append(
patch.options.values.joinToString("\n\n") { option ->
option.buildString()
}.prependIndent("\t"),
)
}

if (withPackages && patch.compatiblePackages != null) {
appendLine("\nCompatible packages:")
append(
patch.compatiblePackages!!.joinToString("\n") {
it.buildString()
}.prependIndent("\t"),
)
}
if (withDescriptions) patch.description?.let { append("\nDescription: $it") }

append("\nEnabled: ${patch.use}")

if (withOptions && patch.options.isNotEmpty()) {
appendLine("\nOptions:")
append(
patch.options.values.joinToString("\n\n") { option ->
option.buildString()
}.prependIndent("\t"),
)
}

if (withPackages && patch.compatiblePackages != null) {
appendLine("\nCompatible packages:")
append(
patch.compatiblePackages!!.joinToString("\n") {
it.buildString()
}.prependIndent("\t"),
)
}
}
}

fun Patch<*>.filterCompatiblePackages(name: String) =
compatiblePackages?.any { (compatiblePackageName, _) -> compatiblePackageName == name }
?: withUniversalPatches
fun Patch<*>.filterCompatiblePackages(name: String) = compatiblePackages?.any { (compatiblePackageName, _) -> compatiblePackageName == name }
?: withUniversalPatches

val patches = loadPatchesFromJar(patchesFiles).withIndex().toList()

Expand Down
46 changes: 26 additions & 20 deletions src/main/kotlin/app/revanced/cli/command/PatchCommand.kt
Original file line number Diff line number Diff line change
Expand Up @@ -115,21 +115,27 @@ internal object PatchCommand : Runnable {
this.outputFilePath = outputFilePath?.absoluteFile
}

@CommandLine.Option(
names = ["-i", "--install"],
description = ["Serial of the ADB device to install to. If not specified, the first connected device will be used."],
// Empty string to indicate that the first connected device should be used.
fallbackValue = "",
arity = "0..1",
)
private var deviceSerial: String? = null

@CommandLine.Option(
names = ["--mount"],
description = ["Install the patched APK file by mounting."],
showDefaultValue = ALWAYS,
)
private var mount: Boolean = false
@ArgGroup(exclusive = false, multiplicity = "0..1")
internal var installation: Installation? = null

internal class Installation {
@CommandLine.Option(
names = ["-i", "--install"],
required = true,
description = ["Serial of the ADB device to install to. If not specified, the first connected device will be used."],
fallbackValue = "", // Empty string is used to select the first of connected devices.
arity = "0..1",
)
internal var deviceSerial: String? = null

@CommandLine.Option(
names = ["--mount"],
required = false,
description = ["Install the patched APK file by mounting."],
showDefaultValue = ALWAYS,
)
internal var mount: Boolean = false
}

@CommandLine.Option(
names = ["--keystore"],
Expand Down Expand Up @@ -245,11 +251,11 @@ internal object PatchCommand : Runnable {
keyStoreFilePath ?: outputFilePath.parentFile
.resolve("${outputFilePath.nameWithoutExtension}.keystore")

val installer = if (deviceSerial != null) {
val deviceSerial = deviceSerial!!.ifEmpty { null }
val installer = if (installation?.deviceSerial != null) {
val deviceSerial = installation?.deviceSerial!!.ifEmpty { null }

try {
if (mount) {
if (installation?.mount == true) {
AdbRootInstaller(deviceSerial)
} else {
AdbInstaller(deviceSerial)
Expand Down Expand Up @@ -332,7 +338,7 @@ internal object PatchCommand : Runnable {
apk.copyTo(temporaryFilesPath.resolve(apk.name), overwrite = true).apply {
patcherResult.applyTo(this)
}.let { patchedApkFile ->
if (!mount) {
if (installation?.mount != true) {
ApkUtils.signApk(
patchedApkFile,
outputFilePath,
Expand All @@ -355,7 +361,7 @@ internal object PatchCommand : Runnable {

// region Install.

deviceSerial?.let {
installation?.deviceSerial?.let {
runBlocking {
when (val result = installer!!.install(Installer.Apk(outputFilePath, packageName))) {
RootInstallerResult.FAILURE -> logger.severe("Failed to mount the patched APK file")
Expand Down
Loading