You've already forked revanced-patcher
mirror of
https://github.com/revanced/revanced-patcher
synced 2025-09-06 16:38:50 +02:00
Compare commits
35 Commits
v15.0.1-de
...
v18.0.0-de
Author | SHA1 | Date | |
---|---|---|---|
![]() |
155e787ff4 | ||
![]() |
c38f0ef42a | ||
![]() |
4456031459 | ||
![]() |
5fb59a227f | ||
![]() |
d9fb241d57 | ||
![]() |
642c4ea97e | ||
![]() |
8c8a251626 | ||
![]() |
5953d6cfb5 | ||
![]() |
a1962fe600 | ||
![]() |
77dbee3d6a | ||
![]() |
cb5e39d73e | ||
![]() |
38ef2f470a | ||
![]() |
129d84e108 | ||
![]() |
affeba76b8 | ||
![]() |
6059d3ca26 | ||
![]() |
444dee5a16 | ||
![]() |
d314466ce2 | ||
![]() |
fdaf9c21c8 | ||
![]() |
06c2b76f11 | ||
![]() |
3896b30738 | ||
![]() |
2c4b88e1a0 | ||
![]() |
dfc7e1596b | ||
![]() |
f590436399 | ||
![]() |
cbfb9ba02f | ||
![]() |
b4cfe80ad5 | ||
![]() |
b37906fa35 | ||
![]() |
356f1f1553 | ||
![]() |
e882af74ee | ||
![]() |
46875fb28e | ||
![]() |
417c3e4234 | ||
![]() |
6d2c28807b | ||
![]() |
4d6e08a650 | ||
![]() |
5cebc1fd30 | ||
![]() |
ac61731dc6 | ||
![]() |
9e4ffabd5c |
6
.github/workflows/pull_request.yml
vendored
6
.github/workflows/pull_request.yml
vendored
@@ -1,4 +1,4 @@
|
|||||||
name: PR to main
|
name: Open a PR to main
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
@@ -7,7 +7,7 @@ on:
|
|||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
env:
|
env:
|
||||||
MESSAGE: merge branch `${{ github.head_ref || github.ref_name }}` to `main`
|
MESSAGE: Merge branch `${{ github.head_ref || github.ref_name }}` to `main`
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
pull-request:
|
pull-request:
|
||||||
@@ -15,7 +15,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v4
|
||||||
- name: Open pull request
|
- name: Open pull request
|
||||||
uses: repo-sync/pull-request@v2
|
uses: repo-sync/pull-request@v2
|
||||||
with:
|
with:
|
||||||
|
2
.github/workflows/release.yml
vendored
2
.github/workflows/release.yml
vendored
@@ -17,7 +17,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
# Make sure the release step uses its own credentials:
|
# Make sure the release step uses its own credentials:
|
||||||
# https://github.com/cycjimmy/semantic-release-action#private-packages
|
# https://github.com/cycjimmy/semantic-release-action#private-packages
|
||||||
|
130
CHANGELOG.md
130
CHANGELOG.md
@@ -1,3 +1,133 @@
|
|||||||
|
# [18.0.0-dev.1](https://github.com/ReVanced/revanced-patcher/compare/v17.0.1-dev.1...v18.0.0-dev.1) (2023-10-14)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* Remove patch annotation processor ([4456031](https://github.com/ReVanced/revanced-patcher/commit/445603145979a6f67823a79f9d6cd140299cff37))
|
||||||
|
|
||||||
|
|
||||||
|
### BREAKING CHANGES
|
||||||
|
|
||||||
|
* Various patch constructor signatures have changed.
|
||||||
|
|
||||||
|
## [17.0.1-dev.1](https://github.com/ReVanced/revanced-patcher/compare/v17.0.0...v17.0.1-dev.1) (2023-10-10)
|
||||||
|
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* Run the garbage collector after writing dex files ([d9fb241](https://github.com/ReVanced/revanced-patcher/commit/d9fb241d57b0c4340130c0e5900250e66730ea56))
|
||||||
|
|
||||||
|
# [17.0.0](https://github.com/ReVanced/revanced-patcher/compare/v16.0.2...v17.0.0) (2023-10-09)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* Add option to use single threaded writer for dex files ([77dbee3](https://github.com/ReVanced/revanced-patcher/commit/77dbee3d6ae7b8dc77543e036624daa68ae63504))
|
||||||
|
|
||||||
|
|
||||||
|
### BREAKING CHANGES
|
||||||
|
|
||||||
|
* This commit gets rid of deprecated constructors.
|
||||||
|
|
||||||
|
# [17.0.0-dev.1](https://github.com/ReVanced/revanced-patcher/compare/v16.0.2...v17.0.0-dev.1) (2023-10-09)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* Add option to use single threaded writer for dex files ([77dbee3](https://github.com/ReVanced/revanced-patcher/commit/77dbee3d6ae7b8dc77543e036624daa68ae63504))
|
||||||
|
|
||||||
|
|
||||||
|
### BREAKING CHANGES
|
||||||
|
|
||||||
|
* This commit gets rid of deprecated constructors.
|
||||||
|
|
||||||
|
## [16.0.2](https://github.com/ReVanced/revanced-patcher/compare/v16.0.1...v16.0.2) (2023-10-06)
|
||||||
|
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* Use a map to merge integrations classes ([6059d3c](https://github.com/ReVanced/revanced-patcher/commit/6059d3ca2685cb659023b171b95d4b9d279c6e53))
|
||||||
|
|
||||||
|
## [16.0.2-dev.1](https://github.com/ReVanced/revanced-patcher/compare/v16.0.1...v16.0.2-dev.1) (2023-10-06)
|
||||||
|
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* Use a map to merge integrations classes ([6059d3c](https://github.com/ReVanced/revanced-patcher/commit/6059d3ca2685cb659023b171b95d4b9d279c6e53))
|
||||||
|
|
||||||
|
## [16.0.1](https://github.com/ReVanced/revanced-patcher/compare/v16.0.0...v16.0.1) (2023-10-05)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* Merge integrations when required ([06c2b76](https://github.com/ReVanced/revanced-patcher/commit/06c2b76f11ac1bfe43d51d54d425e7577ecefdf6))
|
||||||
|
|
||||||
|
## [16.0.1-dev.1](https://github.com/ReVanced/revanced-patcher/compare/v16.0.0...v16.0.1-dev.1) (2023-10-05)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* Merge integrations when required ([06c2b76](https://github.com/ReVanced/revanced-patcher/commit/06c2b76f11ac1bfe43d51d54d425e7577ecefdf6))
|
||||||
|
|
||||||
|
# [16.0.0](https://github.com/ReVanced/revanced-patcher/compare/v15.0.3...v16.0.0) (2023-10-04)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* Use correct super class type ([f590436](https://github.com/ReVanced/revanced-patcher/commit/f590436399f6385c51cea54618251b5d823c31f9))
|
||||||
|
|
||||||
|
|
||||||
|
### BREAKING CHANGES
|
||||||
|
|
||||||
|
* This changes the super classes of some `PatchOptionException` classes
|
||||||
|
|
||||||
|
# [16.0.0-dev.1](https://github.com/ReVanced/revanced-patcher/compare/v15.0.3...v16.0.0-dev.1) (2023-10-04)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* Use correct super class type ([f590436](https://github.com/ReVanced/revanced-patcher/commit/f590436399f6385c51cea54618251b5d823c31f9))
|
||||||
|
|
||||||
|
|
||||||
|
### BREAKING CHANGES
|
||||||
|
|
||||||
|
* This changes the super classes of some `PatchOptionException` classes
|
||||||
|
|
||||||
|
## [15.0.3](https://github.com/ReVanced/revanced-patcher/compare/v15.0.2...v15.0.3) (2023-10-01)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* Fix SMALI compilation on devices with RTL language ([#242](https://github.com/ReVanced/revanced-patcher/issues/242)) ([356f1f1](https://github.com/ReVanced/revanced-patcher/commit/356f1f155348347a8f318a2e024716ebf4fec99b))
|
||||||
|
|
||||||
|
## [15.0.3-dev.1](https://github.com/ReVanced/revanced-patcher/compare/v15.0.2...v15.0.3-dev.1) (2023-09-29)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* Fix SMALI compilation on devices with RTL language ([#242](https://github.com/ReVanced/revanced-patcher/issues/242)) ([356f1f1](https://github.com/ReVanced/revanced-patcher/commit/356f1f155348347a8f318a2e024716ebf4fec99b))
|
||||||
|
|
||||||
|
## [15.0.2](https://github.com/ReVanced/revanced-patcher/compare/v15.0.1...v15.0.2) (2023-09-27)
|
||||||
|
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* Do not unnecessary resolve fingeprints twice ([#241](https://github.com/ReVanced/revanced-patcher/issues/241)) ([4d6e08a](https://github.com/ReVanced/revanced-patcher/commit/4d6e08a650dde6ec2e18611c5db1ab92b9a61dd1))
|
||||||
|
|
||||||
|
## [15.0.2-dev.1](https://github.com/ReVanced/revanced-patcher/compare/v15.0.1...v15.0.2-dev.1) (2023-09-26)
|
||||||
|
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* Do not unnecessary resolve fingeprints twice ([#241](https://github.com/ReVanced/revanced-patcher/issues/241)) ([4d6e08a](https://github.com/ReVanced/revanced-patcher/commit/4d6e08a650dde6ec2e18611c5db1ab92b9a61dd1))
|
||||||
|
|
||||||
|
## [15.0.1](https://github.com/ReVanced/revanced-patcher/compare/v15.0.0...v15.0.1) (2023-09-20)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* Remove log management ([d51bc32](https://github.com/ReVanced/revanced-patcher/commit/d51bc32e37a865194c3825471085b3ccf8c78421))
|
||||||
|
|
||||||
## [15.0.1-dev.1](https://github.com/ReVanced/revanced-patcher/compare/v15.0.0...v15.0.1-dev.1) (2023-09-20)
|
## [15.0.1-dev.1](https://github.com/ReVanced/revanced-patcher/compare/v15.0.0...v15.0.1-dev.1) (2023-09-20)
|
||||||
|
|
||||||
|
|
||||||
|
@@ -67,10 +67,10 @@ public final class app/revanced/patcher/PatcherException$CircularDependencyExcep
|
|||||||
public final class app/revanced/patcher/PatcherOptions {
|
public final class app/revanced/patcher/PatcherOptions {
|
||||||
public fun <init> (Ljava/io/File;Ljava/io/File;Ljava/lang/String;Ljava/lang/String;)V
|
public fun <init> (Ljava/io/File;Ljava/io/File;Ljava/lang/String;Ljava/lang/String;)V
|
||||||
public synthetic fun <init> (Ljava/io/File;Ljava/io/File;Ljava/lang/String;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
public synthetic fun <init> (Ljava/io/File;Ljava/io/File;Ljava/lang/String;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||||
public fun <init> (Ljava/io/File;Ljava/io/File;Ljava/lang/String;Ljava/lang/String;Lapp/revanced/patcher/logging/Logger;)V
|
public fun <init> (Ljava/io/File;Ljava/io/File;Ljava/lang/String;Ljava/lang/String;Z)V
|
||||||
public synthetic fun <init> (Ljava/io/File;Ljava/io/File;Ljava/lang/String;Ljava/lang/String;Lapp/revanced/patcher/logging/Logger;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
public synthetic fun <init> (Ljava/io/File;Ljava/io/File;Ljava/lang/String;Ljava/lang/String;ZILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||||
public final fun copy (Ljava/io/File;Ljava/io/File;Ljava/lang/String;Ljava/lang/String;Lapp/revanced/patcher/logging/Logger;)Lapp/revanced/patcher/PatcherOptions;
|
public final fun copy (Ljava/io/File;Ljava/io/File;Ljava/lang/String;Ljava/lang/String;Z)Lapp/revanced/patcher/PatcherOptions;
|
||||||
public static synthetic fun copy$default (Lapp/revanced/patcher/PatcherOptions;Ljava/io/File;Ljava/io/File;Ljava/lang/String;Ljava/lang/String;Lapp/revanced/patcher/logging/Logger;ILjava/lang/Object;)Lapp/revanced/patcher/PatcherOptions;
|
public static synthetic fun copy$default (Lapp/revanced/patcher/PatcherOptions;Ljava/io/File;Ljava/io/File;Ljava/lang/String;Ljava/lang/String;ZILjava/lang/Object;)Lapp/revanced/patcher/PatcherOptions;
|
||||||
public fun equals (Ljava/lang/Object;)Z
|
public fun equals (Ljava/lang/Object;)Z
|
||||||
public fun hashCode ()I
|
public fun hashCode ()I
|
||||||
public final fun recreateResourceCacheDirectory ()Ljava/io/File;
|
public final fun recreateResourceCacheDirectory ()Ljava/io/File;
|
||||||
@@ -306,13 +306,11 @@ public final class app/revanced/patcher/logging/impl/NopLogger : app/revanced/pa
|
|||||||
|
|
||||||
public abstract class app/revanced/patcher/patch/BytecodePatch : app/revanced/patcher/patch/Patch {
|
public abstract class app/revanced/patcher/patch/BytecodePatch : app/revanced/patcher/patch/Patch {
|
||||||
public fun <init> ()V
|
public fun <init> ()V
|
||||||
public fun <init> (Ljava/util/Set;Ljava/lang/String;Ljava/lang/String;Ljava/util/Set;Ljava/util/Set;ZZ)V
|
public fun <init> (Ljava/util/Set;)V
|
||||||
public synthetic fun <init> (Ljava/util/Set;Ljava/lang/String;Ljava/lang/String;Ljava/util/Set;Ljava/util/Set;ZZILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
public synthetic fun <init> (Ljava/util/Set;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract class app/revanced/patcher/patch/Patch {
|
public abstract class app/revanced/patcher/patch/Patch {
|
||||||
public synthetic fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/util/Set;Ljava/util/Set;ZZILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
|
||||||
public synthetic fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/util/Set;Ljava/util/Set;ZZLkotlin/jvm/internal/DefaultConstructorMarker;)V
|
|
||||||
public fun equals (Ljava/lang/Object;)Z
|
public fun equals (Ljava/lang/Object;)Z
|
||||||
public abstract fun execute (Lapp/revanced/patcher/data/Context;)V
|
public abstract fun execute (Lapp/revanced/patcher/data/Context;)V
|
||||||
public final fun getCompatiblePackages ()Ljava/util/Set;
|
public final fun getCompatiblePackages ()Ljava/util/Set;
|
||||||
@@ -346,8 +344,20 @@ public final class app/revanced/patcher/patch/PatchResult {
|
|||||||
|
|
||||||
public abstract class app/revanced/patcher/patch/ResourcePatch : app/revanced/patcher/patch/Patch {
|
public abstract class app/revanced/patcher/patch/ResourcePatch : app/revanced/patcher/patch/Patch {
|
||||||
public fun <init> ()V
|
public fun <init> ()V
|
||||||
public fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/util/Set;Ljava/util/Set;ZZ)V
|
}
|
||||||
public synthetic fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/util/Set;Ljava/util/Set;ZZILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
|
||||||
|
public abstract interface annotation class app/revanced/patcher/patch/annotation/CompatiblePackage : java/lang/annotation/Annotation {
|
||||||
|
public abstract fun name ()Ljava/lang/String;
|
||||||
|
public abstract fun versions ()[Ljava/lang/String;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract interface annotation class app/revanced/patcher/patch/annotation/Patch : java/lang/annotation/Annotation {
|
||||||
|
public abstract fun compatiblePackages ()[Lapp/revanced/patcher/patch/annotation/CompatiblePackage;
|
||||||
|
public abstract fun dependencies ()[Ljava/lang/Class;
|
||||||
|
public abstract fun description ()Ljava/lang/String;
|
||||||
|
public abstract fun name ()Ljava/lang/String;
|
||||||
|
public abstract fun requiresIntegrations ()Z
|
||||||
|
public abstract fun use ()Z
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract class app/revanced/patcher/patch/options/PatchOption {
|
public abstract class app/revanced/patcher/patch/options/PatchOption {
|
||||||
@@ -371,15 +381,15 @@ public final class app/revanced/patcher/patch/options/PatchOptionException$Inval
|
|||||||
public fun <init> (Ljava/lang/String;Ljava/lang/String;)V
|
public fun <init> (Ljava/lang/String;Ljava/lang/String;)V
|
||||||
}
|
}
|
||||||
|
|
||||||
public final class app/revanced/patcher/patch/options/PatchOptionException$PatchOptionNotFoundException : java/lang/Exception {
|
public final class app/revanced/patcher/patch/options/PatchOptionException$PatchOptionNotFoundException : app/revanced/patcher/patch/options/PatchOptionException {
|
||||||
public fun <init> (Ljava/lang/String;)V
|
public fun <init> (Ljava/lang/String;)V
|
||||||
}
|
}
|
||||||
|
|
||||||
public final class app/revanced/patcher/patch/options/PatchOptionException$ValueRequiredException : java/lang/Exception {
|
public final class app/revanced/patcher/patch/options/PatchOptionException$ValueRequiredException : app/revanced/patcher/patch/options/PatchOptionException {
|
||||||
public fun <init> (Lapp/revanced/patcher/patch/options/PatchOption;)V
|
public fun <init> (Lapp/revanced/patcher/patch/options/PatchOption;)V
|
||||||
}
|
}
|
||||||
|
|
||||||
public final class app/revanced/patcher/patch/options/PatchOptionException$ValueValidationException : java/lang/Exception {
|
public final class app/revanced/patcher/patch/options/PatchOptionException$ValueValidationException : app/revanced/patcher/patch/options/PatchOptionException {
|
||||||
public fun <init> (Ljava/lang/Object;Lapp/revanced/patcher/patch/options/PatchOption;)V
|
public fun <init> (Ljava/lang/Object;Lapp/revanced/patcher/patch/options/PatchOption;)V
|
||||||
}
|
}
|
||||||
|
|
@@ -1,10 +1,86 @@
|
|||||||
plugins {
|
plugins {
|
||||||
kotlin("jvm") version "1.9.0" apply false
|
kotlin("jvm") version "1.9.0"
|
||||||
alias(libs.plugins.binary.compatibility.validator)
|
alias(libs.plugins.binary.compatibility.validator)
|
||||||
|
`maven-publish`
|
||||||
|
signing
|
||||||
|
java
|
||||||
}
|
}
|
||||||
|
|
||||||
allprojects {
|
group = "app.revanced"
|
||||||
apply(plugin = "maven-publish")
|
|
||||||
|
|
||||||
group = "app.revanced"
|
tasks {
|
||||||
|
processResources {
|
||||||
|
expand("projectVersion" to project.version)
|
||||||
|
}
|
||||||
|
|
||||||
|
test {
|
||||||
|
useJUnitPlatform()
|
||||||
|
testLogging {
|
||||||
|
events("PASSED", "SKIPPED", "FAILED")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
mavenCentral()
|
||||||
|
mavenLocal()
|
||||||
|
maven { url = uri("https://jitpack.io") }
|
||||||
|
google()
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation(libs.kotlinx.coroutines.core)
|
||||||
|
implementation(libs.xpp3)
|
||||||
|
implementation(libs.smali)
|
||||||
|
implementation(libs.multidexlib2)
|
||||||
|
implementation(libs.apktool.lib)
|
||||||
|
implementation(libs.kotlin.reflect)
|
||||||
|
|
||||||
|
compileOnly(libs.android)
|
||||||
|
|
||||||
|
testImplementation(libs.kotlin.test)
|
||||||
|
}
|
||||||
|
|
||||||
|
java {
|
||||||
|
withJavadocJar()
|
||||||
|
withSourcesJar()
|
||||||
|
}
|
||||||
|
|
||||||
|
kotlin {
|
||||||
|
jvmToolchain(11)
|
||||||
|
}
|
||||||
|
|
||||||
|
publishing {
|
||||||
|
publications {
|
||||||
|
create<MavenPublication>("revanced-patcher-publication") {
|
||||||
|
from(components["java"])
|
||||||
|
|
||||||
|
version = project.version.toString()
|
||||||
|
|
||||||
|
pom {
|
||||||
|
name = "ReVanced Patcher"
|
||||||
|
description = "Patcher used by ReVanced."
|
||||||
|
url = "https://revanced.app"
|
||||||
|
|
||||||
|
licenses {
|
||||||
|
license {
|
||||||
|
name = "GNU General Public License v3.0"
|
||||||
|
url = "https://www.gnu.org/licenses/gpl-3.0.en.html"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
developers {
|
||||||
|
developer {
|
||||||
|
id = "ReVanced"
|
||||||
|
name = "ReVanced"
|
||||||
|
email = "contact@revanced.app"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
scm {
|
||||||
|
connection = "scm:git:git://github.com/revanced/revanced-patcher.git"
|
||||||
|
developerConnection = "scm:git:git@github.com:revanced/revanced-patcher.git"
|
||||||
|
url = "https://github.com/revanced/revanced-patcher"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@@ -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 = 15.0.1-dev.1
|
version = 18.0.0-dev.1
|
||||||
|
@@ -1,31 +1,23 @@
|
|||||||
[versions]
|
[versions]
|
||||||
android = "4.1.1.4"
|
android = "4.1.1.4"
|
||||||
kotlin-reflect = "1.9.0"
|
kotlin-reflect = "1.9.0"
|
||||||
apktool-lib = "2.8.2-6"
|
apktool-lib = "2.9.1"
|
||||||
kotlin-test = "1.8.20-RC"
|
kotlin-test = "1.8.20-RC"
|
||||||
kotlinx-coroutines-core = "1.7.1"
|
kotlinx-coroutines-core = "1.7.3"
|
||||||
multidexlib2 = "3.0.3.r2"
|
multidexlib2 = "3.0.3.r3"
|
||||||
smali = "3.0.3"
|
smali = "3.0.3"
|
||||||
symbol-processing-api = "1.9.0-1.0.11"
|
|
||||||
xpp3 = "1.1.4c"
|
xpp3 = "1.1.4c"
|
||||||
binary-compatibility-validator = "0.13.2"
|
binary-compatibility-validator = "0.13.2"
|
||||||
kotlin-compile-testing-ksp = "1.5.0"
|
|
||||||
kotlinpoet-ksp = "1.14.2"
|
|
||||||
ksp = "1.9.0-1.0.11"
|
|
||||||
|
|
||||||
[libraries]
|
[libraries]
|
||||||
android = { module = "com.google.android:android", version.ref = "android" }
|
android = { module = "com.google.android:android", version.ref = "android" }
|
||||||
kotlin-reflect = { module = "org.jetbrains.kotlin:kotlin-reflect", version.ref = "kotlin-reflect" }
|
kotlin-reflect = { module = "org.jetbrains.kotlin:kotlin-reflect", version.ref = "kotlin-reflect" }
|
||||||
apktool-lib = { module = "app.revanced:apktool-lib", version.ref = "apktool-lib" }
|
apktool-lib = { module = "app.revanced:apktool", version.ref = "apktool-lib" }
|
||||||
kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlin-test" }
|
kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlin-test" }
|
||||||
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" }
|
||||||
multidexlib2 = { module = "app.revanced:multidexlib2", version.ref = "multidexlib2" }
|
multidexlib2 = { module = "app.revanced:multidexlib2", version.ref = "multidexlib2" }
|
||||||
smali = { module = "com.android.tools.smali:smali", version.ref = "smali" }
|
smali = { module = "com.android.tools.smali:smali", version.ref = "smali" }
|
||||||
symbol-processing-api = { module = "com.google.devtools.ksp:symbol-processing-api", version.ref = "symbol-processing-api" }
|
|
||||||
xpp3 = { module = "xpp3:xpp3", version.ref = "xpp3" }
|
xpp3 = { module = "xpp3:xpp3", version.ref = "xpp3" }
|
||||||
kotlin-compile-testing = { module = "com.github.tschuchortdev:kotlin-compile-testing-ksp", version.ref = "kotlin-compile-testing-ksp" }
|
|
||||||
kotlinpoet-ksp = { module = "com.squareup:kotlinpoet-ksp", version.ref = "kotlinpoet-ksp" }
|
|
||||||
|
|
||||||
[plugins]
|
[plugins]
|
||||||
binary-compatibility-validator = { id = "org.jetbrains.kotlinx.binary-compatibility-validator", version.ref = "binary-compatibility-validator" }
|
binary-compatibility-validator = { id = "org.jetbrains.kotlinx.binary-compatibility-validator", version.ref = "binary-compatibility-validator" }
|
||||||
ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" }
|
|
@@ -1,24 +0,0 @@
|
|||||||
public abstract interface annotation class app/revanced/patcher/patch/annotation/CompatiblePackage : java/lang/annotation/Annotation {
|
|
||||||
public abstract fun name ()Ljava/lang/String;
|
|
||||||
public abstract fun versions ()[Ljava/lang/String;
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract interface annotation class app/revanced/patcher/patch/annotation/Patch : java/lang/annotation/Annotation {
|
|
||||||
public abstract fun compatiblePackages ()[Lapp/revanced/patcher/patch/annotation/CompatiblePackage;
|
|
||||||
public abstract fun dependencies ()[Ljava/lang/Class;
|
|
||||||
public abstract fun description ()Ljava/lang/String;
|
|
||||||
public abstract fun name ()Ljava/lang/String;
|
|
||||||
public abstract fun requiresIntegrations ()Z
|
|
||||||
public abstract fun use ()Z
|
|
||||||
}
|
|
||||||
|
|
||||||
public final class app/revanced/patcher/patch/annotation/processor/PatchProcessor : com/google/devtools/ksp/processing/SymbolProcessor {
|
|
||||||
public fun process (Lcom/google/devtools/ksp/processing/Resolver;)Ljava/util/List;
|
|
||||||
}
|
|
||||||
|
|
||||||
public final class app/revanced/patcher/patch/annotation/processor/PatchProcessorProvider : com/google/devtools/ksp/processing/SymbolProcessorProvider {
|
|
||||||
public fun <init> ()V
|
|
||||||
public fun create (Lcom/google/devtools/ksp/processing/SymbolProcessorEnvironment;)Lapp/revanced/patcher/patch/annotation/processor/PatchProcessor;
|
|
||||||
public synthetic fun create (Lcom/google/devtools/ksp/processing/SymbolProcessorEnvironment;)Lcom/google/devtools/ksp/processing/SymbolProcessor;
|
|
||||||
}
|
|
||||||
|
|
@@ -1,74 +0,0 @@
|
|||||||
plugins {
|
|
||||||
kotlin("jvm") version "1.9.0"
|
|
||||||
alias(libs.plugins.ksp)
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
implementation(libs.symbol.processing.api)
|
|
||||||
implementation(libs.kotlinpoet.ksp)
|
|
||||||
implementation(project(":revanced-patcher"))
|
|
||||||
|
|
||||||
testImplementation(libs.kotlin.test)
|
|
||||||
testImplementation(libs.kotlin.compile.testing)
|
|
||||||
}
|
|
||||||
|
|
||||||
tasks {
|
|
||||||
test {
|
|
||||||
useJUnitPlatform()
|
|
||||||
testLogging {
|
|
||||||
events("PASSED", "SKIPPED", "FAILED")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
kotlin { jvmToolchain(11) }
|
|
||||||
|
|
||||||
java {
|
|
||||||
withSourcesJar()
|
|
||||||
}
|
|
||||||
|
|
||||||
publishing {
|
|
||||||
repositories {
|
|
||||||
mavenLocal()
|
|
||||||
maven {
|
|
||||||
name = "GitHubPackages"
|
|
||||||
url = uri("https://maven.pkg.github.com/revanced/revanced-patcher")
|
|
||||||
credentials {
|
|
||||||
username = System.getenv("GITHUB_ACTOR")
|
|
||||||
password = System.getenv("GITHUB_TOKEN")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
publications {
|
|
||||||
create<MavenPublication>("gpr") {
|
|
||||||
from(components["java"])
|
|
||||||
|
|
||||||
version = project.version.toString()
|
|
||||||
|
|
||||||
pom {
|
|
||||||
name = "ReVanced patch annotation processor"
|
|
||||||
description = "Annotation processor for patches."
|
|
||||||
url = "https://revanced.app"
|
|
||||||
|
|
||||||
licenses {
|
|
||||||
license {
|
|
||||||
name = "GNU General Public License v3.0"
|
|
||||||
url = "https://www.gnu.org/licenses/gpl-3.0.en.html"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
developers {
|
|
||||||
developer {
|
|
||||||
id = "ReVanced"
|
|
||||||
name = "ReVanced"
|
|
||||||
email = "contact@revanced.app"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
scm {
|
|
||||||
connection = "scm:git:git://github.com/revanced/revanced-patcher.git"
|
|
||||||
developerConnection = "scm:git:git@github.com:revanced/revanced-patcher.git"
|
|
||||||
url = "https://github.com/revanced/revanced-patcher"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,2 +0,0 @@
|
|||||||
rootProject.name = "revanced-patch-annotation-processor"
|
|
||||||
|
|
@@ -1,207 +0,0 @@
|
|||||||
package app.revanced.patcher.patch.annotation.processor
|
|
||||||
|
|
||||||
import app.revanced.patcher.data.BytecodeContext
|
|
||||||
import app.revanced.patcher.data.ResourceContext
|
|
||||||
import app.revanced.patcher.patch.BytecodePatch
|
|
||||||
import app.revanced.patcher.patch.ResourcePatch
|
|
||||||
import app.revanced.patcher.patch.annotation.Patch
|
|
||||||
import com.google.devtools.ksp.processing.CodeGenerator
|
|
||||||
import com.google.devtools.ksp.processing.Dependencies
|
|
||||||
import com.google.devtools.ksp.processing.Resolver
|
|
||||||
import com.google.devtools.ksp.processing.SymbolProcessor
|
|
||||||
import com.google.devtools.ksp.symbol.KSAnnotated
|
|
||||||
import com.google.devtools.ksp.symbol.KSAnnotation
|
|
||||||
import com.google.devtools.ksp.symbol.KSClassDeclaration
|
|
||||||
import com.google.devtools.ksp.symbol.KSType
|
|
||||||
import com.google.devtools.ksp.validate
|
|
||||||
import com.squareup.kotlinpoet.*
|
|
||||||
import com.squareup.kotlinpoet.ksp.toClassName
|
|
||||||
import com.squareup.kotlinpoet.ksp.writeTo
|
|
||||||
import kotlin.reflect.KClass
|
|
||||||
|
|
||||||
class PatchProcessor internal constructor(
|
|
||||||
private val codeGenerator: CodeGenerator,
|
|
||||||
) : SymbolProcessor {
|
|
||||||
|
|
||||||
private fun KSAnnotated.isSubclassOf(cls: KClass<*>): Boolean {
|
|
||||||
if (this !is KSClassDeclaration) return false
|
|
||||||
|
|
||||||
if (qualifiedName?.asString() == cls.qualifiedName) return true
|
|
||||||
|
|
||||||
return superTypes.any { it.resolve().declaration.isSubclassOf(cls) }
|
|
||||||
}
|
|
||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
|
||||||
override fun process(resolver: Resolver): List<KSAnnotated> {
|
|
||||||
val patches = buildMap {
|
|
||||||
resolver.getSymbolsWithAnnotation(Patch::class.qualifiedName!!).filter {
|
|
||||||
// Do not check here if Patch is super of the class, because it is expensive.
|
|
||||||
// Check it later when processing.
|
|
||||||
it.validate() && it.isSubclassOf(app.revanced.patcher.patch.Patch::class)
|
|
||||||
}.map {
|
|
||||||
it as KSClassDeclaration
|
|
||||||
}.forEach { patchDeclaration ->
|
|
||||||
patchDeclaration.annotations.find {
|
|
||||||
it.annotationType.resolve().declaration.qualifiedName!!.asString() == Patch::class.qualifiedName!!
|
|
||||||
}?.let { annotation ->
|
|
||||||
fun KSAnnotation.property(name: String) =
|
|
||||||
arguments.find { it.name!!.asString() == name }?.value!!
|
|
||||||
|
|
||||||
val name =
|
|
||||||
annotation.property("name").toString().ifEmpty { null }
|
|
||||||
|
|
||||||
val description =
|
|
||||||
annotation.property("description").toString().ifEmpty { null }
|
|
||||||
|
|
||||||
val dependencies =
|
|
||||||
(annotation.property("dependencies") as List<KSType>).ifEmpty { null }
|
|
||||||
|
|
||||||
val compatiblePackages =
|
|
||||||
(annotation.property("compatiblePackages") as List<KSAnnotation>).ifEmpty { null }
|
|
||||||
|
|
||||||
val use =
|
|
||||||
annotation.property("use") as Boolean
|
|
||||||
|
|
||||||
val requiresIntegrations =
|
|
||||||
annotation.property("requiresIntegrations") as Boolean
|
|
||||||
|
|
||||||
// Data class for KotlinPoet
|
|
||||||
data class PatchData(
|
|
||||||
val name: String?,
|
|
||||||
val description: String?,
|
|
||||||
val dependencies: List<ClassName>?,
|
|
||||||
val compatiblePackages: List<CodeBlock>?,
|
|
||||||
val use: Boolean,
|
|
||||||
val requiresIntegrations: Boolean
|
|
||||||
)
|
|
||||||
|
|
||||||
this[patchDeclaration] = PatchData(
|
|
||||||
name,
|
|
||||||
description,
|
|
||||||
dependencies?.map { dependency -> dependency.toClassName() },
|
|
||||||
compatiblePackages?.map {
|
|
||||||
val packageName = it.property("name")
|
|
||||||
val packageVersions = (it.property("versions") as List<String>).ifEmpty { null }
|
|
||||||
?.joinToString(", ") { version -> "\"$version\"" }
|
|
||||||
|
|
||||||
CodeBlock.of(
|
|
||||||
"%T(%S, %L)",
|
|
||||||
app.revanced.patcher.patch.Patch.CompatiblePackage::class,
|
|
||||||
packageName,
|
|
||||||
packageVersions?.let { "setOf($packageVersions)" },
|
|
||||||
)
|
|
||||||
},
|
|
||||||
use,
|
|
||||||
requiresIntegrations
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If a patch depends on another, that is annotated, the dependency should be replaced with the generated patch,
|
|
||||||
// because the generated patch has all the necessary properties to invoke the super constructor with,
|
|
||||||
// unlike the annotated patch.
|
|
||||||
val dependencyResolutionMap = buildMap {
|
|
||||||
patches.values.filter { it.dependencies != null }.flatMap {
|
|
||||||
it.dependencies!!
|
|
||||||
}.distinct().forEach { dependency ->
|
|
||||||
patches.keys.find { it.qualifiedName?.asString() == dependency.toString() }
|
|
||||||
?.let { patch ->
|
|
||||||
this[dependency] = ClassName(
|
|
||||||
patch.packageName.asString(),
|
|
||||||
patch.simpleName.asString() + "Generated"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
patches.forEach { (patchDeclaration, patchAnnotation) ->
|
|
||||||
val isBytecodePatch = patchDeclaration.isSubclassOf(BytecodePatch::class)
|
|
||||||
|
|
||||||
val superClass = if (isBytecodePatch) {
|
|
||||||
BytecodePatch::class
|
|
||||||
} else {
|
|
||||||
ResourcePatch::class
|
|
||||||
}
|
|
||||||
|
|
||||||
val contextClass = if (isBytecodePatch) {
|
|
||||||
BytecodeContext::class
|
|
||||||
} else {
|
|
||||||
ResourceContext::class
|
|
||||||
}
|
|
||||||
|
|
||||||
val generatedPatchClassName = ClassName(
|
|
||||||
patchDeclaration.packageName.asString(),
|
|
||||||
patchDeclaration.simpleName.asString() + "Generated"
|
|
||||||
)
|
|
||||||
|
|
||||||
FileSpec.builder(generatedPatchClassName)
|
|
||||||
.addType(
|
|
||||||
TypeSpec.objectBuilder(generatedPatchClassName)
|
|
||||||
.superclass(superClass).apply {
|
|
||||||
patchAnnotation.name?.let { name ->
|
|
||||||
addSuperclassConstructorParameter("name = %S", name)
|
|
||||||
}
|
|
||||||
|
|
||||||
patchAnnotation.description?.let { description ->
|
|
||||||
addSuperclassConstructorParameter("description = %S", description)
|
|
||||||
}
|
|
||||||
|
|
||||||
patchAnnotation.compatiblePackages?.let { compatiblePackages ->
|
|
||||||
addSuperclassConstructorParameter(
|
|
||||||
"compatiblePackages = setOf(%L)",
|
|
||||||
compatiblePackages.joinToString(", ")
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// The generated patch always depends on the source patch.
|
|
||||||
addSuperclassConstructorParameter(
|
|
||||||
"dependencies = setOf(%L)",
|
|
||||||
buildList {
|
|
||||||
patchAnnotation.dependencies?.forEach { dependency ->
|
|
||||||
add("${(dependencyResolutionMap[dependency] ?: dependency)}::class")
|
|
||||||
}
|
|
||||||
|
|
||||||
add("${patchDeclaration.toClassName()}::class")
|
|
||||||
}.joinToString(", "),
|
|
||||||
)
|
|
||||||
|
|
||||||
addSuperclassConstructorParameter(
|
|
||||||
"use = %L", patchAnnotation.use
|
|
||||||
)
|
|
||||||
|
|
||||||
addSuperclassConstructorParameter(
|
|
||||||
"requiresIntegrations = %L",
|
|
||||||
patchAnnotation.requiresIntegrations
|
|
||||||
)
|
|
||||||
}
|
|
||||||
.addFunction(
|
|
||||||
FunSpec.builder("execute")
|
|
||||||
.addModifiers(KModifier.OVERRIDE)
|
|
||||||
.addParameter("context", contextClass)
|
|
||||||
.build()
|
|
||||||
)
|
|
||||||
.addInitializerBlock(
|
|
||||||
CodeBlock.builder()
|
|
||||||
.add(
|
|
||||||
"%T.options.forEach { (_, option) ->",
|
|
||||||
patchDeclaration.toClassName()
|
|
||||||
)
|
|
||||||
.addStatement(
|
|
||||||
"options.register(option)"
|
|
||||||
)
|
|
||||||
.add(
|
|
||||||
"}"
|
|
||||||
)
|
|
||||||
.build()
|
|
||||||
)
|
|
||||||
.build()
|
|
||||||
).build().writeTo(
|
|
||||||
codeGenerator,
|
|
||||||
Dependencies(false, patchDeclaration.containingFile!!)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
return emptyList()
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,9 +0,0 @@
|
|||||||
package app.revanced.patcher.patch.annotation.processor
|
|
||||||
|
|
||||||
import com.google.devtools.ksp.processing.SymbolProcessorEnvironment
|
|
||||||
import com.google.devtools.ksp.processing.SymbolProcessorProvider
|
|
||||||
|
|
||||||
class PatchProcessorProvider : SymbolProcessorProvider {
|
|
||||||
override fun create(environment: SymbolProcessorEnvironment) =
|
|
||||||
PatchProcessor(environment.codeGenerator)
|
|
||||||
}
|
|
@@ -1 +0,0 @@
|
|||||||
app.revanced.patcher.patch.annotation.processor.PatchProcessorProvider
|
|
@@ -1,147 +0,0 @@
|
|||||||
package app.revanced.patcher.patch.annotation.processor
|
|
||||||
|
|
||||||
import app.revanced.patcher.patch.Patch
|
|
||||||
import com.tschuchort.compiletesting.KotlinCompilation
|
|
||||||
import com.tschuchort.compiletesting.SourceFile
|
|
||||||
import com.tschuchort.compiletesting.kspWithCompilation
|
|
||||||
import com.tschuchort.compiletesting.symbolProcessorProviders
|
|
||||||
import kotlin.test.Test
|
|
||||||
import kotlin.test.assertEquals
|
|
||||||
import kotlin.test.assertNull
|
|
||||||
|
|
||||||
class TestPatchAnnotationProcessor {
|
|
||||||
// region Processing
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun testProcessing() = assertEquals(
|
|
||||||
"Processable patch", compile(
|
|
||||||
getSourceFile(
|
|
||||||
"processing", "ProcessablePatch"
|
|
||||||
)
|
|
||||||
).loadPatch("$SAMPLE_PACKAGE.processing.ProcessablePatchGenerated").name
|
|
||||||
)
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun generateNullProperties() = compile(
|
|
||||||
getSourceFile(
|
|
||||||
"null", "NullPropertiesPatch"
|
|
||||||
)
|
|
||||||
).loadPatch("$SAMPLE_PACKAGE.null.NullPropertiesPatchGenerated").let {
|
|
||||||
assertNull(it.description) // Because no description was provided.
|
|
||||||
assertNull(it.compatiblePackages!!.first().versions) // Because no versions were provided.
|
|
||||||
}
|
|
||||||
|
|
||||||
// endregion
|
|
||||||
|
|
||||||
// region Dependencies
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun testDependencies() {
|
|
||||||
compile(
|
|
||||||
getSourceFile(
|
|
||||||
"dependencies", "DependentPatch"
|
|
||||||
), getSourceFile(
|
|
||||||
"dependencies", "DependencyPatch"
|
|
||||||
)
|
|
||||||
).let { result ->
|
|
||||||
result.loadPatch("$SAMPLE_PACKAGE.dependencies.DependentPatchGenerated").let {
|
|
||||||
// Dependency as well as the source class of the generated class.
|
|
||||||
assertEquals(
|
|
||||||
2,
|
|
||||||
it.dependencies!!.size
|
|
||||||
)
|
|
||||||
|
|
||||||
// The last dependency is always the source class of the generated class to respect
|
|
||||||
// order of dependencies.
|
|
||||||
assertEquals(
|
|
||||||
result.loadPatch("$SAMPLE_PACKAGE.dependencies.DependentPatch")::class,
|
|
||||||
it.dependencies!!.last()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// endregion
|
|
||||||
|
|
||||||
// region Options
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun testOptions() {
|
|
||||||
val patch = compile(
|
|
||||||
getSourceFile(
|
|
||||||
"options", "OptionsPatch"
|
|
||||||
)
|
|
||||||
).loadPatch("$SAMPLE_PACKAGE.options.OptionsPatchGenerated")
|
|
||||||
|
|
||||||
assert(patch.options.isNotEmpty())
|
|
||||||
assertEquals(patch.options["print"].title, "Print message")
|
|
||||||
}
|
|
||||||
|
|
||||||
// endregion
|
|
||||||
|
|
||||||
// region Limitations
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun failingManualDependency() = assertEquals(
|
|
||||||
1, // Generated patch is always dependent on source class.
|
|
||||||
compile(
|
|
||||||
getSourceFile(
|
|
||||||
"limitations/manualdependency", "DependentPatch"
|
|
||||||
), getSourceFile(
|
|
||||||
"limitations/manualdependency", "DependencyPatch"
|
|
||||||
)
|
|
||||||
).loadPatch("$SAMPLE_PACKAGE.limitations.manualdependency.DependentPatchGenerated").dependencies!!.size
|
|
||||||
)
|
|
||||||
|
|
||||||
// endregion
|
|
||||||
|
|
||||||
private companion object Utils {
|
|
||||||
const val SAMPLE_PACKAGE = "app.revanced.patcher.patch.annotation.processor.samples"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a source file from the given sample and class name.
|
|
||||||
*
|
|
||||||
* @param sample The sample to get the source file from.
|
|
||||||
* @param className The name of the class to get the source file from.
|
|
||||||
* @return The source file.
|
|
||||||
*/
|
|
||||||
fun getSourceFile(sample: String, className: String): SourceFile {
|
|
||||||
val resourceName = "app/revanced/patcher/patch/annotation/processor/samples/$sample/$className.kt"
|
|
||||||
return SourceFile.kotlin(
|
|
||||||
"$className.kt",
|
|
||||||
TestPatchAnnotationProcessor::class.java.classLoader.getResourceAsStream(resourceName)
|
|
||||||
?.readAllBytes()
|
|
||||||
?.toString(Charsets.UTF_8)
|
|
||||||
?: error("Could not find resource $resourceName")
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Compile the given source files and return the result.
|
|
||||||
*
|
|
||||||
* @param sourceFiles The source files to compile.
|
|
||||||
* @return The result of the compilation.
|
|
||||||
*/
|
|
||||||
fun compile(vararg sourceFiles: SourceFile) = KotlinCompilation().apply {
|
|
||||||
sources = sourceFiles.asList()
|
|
||||||
|
|
||||||
symbolProcessorProviders = listOf(PatchProcessorProvider())
|
|
||||||
|
|
||||||
// Required until https://github.com/tschuchortdev/kotlin-compile-testing/issues/312 closed.
|
|
||||||
kspWithCompilation = true
|
|
||||||
|
|
||||||
inheritClassPath = true
|
|
||||||
messageOutputStream = System.out
|
|
||||||
}.compile().also { result ->
|
|
||||||
assertEquals(KotlinCompilation.ExitCode.OK, result.exitCode)
|
|
||||||
}
|
|
||||||
|
|
||||||
// region Class loading
|
|
||||||
|
|
||||||
fun KotlinCompilation.Result.loadPatch(name: String) = classLoader.loadClass(name).loadPatch()
|
|
||||||
|
|
||||||
fun Class<*>.loadPatch() = this.getField("INSTANCE").get(null) as Patch<*>
|
|
||||||
|
|
||||||
// endregion
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,10 +0,0 @@
|
|||||||
package app.revanced.patcher.patch.annotation.processor.samples.dependencies
|
|
||||||
|
|
||||||
import app.revanced.patcher.data.ResourceContext
|
|
||||||
import app.revanced.patcher.patch.ResourcePatch
|
|
||||||
import app.revanced.patcher.patch.annotation.Patch
|
|
||||||
|
|
||||||
@Patch(name = "Dependency patch")
|
|
||||||
object DependencyPatch : ResourcePatch() {
|
|
||||||
override fun execute(context: ResourceContext) {}
|
|
||||||
}
|
|
@@ -1,12 +0,0 @@
|
|||||||
package app.revanced.patcher.patch.annotation.processor.samples.dependencies
|
|
||||||
import app.revanced.patcher.data.BytecodeContext
|
|
||||||
import app.revanced.patcher.patch.BytecodePatch
|
|
||||||
import app.revanced.patcher.patch.annotation.Patch
|
|
||||||
|
|
||||||
@Patch(
|
|
||||||
name = "Dependent patch",
|
|
||||||
dependencies = [DependencyPatch::class],
|
|
||||||
)
|
|
||||||
object DependentPatch : BytecodePatch() {
|
|
||||||
override fun execute(context: BytecodeContext) {}
|
|
||||||
}
|
|
@@ -1,10 +0,0 @@
|
|||||||
package app.revanced.patcher.patch.annotation.processor.samples.limitations.manualdependency
|
|
||||||
|
|
||||||
import app.revanced.patcher.data.ResourceContext
|
|
||||||
import app.revanced.patcher.patch.ResourcePatch
|
|
||||||
import app.revanced.patcher.patch.annotation.Patch
|
|
||||||
|
|
||||||
@Patch(name = "Dependency patch")
|
|
||||||
object DependencyPatch : ResourcePatch() {
|
|
||||||
override fun execute(context: ResourceContext) { }
|
|
||||||
}
|
|
@@ -1,17 +0,0 @@
|
|||||||
package app.revanced.patcher.patch.annotation.processor.samples.limitations.manualdependency
|
|
||||||
import app.revanced.patcher.data.BytecodeContext
|
|
||||||
import app.revanced.patcher.patch.BytecodePatch
|
|
||||||
import app.revanced.patcher.patch.annotation.Patch
|
|
||||||
|
|
||||||
@Patch(name = "Dependent patch")
|
|
||||||
object DependentPatch : BytecodePatch(
|
|
||||||
// Dependency will not be executed correctly if it is manually specified.
|
|
||||||
// The reason for this is that the dependency patch is annotated too,
|
|
||||||
// so the processor will generate a new patch class for it embedding the annotated information.
|
|
||||||
// Because the dependency is manually specified,
|
|
||||||
// the processor will not be able to change this dependency to the generated class,
|
|
||||||
// which means that the dependency will lose the annotated information.
|
|
||||||
dependencies = setOf(DependencyPatch::class)
|
|
||||||
) {
|
|
||||||
override fun execute(context: BytecodeContext) {}
|
|
||||||
}
|
|
@@ -1,14 +0,0 @@
|
|||||||
package app.revanced.patcher.patch.annotation.processor.samples.`null`
|
|
||||||
|
|
||||||
import app.revanced.patcher.data.BytecodeContext
|
|
||||||
import app.revanced.patcher.patch.BytecodePatch
|
|
||||||
import app.revanced.patcher.patch.annotation.CompatiblePackage
|
|
||||||
import app.revanced.patcher.patch.annotation.Patch
|
|
||||||
|
|
||||||
@Patch(
|
|
||||||
"Patch with null properties",
|
|
||||||
compatiblePackages = [CompatiblePackage("com.google.android.youtube")],
|
|
||||||
)
|
|
||||||
object NullPropertiesPatch : BytecodePatch() {
|
|
||||||
override fun execute(context: BytecodeContext) {}
|
|
||||||
}
|
|
@@ -1,19 +0,0 @@
|
|||||||
package app.revanced.patcher.patch.annotation.processor.samples.options
|
|
||||||
|
|
||||||
import app.revanced.patcher.data.ResourceContext
|
|
||||||
import app.revanced.patcher.patch.ResourcePatch
|
|
||||||
import app.revanced.patcher.patch.annotation.Patch
|
|
||||||
import app.revanced.patcher.patch.options.types.StringPatchOption.Companion.stringPatchOption
|
|
||||||
|
|
||||||
@Patch(name = "Options patch")
|
|
||||||
object OptionsPatch : ResourcePatch() {
|
|
||||||
override fun execute(context: ResourceContext) {}
|
|
||||||
|
|
||||||
@Suppress("unused")
|
|
||||||
private val printOption by stringPatchOption(
|
|
||||||
"print",
|
|
||||||
null,
|
|
||||||
"Print message",
|
|
||||||
"The message to print."
|
|
||||||
)
|
|
||||||
}
|
|
@@ -1,10 +0,0 @@
|
|||||||
package app.revanced.patcher.patch.annotation.processor.samples.processing
|
|
||||||
|
|
||||||
import app.revanced.patcher.data.BytecodeContext
|
|
||||||
import app.revanced.patcher.patch.BytecodePatch
|
|
||||||
import app.revanced.patcher.patch.annotation.Patch
|
|
||||||
|
|
||||||
@Patch("Processable patch")
|
|
||||||
object ProcessablePatch : BytecodePatch() {
|
|
||||||
override fun execute(context: BytecodeContext) {}
|
|
||||||
}
|
|
@@ -1,82 +0,0 @@
|
|||||||
plugins {
|
|
||||||
kotlin("jvm") version "1.9.0"
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
implementation(libs.kotlinx.coroutines.core)
|
|
||||||
implementation(libs.xpp3)
|
|
||||||
implementation(libs.smali)
|
|
||||||
implementation(libs.multidexlib2)
|
|
||||||
implementation(libs.apktool.lib)
|
|
||||||
implementation(libs.kotlin.reflect)
|
|
||||||
|
|
||||||
compileOnly(libs.android)
|
|
||||||
|
|
||||||
testImplementation(project(":revanced-patch-annotation-processor"))
|
|
||||||
testImplementation(libs.kotlin.test)
|
|
||||||
}
|
|
||||||
|
|
||||||
tasks {
|
|
||||||
test {
|
|
||||||
useJUnitPlatform()
|
|
||||||
testLogging {
|
|
||||||
events("PASSED", "SKIPPED", "FAILED")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
processResources {
|
|
||||||
expand("projectVersion" to project.version)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
kotlin { jvmToolchain(11) }
|
|
||||||
|
|
||||||
java {
|
|
||||||
withSourcesJar()
|
|
||||||
}
|
|
||||||
|
|
||||||
publishing {
|
|
||||||
repositories {
|
|
||||||
mavenLocal()
|
|
||||||
maven {
|
|
||||||
name = "GitHubPackages"
|
|
||||||
url = uri("https://maven.pkg.github.com/revanced/revanced-patcher")
|
|
||||||
credentials {
|
|
||||||
username = System.getenv("GITHUB_ACTOR")
|
|
||||||
password = System.getenv("GITHUB_TOKEN")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
publications {
|
|
||||||
create<MavenPublication>("gpr") {
|
|
||||||
from(components["java"])
|
|
||||||
|
|
||||||
version = project.version.toString()
|
|
||||||
|
|
||||||
pom {
|
|
||||||
name = "ReVanced Patcher"
|
|
||||||
description = "Patcher used by ReVanced."
|
|
||||||
url = "https://revanced.app"
|
|
||||||
|
|
||||||
licenses {
|
|
||||||
license {
|
|
||||||
name = "GNU General Public License v3.0"
|
|
||||||
url = "https://www.gnu.org/licenses/gpl-3.0.en.html"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
developers {
|
|
||||||
developer {
|
|
||||||
id = "ReVanced"
|
|
||||||
name = "ReVanced"
|
|
||||||
email = "contact@revanced.app"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
scm {
|
|
||||||
connection = "scm:git:git://github.com/revanced/revanced-patcher.git"
|
|
||||||
developerConnection = "scm:git:git@github.com:revanced/revanced-patcher.git"
|
|
||||||
url = "https://github.com/revanced/revanced-patcher"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1 +0,0 @@
|
|||||||
rootProject.name = "revanced-patcher"
|
|
@@ -1,27 +0,0 @@
|
|||||||
package app.revanced.patcher.patch
|
|
||||||
|
|
||||||
import app.revanced.patcher.PatchClass
|
|
||||||
import app.revanced.patcher.data.BytecodeContext
|
|
||||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A ReVanced [Patch] that works on [BytecodeContext].
|
|
||||||
*
|
|
||||||
* @param fingerprints A list of [MethodFingerprint]s which will be resolved before the patch is executed.
|
|
||||||
* @param name The name of the patch.
|
|
||||||
* @param description The description of the patch.
|
|
||||||
* @param compatiblePackages The packages the patch is compatible with.
|
|
||||||
* @param dependencies The names of patches this patch depends on.
|
|
||||||
* @param use Weather or not the patch should be used.
|
|
||||||
* @param requiresIntegrations Weather or not the patch requires integrations.
|
|
||||||
*/
|
|
||||||
abstract class BytecodePatch(
|
|
||||||
internal val fingerprints: Set<MethodFingerprint> = emptySet(),
|
|
||||||
name: String? = null,
|
|
||||||
description: String? = null,
|
|
||||||
compatiblePackages: Set<CompatiblePackage>? = null,
|
|
||||||
dependencies: Set<PatchClass>? = null,
|
|
||||||
use: Boolean = true,
|
|
||||||
// TODO: Remove this property, once integrations are coupled with patches.
|
|
||||||
requiresIntegrations: Boolean = false,
|
|
||||||
) : Patch<BytecodeContext>(name, description, compatiblePackages, dependencies, use, requiresIntegrations)
|
|
@@ -1,24 +0,0 @@
|
|||||||
package app.revanced.patcher.patch
|
|
||||||
|
|
||||||
import app.revanced.patcher.PatchClass
|
|
||||||
import app.revanced.patcher.data.ResourceContext
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A ReVanced [Patch] that works on [ResourceContext].
|
|
||||||
*
|
|
||||||
* @param name The name of the patch.
|
|
||||||
* @param description The description of the patch.
|
|
||||||
* @param compatiblePackages The packages the patch is compatible with.
|
|
||||||
* @param dependencies The names of patches this patch depends on.
|
|
||||||
* @param use Weather or not the patch should be used.
|
|
||||||
* @param requiresIntegrations Weather or not the patch requires integrations.
|
|
||||||
*/
|
|
||||||
abstract class ResourcePatch(
|
|
||||||
name: String? = null,
|
|
||||||
description: String? = null,
|
|
||||||
compatiblePackages: Set<CompatiblePackage>? = null,
|
|
||||||
dependencies: Set<PatchClass>? = null,
|
|
||||||
use: Boolean = true,
|
|
||||||
// TODO: Remove this property, once integrations are coupled with patches.
|
|
||||||
requiresIntegrations: Boolean = false,
|
|
||||||
) : Patch<ResourceContext>(name, description, compatiblePackages, dependencies, use, requiresIntegrations)
|
|
@@ -1,22 +1 @@
|
|||||||
val githubUsername: String = providers.gradleProperty("gpr.user").orNull ?: System.getenv("GITHUB_ACTOR")
|
rootProject.name = "revanced-patcher"
|
||||||
val githubPassword: String = providers.gradleProperty("gpr.key").orNull ?: System.getenv("GITHUB_TOKEN")
|
|
||||||
|
|
||||||
dependencyResolutionManagement {
|
|
||||||
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
|
|
||||||
repositories {
|
|
||||||
mavenCentral()
|
|
||||||
google()
|
|
||||||
mavenLocal()
|
|
||||||
listOf("multidexlib2", "apktool").forEach { repo ->
|
|
||||||
maven {
|
|
||||||
url = uri("https://maven.pkg.github.com/revanced/$repo")
|
|
||||||
credentials {
|
|
||||||
username = githubUsername
|
|
||||||
password = githubPassword
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
include("revanced-patch-annotation-processor", "revanced-patcher")
|
|
@@ -104,7 +104,7 @@ class Patcher(
|
|||||||
|
|
||||||
// Determine, if merging integrations is required.
|
// Determine, if merging integrations is required.
|
||||||
for (patch in patches)
|
for (patch in patches)
|
||||||
if (!patch.anyRecursively { it.requiresIntegrations }) {
|
if (patch.anyRecursively { it.requiresIntegrations }) {
|
||||||
context.bytecodeContext.integrations.merge = true
|
context.bytecodeContext.integrations.merge = true
|
||||||
break
|
break
|
||||||
}
|
}
|
@@ -37,4 +37,5 @@ class PatcherContext internal constructor(options: PatcherOptions) {
|
|||||||
* The [BytecodeContext] of this [PatcherContext].
|
* The [BytecodeContext] of this [PatcherContext].
|
||||||
* This holds the current state of the bytecode.
|
* This holds the current state of the bytecode.
|
||||||
*/
|
*/
|
||||||
internal val bytecodeContext = BytecodeContext(options) }
|
internal val bytecodeContext = BytecodeContext(options)
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user