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
144 Commits
v15.0.0-de
...
v19.3.0-de
Author | SHA1 | Date | |
---|---|---|---|
![]() |
17a4675a8e | ||
![]() |
98085d1d45 | ||
![]() |
bc5c16f112 | ||
![]() |
f1d7217495 | ||
![]() |
64dd1526cd | ||
![]() |
c9a82608f7 | ||
![]() |
9fc42e132c | ||
![]() |
efa98ece45 | ||
![]() |
68e2acebba | ||
![]() |
7a7a8fc353 | ||
![]() |
f8306ac43d | ||
![]() |
d03591b735 | ||
![]() |
4a9184597b | ||
![]() |
0a482f8c9a | ||
![]() |
e7dacfba8c | ||
![]() |
2d7fffd4ec | ||
![]() |
f8baabbcec | ||
![]() |
716825f232 | ||
![]() |
58bd46750b | ||
![]() |
288240f163 | ||
![]() |
ff02452cb8 | ||
![]() |
462fbe2cad | ||
![]() |
7aeae93f3d | ||
![]() |
f1de9b39ef | ||
![]() |
db5b0ed7be | ||
![]() |
9f28a01c03 | ||
![]() |
80407b6102 | ||
![]() |
287841d806 | ||
![]() |
10c3be1195 | ||
![]() |
0c0e22013b | ||
![]() |
f35c8d4446 | ||
![]() |
17418d4b9c | ||
![]() |
ec1fbdf2ae | ||
![]() |
56e5a46fd5 | ||
![]() |
32e86d44a3 | ||
![]() |
7100606dfc | ||
![]() |
d7eb111460 | ||
![]() |
27ea46653e | ||
![]() |
12c43072cb | ||
![]() |
671aa6d507 | ||
![]() |
b697bbad2b | ||
![]() |
f05a404e48 | ||
![]() |
a46e948b5a | ||
![]() |
dc09ea639f | ||
![]() |
49ed096e85 | ||
![]() |
167bd83f4e | ||
![]() |
aed1eac315 | ||
![]() |
54a2f8f16f | ||
![]() |
2ca543ffb9 | ||
![]() |
58e7f815a5 | ||
![]() |
15b38fc841 | ||
![]() |
e2ca50729d | ||
![]() |
6192089b71 | ||
![]() |
a4212f6bf9 | ||
![]() |
124a2e9d3e | ||
![]() |
f77624b3b9 | ||
![]() |
a76ac04214 | ||
![]() |
0447fa9c28 | ||
![]() |
54ac1394a9 | ||
![]() |
0b04c73ac5 | ||
![]() |
079de45238 | ||
![]() |
56ce9ec2f9 | ||
![]() |
1b52e4b0f9 | ||
![]() |
098c2c1efa | ||
![]() |
64343e5a7c | ||
![]() |
0caf6caeb9 | ||
![]() |
55f6c2a9fc | ||
![]() |
c6095bc38a | ||
![]() |
09cd6aa568 | ||
![]() |
ebbaafb78e | ||
![]() |
e6de90d300 | ||
![]() |
c7922e90d0 | ||
![]() |
c1f4c0445a | ||
![]() |
caa634fac6 | ||
![]() |
f28bfe0dbd | ||
![]() |
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 | ||
![]() |
3f410bd39f | ||
![]() |
d51bc32e37 | ||
![]() |
b7f6aa94cc | ||
![]() |
ff965e6953 | ||
![]() |
468d5d7421 | ||
![]() |
fc95b28c49 | ||
![]() |
69184187d9 | ||
![]() |
a802d0df46 | ||
![]() |
8de30633ae | ||
![]() |
a1fbb7990f | ||
![]() |
aa71146b1b | ||
![]() |
9fdb8f087f | ||
![]() |
670f0153de | ||
![]() |
1d7aeca696 | ||
![]() |
4e7811ea07 | ||
![]() |
e11283744a | ||
![]() |
91cdfd53ef | ||
![]() |
bc7d6b9941 | ||
![]() |
6b1e0a1656 | ||
![]() |
72c9eb2129 | ||
![]() |
4bc4b0dc01 | ||
![]() |
637d48746f | ||
![]() |
9a109c129b | ||
![]() |
d49e4ee5ea | ||
![]() |
30f0ea29a3 | ||
![]() |
49930f6565 | ||
![]() |
909d89fa8d | ||
![]() |
81d1d7f544 | ||
![]() |
67b7dff67a | ||
![]() |
4b76d19596 | ||
![]() |
080fbe9feb | ||
![]() |
d3721229bf | ||
![]() |
86c1c9c772 | ||
![]() |
c299817193 |
3
.editorconfig
Normal file
3
.editorconfig
Normal file
@@ -0,0 +1,3 @@
|
||||
[*.{kt,kts}]
|
||||
ktlint_code_style = intellij_idea
|
||||
ktlint_standard_no-wildcard-imports = disabled
|
72
.github/ISSUE_TEMPLATE/bug-issue.yml
vendored
72
.github/ISSUE_TEMPLATE/bug-issue.yml
vendored
@@ -1,72 +0,0 @@
|
||||
name: 🐞 Bug report
|
||||
description: Report a very clearly broken issue.
|
||||
title: 'bug: <title>'
|
||||
labels: [bug]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
# ReVanced bug report
|
||||
|
||||
Important to note that your issue may have already been reported before. Please check for existing issues [here](https://github.com/revanced/revanced-patcher/labels/bug).
|
||||
|
||||
- type: dropdown
|
||||
attributes:
|
||||
label: Type
|
||||
options:
|
||||
- Crash
|
||||
- Cosmetic
|
||||
- Other
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Bug description
|
||||
description: How did you find the bug? Any additional details that might help?
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Steps to reproduce
|
||||
description: Add the steps to reproduce this bug including your environment.
|
||||
placeholder: Step 1. Download some files. Step 2. ...
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Relevant log output
|
||||
description: Please copy and paste any relevant log output. This will be automatically formatted into code, so no need for backticks.
|
||||
render: shell
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Screenshots or videos
|
||||
description: Add screenshots or videos that show the bug here.
|
||||
placeholder: Drag and drop the screenshots/videos into this box.
|
||||
validations:
|
||||
required: false
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Solution
|
||||
description: If applicable, add a possible solution.
|
||||
validations:
|
||||
required: false
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Additional context
|
||||
description: Add additional context here.
|
||||
validations:
|
||||
required: false
|
||||
- type: checkboxes
|
||||
id: acknowledgements
|
||||
attributes:
|
||||
label: Acknowledgements
|
||||
description: Your issue will be closed if you haven't done these steps.
|
||||
options:
|
||||
- label: I have searched the existing issues and this is a new and no duplicate or related to another open issue.
|
||||
required: true
|
||||
- label: I have written a short but informative title.
|
||||
required: true
|
||||
- label: I filled out all of the requested information in this issue properly.
|
||||
required: true
|
108
.github/ISSUE_TEMPLATE/bug-report.yml
vendored
Normal file
108
.github/ISSUE_TEMPLATE/bug-report.yml
vendored
Normal file
@@ -0,0 +1,108 @@
|
||||
name: 🐞 Bug report
|
||||
description: Report a bug or an issue.
|
||||
title: 'bug: '
|
||||
labels: ['Bug report']
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
<p align="center">
|
||||
<picture>
|
||||
<source
|
||||
width="256px"
|
||||
media="(prefers-color-scheme: dark)"
|
||||
srcset="https://raw.githubusercontent.com/revanced/revanced-patcher/main/assets/revanced-headline/revanced-headline-vertical-dark.svg"
|
||||
>
|
||||
<img
|
||||
width="256px"
|
||||
src="https://raw.githubusercontent.com/revanced/revanced-patcher/main/assets/revanced-headline/revanced-headline-vertical-light.svg"
|
||||
>
|
||||
</picture>
|
||||
<br>
|
||||
<a href="https://revanced.app/">
|
||||
<picture>
|
||||
<source height="24px" media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/revanced/revanced-patcher/main/assets/revanced-logo/revanced-logo.svg" />
|
||||
<img height="24px" src="https://raw.githubusercontent.com/revanced/revanced-patcher/main/assets/revanced-logo/revanced-logo.svg" />
|
||||
</picture>
|
||||
</a>
|
||||
<a href="https://github.com/ReVanced">
|
||||
<picture>
|
||||
<source height="24px" media="(prefers-color-scheme: dark)" srcset="https://i.ibb.co/dMMmCrW/Git-Hub-Mark.png" />
|
||||
<img height="24px" src="https://i.ibb.co/9wV3HGF/Git-Hub-Mark-Light.png" />
|
||||
</picture>
|
||||
</a>
|
||||
<a href="http://revanced.app/discord">
|
||||
<picture>
|
||||
<source height="24px" media="(prefers-color-scheme: dark)" srcset="https://user-images.githubusercontent.com/13122796/178032563-d4e084b7-244e-4358-af50-26bde6dd4996.png" />
|
||||
<img height="24px" src="https://user-images.githubusercontent.com/13122796/178032563-d4e084b7-244e-4358-af50-26bde6dd4996.png" />
|
||||
</picture>
|
||||
</a>
|
||||
<a href="https://reddit.com/r/revancedapp">
|
||||
<picture>
|
||||
<source height="24px" media="(prefers-color-scheme: dark)" srcset="https://user-images.githubusercontent.com/13122796/178032351-9d9d5619-8ef7-470a-9eec-2744ece54553.png" />
|
||||
<img height="24px" src="https://user-images.githubusercontent.com/13122796/178032351-9d9d5619-8ef7-470a-9eec-2744ece54553.png" />
|
||||
</picture>
|
||||
</a>
|
||||
<a href="https://t.me/app_revanced">
|
||||
<picture>
|
||||
<source height="24px" media="(prefers-color-scheme: dark)" srcset="https://user-images.githubusercontent.com/13122796/178032213-faf25ab8-0bc3-4a94-a730-b524c96df124.png" />
|
||||
<img height="24px" src="https://user-images.githubusercontent.com/13122796/178032213-faf25ab8-0bc3-4a94-a730-b524c96df124.png" />
|
||||
</picture>
|
||||
</a>
|
||||
<a href="https://x.com/revancedapp">
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: dark)" srcset="https://user-images.githubusercontent.com/93124920/270180600-7c1b38bf-889b-4d68-bd5e-b9d86f91421a.png">
|
||||
<img height="24px" src="https://user-images.githubusercontent.com/93124920/270108715-d80743fa-b330-4809-b1e6-79fbdc60d09c.png" />
|
||||
</picture>
|
||||
</a>
|
||||
<a href="https://www.youtube.com/@ReVanced">
|
||||
<picture>
|
||||
<source height="24px" media="(prefers-color-scheme: dark)" srcset="https://user-images.githubusercontent.com/13122796/178032714-c51c7492-0666-44ac-99c2-f003a695ab50.png" />
|
||||
<img height="24px" src="https://user-images.githubusercontent.com/13122796/178032714-c51c7492-0666-44ac-99c2-f003a695ab50.png" />
|
||||
</picture>
|
||||
</a>
|
||||
<br>
|
||||
<br>
|
||||
Continuing the legacy of Vanced
|
||||
</p>
|
||||
|
||||
# ReVanced Patcher bug report
|
||||
|
||||
Before creating a new bug report, please keep the following in mind:
|
||||
|
||||
- **Do not submit a duplicate bug report**: You can review existing bug reports [here](https://github.com/ReVanced/revanced-patcher/labels/Bug%20report).
|
||||
- **Do not use the issue page for support**: If you need help or have questions, check out other platforms on [revanced.app](https://revanced.app).
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Bug description
|
||||
description: |
|
||||
- Describe your bug in detail
|
||||
- Add steps to reproduce the bug if possible (Step 1. ... Step 2. ...)
|
||||
- Add images and videos if possible
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Error logs
|
||||
description: Exceptions can be captured by running `logcat | grep AndroidRuntime` in a shell.
|
||||
render: shell
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Solution
|
||||
description: If applicable, add a possible solution to the bug.
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Additional context
|
||||
description: Add additional context here.
|
||||
- type: checkboxes
|
||||
id: acknowledgements
|
||||
attributes:
|
||||
label: Acknowledgements
|
||||
description: Your bug report will be closed if you don't follow the checklist below.
|
||||
options:
|
||||
- label: This issue is not a duplicate of an existing bug report.
|
||||
required: true
|
||||
- label: I have chosen an appropriate title.
|
||||
required: true
|
||||
- label: All requested information has been provided properly.
|
||||
required: true
|
58
.github/ISSUE_TEMPLATE/feature-issue.yml
vendored
58
.github/ISSUE_TEMPLATE/feature-issue.yml
vendored
@@ -1,58 +0,0 @@
|
||||
name: ⭐ Feature request
|
||||
description: Create a detailed feature request.
|
||||
title: 'feat: <title>'
|
||||
labels: [feature-request]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
# ReVanced feature request
|
||||
|
||||
Do not submit requests for patches here. Please submit them [here](https://github.com/orgs/revanced/discussions/categories/patches) instead.
|
||||
Important to note that your feature request may have already been made before. Please check for existing feature requests [here](https://github.com/revanced/revanced-patcher/labels/feature-request).
|
||||
|
||||
- type: dropdown
|
||||
attributes:
|
||||
label: Type
|
||||
options:
|
||||
- Functionality
|
||||
- Cosmetic
|
||||
- Other
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Issue
|
||||
description: What is the current problem. Why does it require a feature request?
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Feature
|
||||
description: Describe your feature in detail. How does it solve the issue?
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Motivation
|
||||
description: Why should your feature should be considered?
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Additional context
|
||||
description: Add additional context here.
|
||||
validations:
|
||||
required: false
|
||||
- type: checkboxes
|
||||
id: acknowledgements
|
||||
attributes:
|
||||
label: Acknowledgements
|
||||
description: Your issue will be closed if you haven't done these steps.
|
||||
options:
|
||||
- label: I have searched the existing issues and this is a new and no duplicate or related to another open issue.
|
||||
required: true
|
||||
- label: I have written a short but informative title.
|
||||
required: true
|
||||
- label: I filled out all of the requested information in this issue properly.
|
||||
required: true
|
106
.github/ISSUE_TEMPLATE/feature-request.yml
vendored
Normal file
106
.github/ISSUE_TEMPLATE/feature-request.yml
vendored
Normal file
@@ -0,0 +1,106 @@
|
||||
name: ⭐ Feature request
|
||||
description: Create a detailed request for a new feature.
|
||||
title: 'feat: '
|
||||
labels: ['Feature request']
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
<p align="center">
|
||||
<picture>
|
||||
<source
|
||||
width="256px"
|
||||
media="(prefers-color-scheme: dark)"
|
||||
srcset="https://raw.githubusercontent.com/revanced/revanced-patcher/main/assets/revanced-headline/revanced-headline-vertical-dark.svg"
|
||||
>
|
||||
<img
|
||||
width="256px"
|
||||
src="https://raw.githubusercontent.com/revanced/revanced-patcher/main/assets/revanced-headline/revanced-headline-vertical-light.svg"
|
||||
>
|
||||
</picture>
|
||||
<br>
|
||||
<a href="https://revanced.app/">
|
||||
<picture>
|
||||
<source height="24px" media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/revanced/revanced-patcher/main/assets/revanced-logo/revanced-logo.svg" />
|
||||
<img height="24px" src="https://raw.githubusercontent.com/revanced/revanced-patcher/main/assets/revanced-logo/revanced-logo.svg" />
|
||||
</picture>
|
||||
</a>
|
||||
<a href="https://github.com/ReVanced">
|
||||
<picture>
|
||||
<source height="24px" media="(prefers-color-scheme: dark)" srcset="https://i.ibb.co/dMMmCrW/Git-Hub-Mark.png" />
|
||||
<img height="24px" src="https://i.ibb.co/9wV3HGF/Git-Hub-Mark-Light.png" />
|
||||
</picture>
|
||||
</a>
|
||||
<a href="http://revanced.app/discord">
|
||||
<picture>
|
||||
<source height="24px" media="(prefers-color-scheme: dark)" srcset="https://user-images.githubusercontent.com/13122796/178032563-d4e084b7-244e-4358-af50-26bde6dd4996.png" />
|
||||
<img height="24px" src="https://user-images.githubusercontent.com/13122796/178032563-d4e084b7-244e-4358-af50-26bde6dd4996.png" />
|
||||
</picture>
|
||||
</a>
|
||||
<a href="https://reddit.com/r/revancedapp">
|
||||
<picture>
|
||||
<source height="24px" media="(prefers-color-scheme: dark)" srcset="https://user-images.githubusercontent.com/13122796/178032351-9d9d5619-8ef7-470a-9eec-2744ece54553.png" />
|
||||
<img height="24px" src="https://user-images.githubusercontent.com/13122796/178032351-9d9d5619-8ef7-470a-9eec-2744ece54553.png" />
|
||||
</picture>
|
||||
</a>
|
||||
<a href="https://t.me/app_revanced">
|
||||
<picture>
|
||||
<source height="24px" media="(prefers-color-scheme: dark)" srcset="https://user-images.githubusercontent.com/13122796/178032213-faf25ab8-0bc3-4a94-a730-b524c96df124.png" />
|
||||
<img height="24px" src="https://user-images.githubusercontent.com/13122796/178032213-faf25ab8-0bc3-4a94-a730-b524c96df124.png" />
|
||||
</picture>
|
||||
</a>
|
||||
<a href="https://x.com/revancedapp">
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: dark)" srcset="https://user-images.githubusercontent.com/93124920/270180600-7c1b38bf-889b-4d68-bd5e-b9d86f91421a.png">
|
||||
<img height="24px" src="https://user-images.githubusercontent.com/93124920/270108715-d80743fa-b330-4809-b1e6-79fbdc60d09c.png" />
|
||||
</picture>
|
||||
</a>
|
||||
<a href="https://www.youtube.com/@ReVanced">
|
||||
<picture>
|
||||
<source height="24px" media="(prefers-color-scheme: dark)" srcset="https://user-images.githubusercontent.com/13122796/178032714-c51c7492-0666-44ac-99c2-f003a695ab50.png" />
|
||||
<img height="24px" src="https://user-images.githubusercontent.com/13122796/178032714-c51c7492-0666-44ac-99c2-f003a695ab50.png" />
|
||||
</picture>
|
||||
</a>
|
||||
<br>
|
||||
<br>
|
||||
Continuing the legacy of Vanced
|
||||
</p>
|
||||
|
||||
# ReVanced Patcher feature request
|
||||
|
||||
Before creating a new feature request, please keep the following in mind:
|
||||
|
||||
- **Do not submit a duplicate feature request**: You can review existing feature requests [here](https://github.com/ReVanced/revanced-patcher/labels/Feature%20request).
|
||||
- **Do not use the issue page for support**: If you need help or have questions, check out other platforms on [revanced.app](https://revanced.app).
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Feature description
|
||||
description: |
|
||||
- Describe your feature in detail
|
||||
- Add images, videos, links, examples, references, etc. if possible
|
||||
- Add the target application name in case you request a new patch
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Motivation
|
||||
description: |
|
||||
A strong motivation is necessary for a feature request to be considered.
|
||||
|
||||
- Why should this feature be implemented?
|
||||
- What is the explicit use case?
|
||||
- What are the benefits?
|
||||
- What makes this feature important?
|
||||
validations:
|
||||
required: true
|
||||
- type: checkboxes
|
||||
id: acknowledgements
|
||||
attributes:
|
||||
label: Acknowledgements
|
||||
description: Your feature request will be closed if you don't follow the checklist below.
|
||||
options:
|
||||
- label: This issue is not a duplicate of an existing feature request.
|
||||
required: true
|
||||
- label: I have chosen an appropriate title.
|
||||
required: true
|
||||
- label: All requested information has been provided properly.
|
||||
required: true
|
2
.github/config.yml
vendored
2
.github/config.yml
vendored
@@ -1,2 +1,2 @@
|
||||
firstPRMergeComment: >
|
||||
Thank you for contributing to ReVanced. Join us on [Discord](https://revanced.app/discord) if you want to receive a contributor role.
|
||||
Thank you for contributing to ReVanced. Join us on [Discord](https://revanced.app/discord) to receive a role for your contribution.
|
||||
|
22
.github/dependabot.yml
vendored
Normal file
22
.github/dependabot.yml
vendored
Normal 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
|
7
.github/workflows/pull_request.yml
vendored
7
.github/workflows/pull_request.yml
vendored
@@ -1,4 +1,4 @@
|
||||
name: PR to main
|
||||
name: Open a PR to main
|
||||
|
||||
on:
|
||||
push:
|
||||
@@ -7,7 +7,7 @@ on:
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
MESSAGE: merge branch `${{ github.head_ref || github.ref_name }}` to `main`
|
||||
MESSAGE: Merge branch `${{ github.head_ref || github.ref_name }}` to `main`
|
||||
|
||||
jobs:
|
||||
pull-request:
|
||||
@@ -15,7 +15,8 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Open pull request
|
||||
uses: repo-sync/pull-request@v2
|
||||
with:
|
||||
|
35
.github/workflows/release.yml
vendored
35
.github/workflows/release.yml
vendored
@@ -17,28 +17,37 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
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
|
||||
uses: actions/cache@v3
|
||||
|
||||
- name: Import GPG key
|
||||
uses: crazy-max/ghaction-import-gpg@v6
|
||||
with:
|
||||
path: |
|
||||
${{ runner.home }}/.gradle/caches
|
||||
${{ runner.home }}/.gradle/wrapper
|
||||
.gradle
|
||||
build
|
||||
node_modules
|
||||
key: ${{ runner.os }}-gradle-npm-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties', 'package-lock.json') }}
|
||||
- name: Build with Gradle
|
||||
gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }}
|
||||
passphrase: ${{ secrets.PASSPHRASE }}
|
||||
fingerprint: ${{ env.GPG_FINGERPRINT }}
|
||||
|
||||
- name: Cache Gradle
|
||||
uses: burrunan/gradle-cache-action@v1
|
||||
|
||||
- name: Build
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: ./gradlew build clean --no-daemon
|
||||
- name: Setup semantic-release
|
||||
run: ./gradlew build clean
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: "lts/*"
|
||||
cache: 'npm'
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm install
|
||||
|
||||
- name: Release
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.REPOSITORY_PUSH_ACCESS }}
|
||||
|
441
CHANGELOG.md
441
CHANGELOG.md
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 11 KiB |
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 11 KiB |
1
assets/revanced-logo/revanced-logo.svg
Normal file
1
assets/revanced-logo/revanced-logo.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 2.8 KiB |
@@ -1,4 +1,95 @@
|
||||
plugins {
|
||||
kotlin("jvm") version "1.9.0" apply false
|
||||
alias(libs.plugins.kotlin)
|
||||
alias(libs.plugins.binary.compatibility.validator)
|
||||
`maven-publish`
|
||||
signing
|
||||
java
|
||||
}
|
||||
|
||||
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)
|
||||
|
||||
// TODO: Convert project to KMP.
|
||||
compileOnly(libs.android) {
|
||||
// Exclude, otherwise the org.w3c.dom API breaks.
|
||||
exclude(group = "xerces", module = "xmlParserAPIs")
|
||||
}
|
||||
|
||||
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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
signing {
|
||||
useGpgCmd()
|
||||
sign(publishing.publications["revanced-patcher-publication"])
|
||||
}
|
||||
|
@@ -1,4 +1,3 @@
|
||||
org.gradle.parallel = true
|
||||
org.gradle.caching = true
|
||||
kotlin.code.style = official
|
||||
version = 15.0.0-dev.1
|
||||
version = 19.3.0-dev.2
|
||||
|
@@ -1,31 +1,23 @@
|
||||
[versions]
|
||||
android = "4.1.1.4"
|
||||
kotlin-reflect = "1.9.0"
|
||||
apktool-lib = "2.8.2-6"
|
||||
kotlin-test = "1.8.20-RC"
|
||||
kotlinx-coroutines-core = "1.7.1"
|
||||
multidexlib2 = "3.0.3.r2"
|
||||
smali = "3.0.3"
|
||||
symbol-processing-api = "1.9.0-1.0.11"
|
||||
xpp3 = "1.1.4c"
|
||||
apktool-lib = "2.9.1"
|
||||
kotlin = "1.9.22"
|
||||
kotlinx-coroutines-core = "1.7.3"
|
||||
multidexlib2 = "3.0.3.r3"
|
||||
smali = "3.0.4"
|
||||
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"
|
||||
xpp3 = "1.1.4c"
|
||||
|
||||
[libraries]
|
||||
android = { module = "com.google.android:android", version.ref = "android" }
|
||||
kotlin-reflect = { module = "org.jetbrains.kotlin:kotlin-reflect", version.ref = "kotlin-reflect" }
|
||||
apktool-lib = { module = "app.revanced:apktool-lib", version.ref = "apktool-lib" }
|
||||
kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlin-test" }
|
||||
kotlin-reflect = { module = "org.jetbrains.kotlin:kotlin-reflect", version.ref = "kotlin" }
|
||||
apktool-lib = { module = "app.revanced:apktool", version.ref = "apktool-lib" }
|
||||
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" }
|
||||
multidexlib2 = { module = "app.revanced:multidexlib2", version.ref = "multidexlib2" }
|
||||
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" }
|
||||
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]
|
||||
binary-compatibility-validator = { id = "org.jetbrains.kotlinx.binary-compatibility-validator", version.ref = "binary-compatibility-validator" }
|
||||
ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" }
|
||||
kotlin = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" }
|
7
gradle/wrapper/gradle-wrapper.properties
vendored
7
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,7 +1,6 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip
|
||||
distributionSha256Sum=3e1af3ae886920c3ac87f7a91f816c0c7c436f276a6eefdb3da152100fef72ae
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
zipStorePath=wrapper/dist
|
5199
package-lock.json
generated
5199
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -1,9 +1,9 @@
|
||||
{
|
||||
"devDependencies": {
|
||||
"@saithodev/semantic-release-backmerge": "^3.1.0",
|
||||
"@semantic-release/changelog": "^6.0.2",
|
||||
"@saithodev/semantic-release-backmerge": "^4.0.1",
|
||||
"@semantic-release/changelog": "^6.0.3",
|
||||
"@semantic-release/git": "^10.0.1",
|
||||
"gradle-semantic-release-plugin": "^1.7.6",
|
||||
"semantic-release": "^20.1.0"
|
||||
"gradle-semantic-release-plugin": "^1.9.1",
|
||||
"semantic-release": "^23.0.0"
|
||||
}
|
||||
}
|
||||
|
@@ -1,25 +0,0 @@
|
||||
public abstract interface annotation class app/revanced/patcher/patch/annotations/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/annotations/Patch : java/lang/annotation/Annotation {
|
||||
public abstract fun compatiblePackages ()[Lapp/revanced/patcher/patch/annotations/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/annotations/processor/PatchProcessor : com/google/devtools/ksp/processing/SymbolProcessor {
|
||||
public fun <init> (Lcom/google/devtools/ksp/processing/CodeGenerator;Lcom/google/devtools/ksp/processing/KSPLogger;)V
|
||||
public fun process (Lcom/google/devtools/ksp/processing/Resolver;)Ljava/util/List;
|
||||
}
|
||||
|
||||
public final class app/revanced/patcher/patch/annotations/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/annotations/processor/PatchProcessor;
|
||||
public synthetic fun create (Lcom/google/devtools/ksp/processing/SymbolProcessorEnvironment;)Lcom/google/devtools/ksp/processing/SymbolProcessor;
|
||||
}
|
||||
|
@@ -1,50 +0,0 @@
|
||||
plugins {
|
||||
kotlin("jvm") version "1.9.0"
|
||||
`maven-publish`
|
||||
alias(libs.plugins.ksp)
|
||||
}
|
||||
|
||||
group = "app.revanced"
|
||||
|
||||
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-patch-annotations-processor")
|
||||
credentials {
|
||||
username = System.getenv("GITHUB_ACTOR")
|
||||
password = System.getenv("GITHUB_TOKEN")
|
||||
}
|
||||
}
|
||||
}
|
||||
publications {
|
||||
create<MavenPublication>("gpr") {
|
||||
from(components["java"])
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,2 +0,0 @@
|
||||
rootProject.name = "revanced-patch-annotations-processor"
|
||||
|
@@ -1,198 +0,0 @@
|
||||
package app.revanced.patcher.patch.annotations.processor
|
||||
|
||||
import app.revanced.patcher.data.BytecodeContext
|
||||
import app.revanced.patcher.data.ResourceContext
|
||||
import app.revanced.patcher.patch.BytecodePatch
|
||||
import app.revanced.patcher.patch.PatchOptions
|
||||
import app.revanced.patcher.patch.ResourcePatch
|
||||
import app.revanced.patcher.patch.annotations.Patch
|
||||
import com.google.devtools.ksp.processing.*
|
||||
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(
|
||||
private val codeGenerator: CodeGenerator,
|
||||
private val logger: KSPLogger
|
||||
) : 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 executablePatches = 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>)
|
||||
.joinToString(", ") { version -> "\"$version\"" }
|
||||
|
||||
CodeBlock.of(
|
||||
"%T(%S, setOf(%L))",
|
||||
app.revanced.patcher.patch.Patch.CompatiblePackage::class,
|
||||
packageName,
|
||||
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,
|
||||
// unlike the annotated patch.
|
||||
val dependencyResolutionMap = buildMap {
|
||||
executablePatches.values.filter { it.dependencies != null }.flatMap {
|
||||
it.dependencies!!
|
||||
}.distinct().forEach { dependency ->
|
||||
executablePatches.keys.find { it.qualifiedName?.asString() == dependency.toString() }
|
||||
?.let { patch ->
|
||||
this[dependency] = ClassName(
|
||||
patch.packageName.asString(),
|
||||
patch.simpleName.asString() + "Generated"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// kotlin poet generate a class for each patch
|
||||
executablePatches.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(", ")
|
||||
)
|
||||
}
|
||||
|
||||
patchAnnotation.dependencies?.let { dependencies ->
|
||||
addSuperclassConstructorParameter(
|
||||
"dependencies = setOf(%L)",
|
||||
buildList {
|
||||
addAll(dependencies)
|
||||
// Also add the source class of the generated class so that it is also executed
|
||||
add(patchDeclaration.toClassName())
|
||||
}.joinToString(", ") { dependency ->
|
||||
"${(dependencyResolutionMap[dependency] ?: dependency)}::class"
|
||||
}
|
||||
)
|
||||
}
|
||||
addSuperclassConstructorParameter(
|
||||
"use = %L", patchAnnotation.use
|
||||
)
|
||||
|
||||
addSuperclassConstructorParameter(
|
||||
"requiresIntegrations = %L",
|
||||
patchAnnotation.requiresIntegrations
|
||||
)
|
||||
}
|
||||
.addFunction(
|
||||
FunSpec.builder("execute")
|
||||
.addModifiers(KModifier.OVERRIDE)
|
||||
.addParameter("context", contextClass)
|
||||
.build()
|
||||
)
|
||||
.addProperty(
|
||||
PropertySpec.builder("options", PatchOptions::class, KModifier.OVERRIDE)
|
||||
.initializer("%T.options", patchDeclaration.toClassName())
|
||||
.build()
|
||||
)
|
||||
.build()
|
||||
).build().writeTo(
|
||||
codeGenerator,
|
||||
Dependencies(false, patchDeclaration.containingFile!!)
|
||||
)
|
||||
}
|
||||
|
||||
return emptyList()
|
||||
}
|
||||
}
|
@@ -1,9 +0,0 @@
|
||||
package app.revanced.patcher.patch.annotations.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, environment.logger)
|
||||
}
|
@@ -1 +0,0 @@
|
||||
app.revanced.patcher.patch.annotations.processor.PatchProcessorProvider
|
@@ -1,131 +0,0 @@
|
||||
package app.revanced.patcher.patch.annotations.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.assertNotNull
|
||||
import kotlin.test.assertNull
|
||||
|
||||
class TestPatchAnnotationProcessor {
|
||||
// region Processing
|
||||
|
||||
@Test
|
||||
fun testProcessing() = assertEquals(
|
||||
"Processable patch", compile(
|
||||
getSourceFile(
|
||||
"processing", "ProcessablePatch"
|
||||
)
|
||||
).loadPatch("$SAMPLE_PACKAGE.processing.ProcessablePatchGenerated").name
|
||||
)
|
||||
|
||||
// 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")
|
||||
|
||||
assertNotNull(patch.options)
|
||||
assertEquals(patch.options["print"].title, "Print message")
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region Limitations
|
||||
@Test
|
||||
fun failingManualDependency() = assertNull(
|
||||
compile(
|
||||
getSourceFile(
|
||||
"limitations/manualdependency", "DependentPatch"
|
||||
), getSourceFile(
|
||||
"limitations/manualdependency", "DependencyPatch"
|
||||
)
|
||||
).loadPatch("$SAMPLE_PACKAGE.limitations.manualdependency.DependentPatchGenerated").dependencies
|
||||
)
|
||||
|
||||
// endregion
|
||||
|
||||
private companion object Utils {
|
||||
const val SAMPLE_PACKAGE = "app.revanced.patcher.patch.annotations.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.kotlin(
|
||||
"$className.kt", TestPatchAnnotationProcessor::class.java.classLoader.getResourceAsStream(
|
||||
"app/revanced/patcher/patch/annotations/processor/samples/$sample/$className.kt"
|
||||
)?.readAllBytes()?.toString(Charsets.UTF_8) ?: error("Could not find resource $className")
|
||||
)
|
||||
|
||||
/**
|
||||
* 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.annotations.processor.samples.dependencies
|
||||
|
||||
import app.revanced.patcher.data.ResourceContext
|
||||
import app.revanced.patcher.patch.ResourcePatch
|
||||
import app.revanced.patcher.patch.annotations.Patch
|
||||
|
||||
@Patch(name = "Dependency patch")
|
||||
object DependencyPatch : ResourcePatch() {
|
||||
override fun execute(context: ResourceContext) {}
|
||||
}
|
@@ -1,12 +0,0 @@
|
||||
package app.revanced.patcher.patch.annotations.processor.samples.dependencies
|
||||
import app.revanced.patcher.data.BytecodeContext
|
||||
import app.revanced.patcher.patch.BytecodePatch
|
||||
import app.revanced.patcher.patch.annotations.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.annotations.processor.samples.limitations.manualdependency
|
||||
|
||||
import app.revanced.patcher.data.ResourceContext
|
||||
import app.revanced.patcher.patch.ResourcePatch
|
||||
import app.revanced.patcher.patch.annotations.Patch
|
||||
|
||||
@Patch(name = "Dependency patch")
|
||||
object DependencyPatch : ResourcePatch() {
|
||||
override fun execute(context: ResourceContext) { }
|
||||
}
|
@@ -1,17 +0,0 @@
|
||||
package app.revanced.patcher.patch.annotations.processor.samples.limitations.manualdependency
|
||||
import app.revanced.patcher.data.BytecodeContext
|
||||
import app.revanced.patcher.patch.BytecodePatch
|
||||
import app.revanced.patcher.patch.annotations.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,21 +0,0 @@
|
||||
package app.revanced.patcher.patch.annotations.processor.samples.options
|
||||
|
||||
import app.revanced.patcher.data.ResourceContext
|
||||
import app.revanced.patcher.patch.PatchOption
|
||||
import app.revanced.patcher.patch.ResourcePatch
|
||||
import app.revanced.patcher.patch.annotations.Patch
|
||||
|
||||
@Patch(name = "Options patch")
|
||||
object OptionsPatch : ResourcePatch() {
|
||||
override fun execute(context: ResourceContext) {}
|
||||
|
||||
@Suppress("unused")
|
||||
private val printOption by option(
|
||||
PatchOption.StringOption(
|
||||
"print",
|
||||
null,
|
||||
"Print message",
|
||||
"The message to print."
|
||||
)
|
||||
)
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user