Compare commits

..

180 Commits

Author SHA1 Message Date
semantic-release-bot
a0189aeaee chore: Release v5.0.1 [skip ci]
## [5.0.1](https://github.com/ReVanced/revanced-cli/compare/v5.0.0...v5.0.1) (2025-04-14)

### Bug Fixes

* Make mounting work again by bumping dependencies ([#359](https://github.com/ReVanced/revanced-cli/issues/359)) ([68a4872](68a48724eb))
2025-04-14 08:53:31 +00:00
oSumAtrIX
19e8422588
chore: Merge branch dev to main (#354)
Co-authored-by: kitadai31 <90122968+kitadai31@users.noreply.github.com>
Co-authored-by: Jamie McCullough <92225779+AoifeMcCull@users.noreply.github.com>
Co-authored-by: semantic-release-bot <semantic-release-bot@martynus.net>
2025-04-14 10:51:31 +02:00
semantic-release-bot
d908595b22 chore: Release v5.0.1-dev.1 [skip ci]
## [5.0.1-dev.1](https://github.com/ReVanced/revanced-cli/compare/v5.0.0...v5.0.1-dev.1) (2025-02-26)

### Bug Fixes

* Make mounting work again by bumping dependencies ([#359](https://github.com/ReVanced/revanced-cli/issues/359)) ([68a4872](68a48724eb))
2025-02-26 21:52:52 +00:00
Jamie McCullough
68a48724eb
fix: Make mounting work again by bumping dependencies (#359) 2025-02-26 22:50:58 +01:00
kitadai31
bf31de4148
build: Remove AAPT1 binary & minimize ReVanced Library (#340) 2024-12-24 01:52:44 +01:00
semantic-release-bot
63b6350afc chore: Release v5.0.0 [skip ci]
# [5.0.0](https://github.com/ReVanced/revanced-cli/compare/v4.6.0...v5.0.0) (2024-11-10)

### Bug Fixes

* Check for null when no device serial was specified ([1da8ae9](1da8ae9e46))
* List if patch option is required ([#346](https://github.com/ReVanced/revanced-cli/issues/346)) ([98ff0c3](98ff0c34fa))
* Make CLI ArgGroup non-exclusive to be able to disable and enable patches at the same time ([1bb0d13](1bb0d13726))
* Make patches selectable by using a mutable collection for the selection option ([751fa1d](751fa1d889))
* Make the patch command work without specifying any selection ([ba159a3](ba159a35a9))
* Print in new line correctly ([c2dc9d7](c2dc9d76be))
* Use the first connected device when no ADB device is specified ([5f952f3](5f952f35f5))

### Features

* Set patch options via CLI ([#336](https://github.com/ReVanced/revanced-cli/issues/336)) ([2300243](23002434b2))
* Show error about no installation device found at the beginning ([3300e6b](3300e6b433))
* Simplify command and option names and descriptions ([#338](https://github.com/ReVanced/revanced-cli/issues/338)) ([6e7797a](6e7797a3f0))
* Simplify option descriptions ([45c998b](45c998b335))

### BREAKING CHANGES

* Options have been renamed.
* This commit changes various CLI options and removes the `options.json` file. Instead, patch options can now be passed via CLI options
2024-11-10 14:57:43 +00:00
oSumAtrIX
5d8beae7be
chore: Merge branch dev to main (#328) 2024-11-10 15:55:48 +01:00
semantic-release-bot
dbbc00706d chore: Release v5.0.0-dev.11 [skip ci]
# [5.0.0-dev.11](https://github.com/ReVanced/revanced-cli/compare/v5.0.0-dev.10...v5.0.0-dev.11) (2024-11-10)

### Bug Fixes

* List if patch option is required ([#346](https://github.com/ReVanced/revanced-cli/issues/346)) ([98ff0c3](98ff0c34fa))
2024-11-10 14:49:46 +00:00
decipher
98ff0c34fa
fix: List if patch option is required (#346) 2024-11-10 15:47:55 +01:00
semantic-release-bot
77be717de0 chore: Release v5.0.0-dev.10 [skip ci]
# [5.0.0-dev.10](https://github.com/ReVanced/revanced-cli/compare/v5.0.0-dev.9...v5.0.0-dev.10) (2024-11-05)

### Bug Fixes

* Make CLI ArgGroup non-exclusive to be able to disable and enable patches at the same time ([1bb0d13](1bb0d13726))
2024-11-05 19:01:23 +00:00
oSumAtrIX
1bb0d13726
fix: Make CLI ArgGroup non-exclusive to be able to disable and enable patches at the same time 2024-11-05 19:59:09 +01:00
oSumAtrIX
18e56e6ff4
build(Needs bump): Bump dependencies 2024-11-05 19:58:21 +01:00
semantic-release-bot
94b9e2bc6c chore: Release v5.0.0-dev.9 [skip ci]
# [5.0.0-dev.9](https://github.com/ReVanced/revanced-cli/compare/v5.0.0-dev.8...v5.0.0-dev.9) (2024-11-05)

### Bug Fixes

* Print in new line correctly ([c2dc9d7](c2dc9d76be))
2024-11-05 15:55:05 +00:00
oSumAtrIX
c2dc9d76be
fix: Print in new line correctly 2024-11-05 16:53:03 +01:00
oSumAtrIX
3d0c8c1526
chore: Remove unused variable 2024-10-27 05:13:31 +01:00
oSumAtrIX
b54308b0e2
docs: Fix spelling mistakes [skip ci] 2024-10-23 21:08:49 +02:00
semantic-release-bot
504c6c1ea5 chore: Release v5.0.0-dev.8 [skip ci]
# [5.0.0-dev.8](https://github.com/ReVanced/revanced-cli/compare/v5.0.0-dev.7...v5.0.0-dev.8) (2024-10-17)
2024-10-17 18:06:32 +00:00
oSumAtrIX
f58b101636
build(Needs bump): Bump ReVanced Patcher 2024-10-17 20:02:26 +02:00
cyberboh
292b93b609
docs: Use correct option name in command example (#342) 2024-10-16 15:27:58 +02:00
semantic-release-bot
e60a61b098 chore: Release v5.0.0-dev.7 [skip ci]
# [5.0.0-dev.7](https://github.com/ReVanced/revanced-cli/compare/v5.0.0-dev.6...v5.0.0-dev.7) (2024-10-16)

### Bug Fixes

* Check for null when no device serial was specified ([1da8ae9](1da8ae9e46))
2024-10-16 02:57:57 +00:00
oSumAtrIX
1da8ae9e46
fix: Check for null when no device serial was specified 2024-10-16 04:55:52 +02:00
semantic-release-bot
a9f2538827 chore: Release v5.0.0-dev.6 [skip ci]
# [5.0.0-dev.6](https://github.com/ReVanced/revanced-cli/compare/v5.0.0-dev.5...v5.0.0-dev.6) (2024-10-10)

### Bug Fixes

* Use the first connected device when no ADB device is specified ([5f952f3](5f952f35f5))
2024-10-10 21:05:17 +00:00
oSumAtrIX
5f952f35f5
fix: Use the first connected device when no ADB device is specified 2024-10-10 23:03:20 +02:00
oSumAtrIX
280ded2281
ci: Adjust release commit message 2024-10-01 17:30:15 +02:00
semantic-release-bot
bb6bc1ba9a chore: Release 5.0.0-dev.5 [skip ci]
# [5.0.0-dev.5](https://github.com/ReVanced/revanced-cli/compare/v5.0.0-dev.4...v5.0.0-dev.5) (2024-09-30)
2024-09-30 20:27:43 +00:00
oSumAtrIX
04b178b701
build(Needs bump): Update dependencies 2024-09-30 22:25:06 +02:00
oSumAtrIX
32e6aae132
ci: Adjust release commit message 2024-09-30 22:24:40 +02:00
oSumAtrIX
7ee4f15ab9
ci: Use permissions and regular GitHub token instead of PAT 2024-09-30 22:24:18 +02:00
oSumAtrIX
a7af611ef0
docs: Use correct option keys in command examples [skip ci] 2024-09-21 23:08:32 +02:00
semantic-release-bot
9440dc769e chore(release): 5.0.0-dev.4 [skip ci]
# [5.0.0-dev.4](https://github.com/ReVanced/revanced-cli/compare/v5.0.0-dev.3...v5.0.0-dev.4) (2024-09-17)

### Bug Fixes

* Make patches selectable by using a mutable collection for the selection option ([751fa1d](751fa1d889))
* Make the patch command work without specifying any selection ([ba159a3](ba159a35a9))

### Features

* Show error about no installation device found at the beginning ([3300e6b](3300e6b433))
2024-09-17 23:18:07 +00:00
oSumAtrIX
751fa1d889
fix: Make patches selectable by using a mutable collection for the selection option 2024-09-05 23:08:18 +04:00
oSumAtrIX
3300e6b433
feat: Show error about no installation device found at the beginning 2024-09-05 23:00:22 +04:00
oSumAtrIX
ba159a35a9
fix: Make the patch command work without specifying any selection 2024-09-05 22:54:09 +04:00
kitadai31
74ff94037e
docs: List supported ABIs correctly and add a mention how to use other ones
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
2024-09-01 16:36:34 +02:00
oSumAtrIX
7e8fb5722a
docs: Link to JRE downloads instead of JDK 2024-08-23 13:21:27 +04:00
semantic-release-bot
7b4af46c94 chore(release): 5.0.0-dev.3 [skip ci]
# [5.0.0-dev.3](https://github.com/ReVanced/revanced-cli/compare/v5.0.0-dev.2...v5.0.0-dev.3) (2024-08-14)

### Features

* Simplify option descriptions ([45c998b](45c998b335))
2024-08-14 13:36:05 +00:00
oSumAtrIX
45c998b335
feat: Simplify option descriptions 2024-08-14 15:34:02 +02:00
semantic-release-bot
9b03963687 chore(release): 5.0.0-dev.2 [skip ci]
# [5.0.0-dev.2](https://github.com/ReVanced/revanced-cli/compare/v5.0.0-dev.1...v5.0.0-dev.2) (2024-08-14)

### Features

* Simplify command and option names and descriptions ([#338](https://github.com/ReVanced/revanced-cli/issues/338)) ([6e7797a](6e7797a3f0))

### BREAKING CHANGES

* Options have been renamed.
2024-08-14 12:08:47 +00:00
oSumAtrIX
6e7797a3f0
feat: Simplify command and option names and descriptions (#338)
BREAKING CHANGE: Options have been renamed.
2024-08-14 14:06:58 +02:00
semantic-release-bot
6306b1abfe chore(release): 5.0.0-dev.1 [skip ci]
# [5.0.0-dev.1](https://github.com/ReVanced/revanced-cli/compare/v4.6.0...v5.0.0-dev.1) (2024-08-12)

### Features

* Set patch options via CLI ([#336](https://github.com/ReVanced/revanced-cli/issues/336)) ([2300243](23002434b2))

### BREAKING CHANGES

* This commit changes various CLI options and removes the `options.json` file. Instead, patch options can now be passed via CLI options
2024-08-12 20:14:37 +00:00
oSumAtrIX
23002434b2
feat: Set patch options via CLI (#336)
BREAKING CHANGE: This commit changes various CLI options and removes the `options.json` file. Instead, patch options can now be passed via CLI options
2024-08-12 22:12:45 +02:00
oSumAtrIX
54ae01cd76
build: Bump ReVanced Patcher (#335) 2024-08-12 22:05:47 +02:00
oSumAtrIX
0a2e99c1c0
build: Remove local Maven repo and unnecessary build configuration 2024-07-26 02:03:51 +02:00
oSumAtrIX
832badef4a
ci: Correct usage of repository variable 2024-07-13 00:45:05 +02:00
oSumAtrIX
40279e0369
docs: Fix invalid option name 2024-05-30 23:31:24 +02:00
oSumAtrIX
e65143851d
build: Bump dependencies 2024-05-26 01:21:15 +02:00
oSumAtrIX
3bec9b5f28
docs: Improve issue templates 2024-05-26 00:43:40 +02:00
oSumAtrIX
6558aafbf1
chore: Fix spelling mistake 2024-04-05 21:17:42 +02:00
semantic-release-bot
1496e824d6 chore(release): 4.6.0 [skip ci]
# [4.6.0](https://github.com/ReVanced/revanced-cli/compare/v4.5.0...v4.6.0) (2024-04-01)

### Bug Fixes

* Copy APK to output path when it is not being signed ([366f400](366f400c5a))
* Use correct option description ([45a2ffa](45a2ffa2dd))

### Features

* Use more consistent option name ([223629c](223629c663))
2024-04-01 14:56:47 +00:00
oSumAtrIX
66a5fc2bf6
chore: Merge branch dev to main (#318) 2024-04-01 16:54:44 +02:00
oSumAtrIX
2b41fe6d0b
docs: Add notice about authentication 2024-03-29 18:41:15 +01:00
semantic-release-bot
9dd460f056 chore(release): 4.6.0-dev.1 [skip ci]
# [4.6.0-dev.1](https://github.com/ReVanced/revanced-cli/compare/v4.5.1-dev.1...v4.6.0-dev.1) (2024-03-14)

### Bug Fixes

* Use correct option description ([45a2ffa](45a2ffa2dd))

### Features

* Use more consistent option name ([223629c](223629c663))
2024-03-14 13:47:05 +00:00
oSumAtrIX
223629c663
feat: Use more consistent option name 2024-03-14 13:22:54 +01:00
oSumAtrIX
45a2ffa2dd
fix: Use correct option description 2024-03-14 13:22:54 +01:00
oSumAtrIX
932494eeab
build: Bump dependencies 2024-03-14 13:22:54 +01:00
semantic-release-bot
0d28a49773 chore(release): 4.5.1-dev.1 [skip ci]
## [4.5.1-dev.1](https://github.com/ReVanced/revanced-cli/compare/v4.5.0...v4.5.1-dev.1) (2024-03-12)

### Bug Fixes

* Copy APK to output path when it is not being signed ([366f400](366f400c5a))
2024-03-12 13:49:51 +00:00
oSumAtrIX
366f400c5a
fix: Copy APK to output path when it is not being signed
When `--mount` is used, signing is skipped. For that reason the APK was never copied to the output path.
2024-03-12 14:47:45 +01:00
semantic-release-bot
d5c27408f3 chore(release): 4.5.0 [skip ci]
# [4.5.0](https://github.com/ReVanced/revanced-cli/compare/v4.4.2...v4.5.0) (2024-03-11)

### Bug Fixes

* Show path for missing files instead of just the name ([f0f3e56](f0f3e5614b))
* Sign APKs correctly ([5ff105c](5ff105cf6b))

### Features

* Remove deprecated CLI options ([48a1a39](48a1a39b94))
2024-03-11 09:12:29 +00:00
oSumAtrIX
8ee5b754da
chore: Merge branch dev to main (#317) 2024-03-11 10:10:56 +01:00
semantic-release-bot
9476f5a2e4 chore(release): 4.5.0-dev.1 [skip ci]
# [4.5.0-dev.1](https://github.com/ReVanced/revanced-cli/compare/v4.4.2...v4.5.0-dev.1) (2024-03-11)

### Bug Fixes

* Show path for missing files instead of just the name ([f0f3e56](f0f3e5614b))
* Sign APKs correctly ([5ff105c](5ff105cf6b))

### Features

* Remove deprecated CLI options ([48a1a39](48a1a39b94))
2024-03-11 09:08:04 +00:00
oSumAtrIX
5ff105cf6b
fix: Sign APKs correctly 2024-03-11 10:05:32 +01:00
oSumAtrIX
f0f3e5614b
fix: Show path for missing files instead of just the name 2024-03-11 10:05:04 +01:00
oSumAtrIX
48a1a39b94
feat: Remove deprecated CLI options 2024-03-11 09:22:35 +01:00
semantic-release-bot
c45ed69adf chore(release): 4.4.2 [skip ci]
## [4.4.2](https://github.com/ReVanced/revanced-cli/compare/v4.4.1...v4.4.2) (2024-03-10)
2024-03-10 15:44:08 +00:00
oSumAtrIX
8641d301b1
chore: Merge branch dev to main (#315) 2024-03-10 16:42:17 +01:00
semantic-release-bot
44b72ca99d chore(release): 4.4.2-dev.2 [skip ci]
## [4.4.2-dev.2](https://github.com/ReVanced/revanced-cli/compare/v4.4.2-dev.1...v4.4.2-dev.2) (2024-03-10)
2024-03-10 15:41:25 +00:00
oSumAtrIX
240f2cfb6b
build(Needs bump): Bump dependencies to fix generating keystore 2024-03-10 16:39:43 +01:00
semantic-release-bot
304275ddbb chore(release): 4.4.2-dev.1 [skip ci]
## [4.4.2-dev.1](https://github.com/ReVanced/revanced-cli/compare/v4.4.1...v4.4.2-dev.1) (2024-03-09)
2024-03-09 04:22:02 +00:00
oSumAtrIX
483590726a
build(Needs bump): Bump dependencies to fix signing issues 2024-03-09 05:20:11 +01:00
semantic-release-bot
cf20efd467 chore(release): 4.4.1 [skip ci]
## [4.4.1](https://github.com/ReVanced/revanced-cli/compare/v4.4.0...v4.4.1) (2024-03-06)

### Bug Fixes

* Bump dependencies to support BCS keystore ([1c10a77](1c10a7760d))
2024-03-06 19:14:29 +00:00
oSumAtrIX
164d09dec1
chore: Merge branch dev to main (#309) 2024-03-06 20:12:35 +01:00
oSumAtrIX
1e92239616
build: Set target bytecode level to JVM 11 2024-03-04 19:16:09 +01:00
semantic-release-bot
a5a5085f0f chore(release): 4.4.1-dev.2 [skip ci]
## [4.4.1-dev.2](https://github.com/ReVanced/revanced-cli/compare/v4.4.1-dev.1...v4.4.1-dev.2) (2024-03-04)

### Bug Fixes

* Bump dependencies to support BCS keystore ([1c10a77](1c10a7760d))
2024-03-04 14:50:04 +00:00
oSumAtrIX
1c10a7760d
fix: Bump dependencies to support BCS keystore 2024-03-04 15:47:59 +01:00
oSumAtrIX
4ff697ef0b
ci: Update action 2024-03-04 15:36:34 +01:00
oSumAtrIX
628b452b7e
docs: Add features and documentation section to readme 2024-02-26 04:38:22 +01:00
oSumAtrIX
e622616628
docs: Fix broken links 2024-02-26 04:37:46 +01:00
oSumAtrIX
109b33f1ed
chore: Rename issue templates 2024-02-25 03:37:53 +01:00
oSumAtrIX
9fe4795923
ci: Rename workflow file 2024-02-25 03:14:02 +01:00
oSumAtrIX
f21c56d8c0
ci: Fix indentation in workflow 2024-02-24 01:14:45 +01:00
oSumAtrIX
de63cfa426
refactor: Move code out of use block 2024-02-24 01:10:23 +01:00
oSumAtrIX
9c0ad4604a
docs: Break long lines 2024-02-23 04:02:32 +01:00
oSumAtrIX
2fcb74e79d
docs: Fix mistakes and wording 2024-02-23 03:57:02 +01:00
oSumAtrIX
f2368ccf27
docs: Format markdown code 2024-02-23 03:03:51 +01:00
oSumAtrIX
a4e8d2df0d
docs: Fix incorrect punctuation 2024-02-23 03:00:35 +01:00
oSumAtrIX
724593a7b1
ci: Split release into a separate PR build workflow
Because the release workflow already runs on dev and main, it is not necessary to also trigger it for PRs.
ci: Do not start a Gradle daemon for PR builds
2024-02-23 02:26:12 +01:00
semantic-release-bot
4f1982e3ad chore(release): 4.4.1-dev.1 [skip ci]
## [4.4.1-dev.1](https://github.com/ReVanced/revanced-cli/compare/v4.4.0...v4.4.1-dev.1) (2024-02-21)
2024-02-21 03:58:27 +00:00
oSumAtrIX
f1d7d0dc62
build: Sign release artifacts 2024-02-21 04:52:53 +01:00
oSumAtrIX
40c90f5c1b
build: Bump Gradle 2024-02-15 02:34:10 +01:00
oSumAtrIX
30b46bcb0f
build(Needs bump): Bump dependencies 2024-02-15 02:34:10 +01:00
oSumAtrIX
b6f63c7d9d
docs: Fix blockquote highlights not rendering
As of 14. Nov 2023 GitHub has decided to disable nested highlighted blockquotes: https://github.com/orgs/community/discussions/16925.
2024-02-04 18:35:41 +01:00
oSumAtrIX
b5bd988a1d
ci: Use latest Node.js LTS version to fix builds 2024-01-26 22:52:38 +01:00
oSumAtrIX
95c998b0a6
ci: Add dependabot 2024-01-26 01:45:45 +01:00
oSumAtrIX
24a8f6575c
build: Bump dependencies 2024-01-26 01:42:04 +01:00
oSumAtrIX
55f0c01e5a
docs: Fix grammatic error 2024-01-12 11:45:39 +01:00
oSumAtrIX
ee1e96b2d5
docs: Simplify patch command 2024-01-12 09:42:05 +01:00
oSumAtrIX
0fc1d571e8
docs: Add JRE links to obtain 2024-01-11 23:37:20 +01:00
oSumAtrIX
4933fe0314
build: Bump dependencies 2024-01-10 09:33:54 +01:00
oSumAtrIX
2e2ddac273
chore: Add local.properties to .gitignore 2024-01-10 09:33:54 +01:00
semantic-release-bot
3c264572a2 chore(release): 4.4.0 [skip ci]
# [4.4.0](https://github.com/ReVanced/revanced-cli/compare/v4.3.0...v4.4.0) (2023-12-28)

### Bug Fixes

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

### Features

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

### Bug Fixes

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

### Features

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

### Features

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

### Features

* Add `list-versions` command ([a974b8e](a974b8ea80))
2023-11-27 22:12:44 +00:00
oSumAtrIX
a974b8ea80
feat: Add list-versions command 2023-11-27 23:11:23 +01:00
semantic-release-bot
89c35ee21b chore(release): 4.2.0 [skip ci]
# [4.2.0](https://github.com/ReVanced/revanced-cli/compare/v4.1.0...v4.2.0) (2023-11-26)

### Bug Fixes

* Fix typo ([#300](https://github.com/ReVanced/revanced-cli/issues/300)) ([9d96bb7](9d96bb7b4c))

### Features

* Allow selecting first Adb device, if none supplied automatically by updating dependencies ([e7c3d64](e7c3d64bf1))
* Exit application with CLI exit code ([36c6a6a](36c6a6a5f7))
* Make `--out´ option optional ([3765957](3765957043))
2023-11-26 05:03:52 +00:00
oSumAtrIX
41bdb04ab0
chore: Merge branch dev to main (#299) 2023-11-26 06:02:21 +01:00
semantic-release-bot
a5542467c8 chore(release): 4.2.0-dev.1 [skip ci]
# [4.2.0-dev.1](https://github.com/ReVanced/revanced-cli/compare/v4.1.1-dev.1...v4.2.0-dev.1) (2023-11-26)

### Features

* Allow selecting first Adb device, if none supplied automatically by updating dependencies ([e7c3d64](e7c3d64bf1))
* Exit application with CLI exit code ([36c6a6a](36c6a6a5f7))
* Make `--out´ option optional ([3765957](3765957043))
2023-11-26 04:58:20 +00:00
oSumAtrIX
5fd205f77d
chore: Lint code 2023-11-26 05:56:31 +01:00
oSumAtrIX
e7c3d64bf1
feat: Allow selecting first Adb device, if none supplied automatically by updating dependencies 2023-11-26 05:55:49 +01:00
oSumAtrIX
3765957043
feat: Make `--out´ option optional 2023-11-26 05:27:31 +01:00
oSumAtrIX
5e63e0a276
refactor: Use a newline for annotation properties 2023-11-26 05:27:30 +01:00
oSumAtrIX
36c6a6a5f7
feat: Exit application with CLI exit code 2023-11-26 05:27:30 +01:00
semantic-release-bot
860fb7b957 chore(release): 4.1.1-dev.1 [skip ci]
## [4.1.1-dev.1](https://github.com/ReVanced/revanced-cli/compare/v4.1.0...v4.1.1-dev.1) (2023-11-25)

### Bug Fixes

* Fix typo ([#300](https://github.com/ReVanced/revanced-cli/issues/300)) ([9d96bb7](9d96bb7b4c))
2023-11-25 22:48:42 +00:00
SandaruKasa
9d96bb7b4c
fix: Fix typo (#300) 2023-11-25 23:47:13 +01:00
oSumAtrIX
3afa590616
chore: Add heading to issue templates 2023-11-23 00:56:53 +01:00
oSumAtrIX
db0b943ad3
chore: Update README heading 2023-11-22 23:41:26 +01:00
oSumAtrIX
8c3d4d3aa1
build: Bump Gradle wrapper 2023-11-22 00:59:45 +01:00
oSumAtrIX
04d312df31
build: Use dedicated Gradle cache action 2023-11-22 00:45:44 +01:00
oSumAtrIX
158f59ab88
build: Use Gradle build cache 2023-11-22 00:26:40 +01:00
oSumAtrIX
a078b53a21
ci: Simplify cache paths 2023-11-22 00:11:19 +01:00
oSumAtrIX
fb75b0f115
chore: Reword comment for first PR merge 2023-11-22 00:07:38 +01:00
oSumAtrIX
c52383eca0
chore: Add a newline between steps 2023-11-22 00:04:47 +01:00
oSumAtrIX
0562ee85c5
chore: Notice about contribution guidelines in issue templates 2023-11-22 00:01:25 +01:00
oSumAtrIX
1cde672a05
chore: Do not use a line break in issue template sentence 2023-11-21 23:48:30 +01:00
oSumAtrIX
d5419dbb6b
build: Bump dependencies 2023-11-21 23:43:49 +01:00
oSumAtrIX
d29016b428
ci: Update cache key 2023-11-21 23:41:43 +01:00
oSumAtrIX
1eb51e9d4f
chore: Update packages 2023-11-21 23:41:00 +01:00
semantic-release-bot
86b8415ac6 chore(release): 4.1.0 [skip ci]
# [4.1.0](https://github.com/ReVanced/revanced-cli/compare/v4.0.2...v4.1.0) (2023-11-04)

### Features

* Include or exclude patches by their index in relation to supplied patch bundles ([b2055ce](b2055ce07d))
* List patches which are compatible with any app ([#297](https://github.com/ReVanced/revanced-cli/issues/297)) ([0139dfe](0139dfe0bf))

### Performance Improvements

* Use a `HashSet` to check for included and excluded patches ([616d14f](616d14f009))
2023-11-04 21:13:41 +00:00
oSumAtrIX
8f4aebc60b
chore: Merge branch dev to main (#292) 2023-11-04 22:11:36 +01:00
semantic-release-bot
bd3171c7c5 chore(release): 4.1.0-dev.3 [skip ci]
# [4.1.0-dev.3](https://github.com/ReVanced/revanced-cli/compare/v4.1.0-dev.2...v4.1.0-dev.3) (2023-11-03)
2023-11-03 17:27:32 +00:00
oSumAtrIX
6481ba68db
build(Needs bump): Bump dependencies 2023-11-03 18:24:27 +01:00
semantic-release-bot
799882e6a6 chore(release): 4.1.0-dev.2 [skip ci]
# [4.1.0-dev.2](https://github.com/ReVanced/revanced-cli/compare/v4.1.0-dev.1...v4.1.0-dev.2) (2023-11-03)

### Features

* Include or exclude patches by their index in relation to supplied patch bundles ([b2055ce](b2055ce07d))

### Performance Improvements

* Use a `HashSet` to check for included and excluded patches ([616d14f](616d14f009))
2023-11-03 01:04:32 +00:00
oSumAtrIX
616d14f009
perf: Use a HashSet to check for included and excluded patches 2023-11-03 02:02:41 +01:00
oSumAtrIX
b2055ce07d
feat: Include or exclude patches by their index in relation to supplied patch bundles 2023-11-03 02:02:40 +01:00
semantic-release-bot
4fc42089a5 chore(release): 4.1.0-dev.1 [skip ci]
# [4.1.0-dev.1](https://github.com/ReVanced/revanced-cli/compare/v4.0.3-dev.2...v4.1.0-dev.1) (2023-11-03)

### Features

* List patches which are compatible with any app ([#297](https://github.com/ReVanced/revanced-cli/issues/297)) ([0139dfe](0139dfe0bf))
2023-11-03 00:33:10 +00:00
SandaruKasa
0139dfe0bf
feat: List patches which are compatible with any app (#297)
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
2023-11-03 01:31:45 +01:00
semantic-release-bot
7d1c0e663f chore(release): 4.0.3-dev.2 [skip ci]
## [4.0.3-dev.2](https://github.com/ReVanced/revanced-cli/compare/v4.0.3-dev.1...v4.0.3-dev.2) (2023-10-30)
2023-10-30 21:24:43 +00:00
taku
6cc6960493
build(Needs bump): Bump dependencies to support PatchOption#valueType (#296) 2023-10-30 22:22:50 +01:00
semantic-release-bot
9f15ac6ec5 chore(release): 4.0.3-dev.1 [skip ci]
## [4.0.3-dev.1](https://github.com/ReVanced/revanced-cli/compare/v4.0.2...v4.0.3-dev.1) (2023-10-23)
2023-10-23 00:15:36 +00:00
oSumAtrIX
6670d89c74
build(Needs bump): Bump dependencies to support new patch options fields 2023-10-23 02:04:50 +02:00
oSumAtrIX
a60d07fc5d
build: Bump Kotlin Gradle plugin version 2023-10-22 16:14:47 +02:00
oSumAtrIX
362e6f5904
docs: Use shorter heading 2023-10-21 12:07:40 +02:00
Palm
51402ab8a7
build: Bump dependencies 2023-10-12 21:57:50 +02:00
semantic-release-bot
a8c8682116 chore(release): 4.0.2 [skip ci]
## [4.0.2](https://github.com/ReVanced/revanced-cli/compare/v4.0.1...v4.0.2) (2023-10-12)

### Bug Fixes

* Move file to output even when mounting ([59dfc98](59dfc988e3))
* Use punctuation in option descriptions ([da4469f](da4469f402))

### Performance Improvements

* Use multiple threads for writing dex files ([28648a1](28648a1c53))
2023-10-12 17:58:47 +00:00
oSumAtrIX
a86919eb71
chore: Merge branch dev to main (#281) 2023-10-12 19:56:45 +02:00
semantic-release-bot
8b04b6790b chore(release): 4.0.2-dev.3 [skip ci]
## [4.0.2-dev.3](https://github.com/ReVanced/revanced-cli/compare/v4.0.2-dev.2...v4.0.2-dev.3) (2023-10-10)

### Bug Fixes

* Move file to output even when mounting ([59dfc98](59dfc988e3))
2023-10-10 08:11:07 +00:00
oSumAtrIX
59dfc988e3
fix: Move file to output even when mounting 2023-10-10 10:09:04 +02:00
oSumAtrIX
b01fef730a
docs: Use preciser formulation 2023-10-10 10:01:39 +02:00
semantic-release-bot
a564aaa1b5 chore(release): 4.0.2-dev.2 [skip ci]
## [4.0.2-dev.2](https://github.com/ReVanced/revanced-cli/compare/v4.0.2-dev.1...v4.0.2-dev.2) (2023-10-10)

### Performance Improvements

* Use multiple threads for writing dex files ([28648a1](28648a1c53))
2023-10-10 08:00:39 +00:00
oSumAtrIX
f315485713
docs: Remove unneeded requirements 2023-10-10 09:58:49 +02:00
oSumAtrIX
28648a1c53
perf: Use multiple threads for writing dex files
This has an impact on memory, but should not cause any issues in the environment of ReVanced CLI.
2023-10-10 09:58:49 +02:00
oSumAtrIX
daac98817f
docs: Remove unnecessary text 2023-10-10 09:54:28 +02:00
oSumAtrIX
9328475e11
docs: Use more fitting emojis for sections 2023-10-10 01:12:10 +02:00
oSumAtrIX
6507b5fe8a
docs: Use consistent language 2023-10-10 01:09:46 +02:00
oSumAtrIX
349ff5749a
docs: Move warning to the beginning of it's section 2023-10-10 01:08:17 +02:00
oSumAtrIX
495735f44c
docs: Improve structural integrity 2023-10-10 01:07:11 +02:00
oSumAtrIX
f48da18e37
build: Use artifacts from Jitpack 2023-10-09 19:15:23 +02:00
semantic-release-bot
cf58f55b38 chore(release): 4.0.2-dev.1 [skip ci]
## [4.0.2-dev.1](https://github.com/ReVanced/revanced-cli/compare/v4.0.1...v4.0.2-dev.1) (2023-10-08)

### Bug Fixes

* Use punctuation in option descriptions ([da4469f](da4469f402))
2023-10-08 18:53:45 +00:00
oSumAtrIX
da4469f402
fix: Use punctuation in option descriptions 2023-10-08 20:51:49 +02:00
semantic-release-bot
df2c137ae9 chore(release): 4.0.1 [skip ci]
## [4.0.1](https://github.com/ReVanced/revanced-cli/compare/v4.0.0...v4.0.1) (2023-10-08)

### Bug Fixes

* Correct warning message ([ba573f7](ba573f73d0))
2023-10-08 01:52:44 +00:00
oSumAtrIX
8a2f219f8b
chore: Merge branch dev to main (#280) 2023-10-08 03:50:53 +02:00
oSumAtrIX
719d9fcfa3 docs: Use new X branding 2023-10-08 03:50:43 +02:00
semantic-release-bot
6c44a730c3 chore(release): 4.0.1-dev.1 [skip ci]
## [4.0.1-dev.1](https://github.com/ReVanced/revanced-cli/compare/v4.0.0...v4.0.1-dev.1) (2023-10-07)

### Bug Fixes

* Correct warning message ([e4e339d](e4e339dff4))
2023-10-08 03:50:43 +02:00
oSumAtrIX
ba573f73d0 fix: Correct warning message 2023-10-08 03:50:43 +02:00
oSumAtrIX
e95a392016 build(Needs bump): Bump dependencies 2023-10-08 03:50:43 +02:00
oSumAtrIX
fc62f7f475 docs: Fix incorrect bullet point 2023-10-08 03:50:43 +02:00
oSumAtrIX
ff2e10dbe6
chore: Merge branch dev to main (#276) 2023-10-05 01:53:13 +02:00
oSumAtrIX
7ff433860d
chore: Add missing assets 2023-10-05 01:52:20 +02:00
semantic-release-bot
7121e5fa4c chore(release): 4.0.0 [skip ci]
# [4.0.0](https://github.com/ReVanced/revanced-cli/compare/v3.1.1...v4.0.0) (2023-10-04)

### Bug Fixes

* Check, if mounting is possible ([3e13fb5](3e13fb5d56))
* Delete temporal files if it exists ([a022feb](a022febd0c))
* Do not sign if mounting ([578e16b](578e16b099))
* Filter logs correctly ([43fc20d](43fc20d90e))
* Log correct options command ([#262](https://github.com/ReVanced/revanced-cli/issues/262)) ([96c196d](96c196dcb1))
* Log logs with levels over warning to error output stream ([075f6ad](075f6ad565))
* Only open files for reading and writing if writeable ([3846f72](3846f721ca))
* Only set options for filtered patches ([64d9127](64d9127291))

### Features

* Add function to get the most common compatible version ([77d9173](77d91735ff))
* Add option to filter patches to be listed by package name ([50c0f98](50c0f98ce5))
* Add option to warn about patches not being found in supplied patch bundles ([e46d855](e46d855643))
* Add ReVanced Library subproject ([#265](https://github.com/ReVanced/revanced-cli/issues/265)) ([157278c](157278c9ba))
* Do not format patch names ([80a8d88](80a8d88406))
* Extend signing API ([592dc1c](592dc1c64a))
* Improve option descriptions ([d5ea5a0](d5ea5a0ab1))
* Log stacktrace in new line ([c67e3c7](c67e3c70c7))
* Use ReVanced Library in ReVanced CLI ([7794327](7794327a11))
* Word log message better ([6942b22](6942b22a68))

### Performance Improvements

* Do not check, if the options file exists twice ([e3c5550](e3c55507cf))

### BREAKING CHANGES

* This changes many signatures of existing APIs and adds new functions for signing
* This changes the log handler signature
2023-10-04 23:40:45 +00:00
oSumAtrIX
23b5e8b7f9
chore: Merge branch dev to main (#263) 2023-10-05 01:38:56 +02:00
43 changed files with 5857 additions and 3476 deletions

3
.editorconfig Normal file
View File

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

View File

@ -1,49 +0,0 @@
name: 🐞 Bug report
description: Report a bug or an issue.
title: 'bug: '
labels: ['Bug report']
body:
- type: markdown
attributes:
value: |
# ReVanced CLI bug report
Please check for existing bug reports
[here](https://github.com/ReVanced/revanced-cli/labels/Bug%20report)
before creating a new one.
- 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
- List used patches if applicable
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 issue will be closed if you don't follow the checklist below.
options:
- label: This request is not a duplicate of an existing issue.
required: true
- label: I have chosen an appropriate title.
required: true
- label: All requested information has been provided properly.
required: true

110
.github/ISSUE_TEMPLATE/bug_report.yml vendored Normal file
View File

@ -0,0 +1,110 @@
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-cli/main/assets/revanced-headline/revanced-headline-vertical-dark.svg"
>
<img
width="256px"
src="https://raw.githubusercontent.com/revanced/revanced-cli/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-cli/main/assets/revanced-logo/revanced-logo.svg" />
<img height="24px" src="https://raw.githubusercontent.com/revanced/revanced-cli/main/assets/revanced-logo/revanced-logo.svg" />
</picture>
</a>&nbsp;&nbsp;&nbsp;
<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>&nbsp;&nbsp;&nbsp;
<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>&nbsp;&nbsp;&nbsp;
<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>&nbsp;&nbsp;&nbsp;
<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>&nbsp;&nbsp;&nbsp;
<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>&nbsp;&nbsp;&nbsp;
<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 CLI bug report
Before creating a new bug report, please keep the following in mind:
- **Do not submit a duplicate bug report**: Search for existing bug reports [here](https://github.com/ReVanced/revanced-cli/issues?q=label%3A%22Bug+report%22).
- **Review the contribution guidelines**: Make sure your bug report adheres to it. You can find the guidelines [here](https://github.com/ReVanced/revanced-cli/blob/main/CONTRIBUTING.md).
- **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
- List used patches if applicable
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: I have checked all open and closed bug reports and this is not a duplicate.
required: true
- label: I have chosen an appropriate title.
required: true
- label: All requested information has been provided properly.
required: true

View File

@ -1,45 +0,0 @@
name: ⭐ Feature request
description: Create a detailed request for a new feature.
title: 'feat: '
labels: ['Feature request']
body:
- type: markdown
attributes:
value: |
# ReVanced CLI feature request
Please check for existing feature requests
[here](https://github.com/ReVanced/revanced-cli/labels/Feature%20request)
before creating a new one.
- 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 issue will be closed if you don't follow the checklist below.
options:
- label: This request is not a duplicate of an existing issue.
required: true
- label: I have chosen an appropriate title.
required: true
- label: All requested information has been provided properly.
required: true

View 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-cli/main/assets/revanced-headline/revanced-headline-vertical-dark.svg"
>
<img
width="256px"
src="https://raw.githubusercontent.com/revanced/revanced-cli/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-cli/main/assets/revanced-logo/revanced-logo.svg" />
<img height="24px" src="https://raw.githubusercontent.com/revanced/revanced-cli/main/assets/revanced-logo/revanced-logo.svg" />
</picture>
</a>&nbsp;&nbsp;&nbsp;
<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>&nbsp;&nbsp;&nbsp;
<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>&nbsp;&nbsp;&nbsp;
<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>&nbsp;&nbsp;&nbsp;
<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>&nbsp;&nbsp;&nbsp;
<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>&nbsp;&nbsp;&nbsp;
<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 CLI feature request
Before creating a new feature request, please keep the following in mind:
- **Do not submit a duplicate feature request**: Search for existing feature requests [here](https://github.com/ReVanced/revanced-cli/issues?q=label%3A%22Feature+request%22).
- **Review the contribution guidelines**: Make sure your feature request adheres to it. You can find the guidelines [here](https://github.com/ReVanced/revanced-cli//blob/main/CONTRIBUTING.md).
- **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: I have checked all open and closed feature requests and this is not a duplicate.
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
View File

@ -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
View File

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

View File

@ -0,0 +1,25 @@
name: Build pull request
on:
workflow_dispatch:
pull_request:
branches:
- dev
jobs:
release:
name: Build
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Cache Gradle
uses: burrunan/gradle-cache-action@v1
- name: Build
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: ./gradlew build --no-daemon

View File

@ -16,6 +16,7 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Open pull request
uses: repo-sync/pull-request@v2
with:

View File

@ -6,14 +6,12 @@ on:
branches:
- main
- dev
pull_request:
branches:
- main
- dev
jobs:
release:
name: Release
permissions:
contents: write
runs-on: ubuntu-latest
steps:
- name: Checkout
@ -23,24 +21,32 @@ jobs:
# https://github.com/cycjimmy/semantic-release-action#private-packages
persist-credentials: false
fetch-depth: 0
- name: Cache
uses: actions/cache@v3
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: Cache Gradle
uses: burrunan/gradle-cache-action@v1
- name: Build
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# Cleaning is necessary to avoid uploading two identical artifacts with different versions
run: ./gradlew 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: Import GPG key
uses: crazy-max/ghaction-import-gpg@v6
with:
gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }}
passphrase: ${{ secrets.GPG_PASSPHRASE }}
fingerprint: ${{ vars.GPG_FINGERPRINT }}
- name: Release
env:
GITHUB_TOKEN: ${{ secrets.REPOSITORY_PUSH_ACCESS }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: npm exec semantic-release

View File

@ -11,7 +11,7 @@ jobs:
name: Dispatch event to documentation repository
if: github.ref == 'refs/heads/main'
steps:
- uses: peter-evans/repository-dispatch@v2
- uses: peter-evans/repository-dispatch@v3
with:
token: ${{ secrets.DOCUMENTATION_REPO_ACCESS_TOKEN }}
repository: revanced/revanced-documentation

3
.gitignore vendored
View File

@ -120,3 +120,6 @@ node_modules/
# ReVanced CLI
revanced-cache/
options.toml
# Generated by Android projects
local.properties

View File

@ -23,7 +23,8 @@
"assets": [
"CHANGELOG.md",
"gradle.properties"
]
],
"message": "chore: Release v${nextRelease.version} [skip ci]\n\n${nextRelease.notes}"
}
],
[
@ -31,7 +32,7 @@
{
"assets": [
{
"path": "build/libs/*all.jar"
"path": "build/libs/*-all*"
}
],
successComment: false

View File

@ -1,3 +1,402 @@
## [5.0.1](https://github.com/ReVanced/revanced-cli/compare/v5.0.0...v5.0.1) (2025-04-14)
### Bug Fixes
* Make mounting work again by bumping dependencies ([#359](https://github.com/ReVanced/revanced-cli/issues/359)) ([68a4872](https://github.com/ReVanced/revanced-cli/commit/68a48724ebf01a0c8f8adc0fec63037bff672dc9))
## [5.0.1-dev.1](https://github.com/ReVanced/revanced-cli/compare/v5.0.0...v5.0.1-dev.1) (2025-02-26)
### Bug Fixes
* Make mounting work again by bumping dependencies ([#359](https://github.com/ReVanced/revanced-cli/issues/359)) ([68a4872](https://github.com/ReVanced/revanced-cli/commit/68a48724ebf01a0c8f8adc0fec63037bff672dc9))
# [5.0.0](https://github.com/ReVanced/revanced-cli/compare/v4.6.0...v5.0.0) (2024-11-10)
### Bug Fixes
* Check for null when no device serial was specified ([1da8ae9](https://github.com/ReVanced/revanced-cli/commit/1da8ae9e46000dd3c4eecd793c559e75012cf535))
* List if patch option is required ([#346](https://github.com/ReVanced/revanced-cli/issues/346)) ([98ff0c3](https://github.com/ReVanced/revanced-cli/commit/98ff0c34fa71c3b3ecd96157d45a30ee2b8979c6))
* Make CLI ArgGroup non-exclusive to be able to disable and enable patches at the same time ([1bb0d13](https://github.com/ReVanced/revanced-cli/commit/1bb0d13726fd5790c59cb6d28df3618c7606710d))
* Make patches selectable by using a mutable collection for the selection option ([751fa1d](https://github.com/ReVanced/revanced-cli/commit/751fa1d889f40c51b291116029fd84f2b051f2f0))
* Make the patch command work without specifying any selection ([ba159a3](https://github.com/ReVanced/revanced-cli/commit/ba159a35a9a99d18a4c1e04128b08ae336a49b3e))
* Print in new line correctly ([c2dc9d7](https://github.com/ReVanced/revanced-cli/commit/c2dc9d76be33c98284741e23c406500483c47753))
* Use the first connected device when no ADB device is specified ([5f952f3](https://github.com/ReVanced/revanced-cli/commit/5f952f35f5cb388b6509b2b4d905b8143ebc7996))
### Features
* Set patch options via CLI ([#336](https://github.com/ReVanced/revanced-cli/issues/336)) ([2300243](https://github.com/ReVanced/revanced-cli/commit/23002434b2d51c2a3b30b33dd0526261432d90ce))
* Show error about no installation device found at the beginning ([3300e6b](https://github.com/ReVanced/revanced-cli/commit/3300e6b4333ed1c4e6785cb82eca9016fc6d4a20))
* Simplify command and option names and descriptions ([#338](https://github.com/ReVanced/revanced-cli/issues/338)) ([6e7797a](https://github.com/ReVanced/revanced-cli/commit/6e7797a3f0525a8f48af7182157da0d045600ac2))
* Simplify option descriptions ([45c998b](https://github.com/ReVanced/revanced-cli/commit/45c998b335b65ac233fece8b804dc7410142691c))
### BREAKING CHANGES
* Options have been renamed.
* This commit changes various CLI options and removes the `options.json` file. Instead, patch options can now be passed via CLI options
# [5.0.0-dev.11](https://github.com/ReVanced/revanced-cli/compare/v5.0.0-dev.10...v5.0.0-dev.11) (2024-11-10)
### Bug Fixes
* List if patch option is required ([#346](https://github.com/ReVanced/revanced-cli/issues/346)) ([98ff0c3](https://github.com/ReVanced/revanced-cli/commit/98ff0c34fa71c3b3ecd96157d45a30ee2b8979c6))
# [5.0.0-dev.10](https://github.com/ReVanced/revanced-cli/compare/v5.0.0-dev.9...v5.0.0-dev.10) (2024-11-05)
### Bug Fixes
* Make CLI ArgGroup non-exclusive to be able to disable and enable patches at the same time ([1bb0d13](https://github.com/ReVanced/revanced-cli/commit/1bb0d13726fd5790c59cb6d28df3618c7606710d))
# [5.0.0-dev.9](https://github.com/ReVanced/revanced-cli/compare/v5.0.0-dev.8...v5.0.0-dev.9) (2024-11-05)
### Bug Fixes
* Print in new line correctly ([c2dc9d7](https://github.com/ReVanced/revanced-cli/commit/c2dc9d76be33c98284741e23c406500483c47753))
# [5.0.0-dev.8](https://github.com/ReVanced/revanced-cli/compare/v5.0.0-dev.7...v5.0.0-dev.8) (2024-10-17)
# [5.0.0-dev.7](https://github.com/ReVanced/revanced-cli/compare/v5.0.0-dev.6...v5.0.0-dev.7) (2024-10-16)
### Bug Fixes
* Check for null when no device serial was specified ([1da8ae9](https://github.com/ReVanced/revanced-cli/commit/1da8ae9e46000dd3c4eecd793c559e75012cf535))
# [5.0.0-dev.6](https://github.com/ReVanced/revanced-cli/compare/v5.0.0-dev.5...v5.0.0-dev.6) (2024-10-10)
### Bug Fixes
* Use the first connected device when no ADB device is specified ([5f952f3](https://github.com/ReVanced/revanced-cli/commit/5f952f35f5cb388b6509b2b4d905b8143ebc7996))
# [5.0.0-dev.5](https://github.com/ReVanced/revanced-cli/compare/v5.0.0-dev.4...v5.0.0-dev.5) (2024-09-30)
# [5.0.0-dev.4](https://github.com/ReVanced/revanced-cli/compare/v5.0.0-dev.3...v5.0.0-dev.4) (2024-09-17)
### Bug Fixes
* Make patches selectable by using a mutable collection for the selection option ([751fa1d](https://github.com/ReVanced/revanced-cli/commit/751fa1d889f40c51b291116029fd84f2b051f2f0))
* Make the patch command work without specifying any selection ([ba159a3](https://github.com/ReVanced/revanced-cli/commit/ba159a35a9a99d18a4c1e04128b08ae336a49b3e))
### Features
* Show error about no installation device found at the beginning ([3300e6b](https://github.com/ReVanced/revanced-cli/commit/3300e6b4333ed1c4e6785cb82eca9016fc6d4a20))
# [5.0.0-dev.3](https://github.com/ReVanced/revanced-cli/compare/v5.0.0-dev.2...v5.0.0-dev.3) (2024-08-14)
### Features
* Simplify option descriptions ([45c998b](https://github.com/ReVanced/revanced-cli/commit/45c998b335b65ac233fece8b804dc7410142691c))
# [5.0.0-dev.2](https://github.com/ReVanced/revanced-cli/compare/v5.0.0-dev.1...v5.0.0-dev.2) (2024-08-14)
### Features
* Simplify command and option names and descriptions ([#338](https://github.com/ReVanced/revanced-cli/issues/338)) ([6e7797a](https://github.com/ReVanced/revanced-cli/commit/6e7797a3f0525a8f48af7182157da0d045600ac2))
### BREAKING CHANGES
* Options have been renamed.
# [5.0.0-dev.1](https://github.com/ReVanced/revanced-cli/compare/v4.6.0...v5.0.0-dev.1) (2024-08-12)
### Features
* Set patch options via CLI ([#336](https://github.com/ReVanced/revanced-cli/issues/336)) ([2300243](https://github.com/ReVanced/revanced-cli/commit/23002434b2d51c2a3b30b33dd0526261432d90ce))
### BREAKING CHANGES
* This commit changes various CLI options and removes the `options.json` file. Instead, patch options can now be passed via CLI options
# [4.6.0](https://github.com/ReVanced/revanced-cli/compare/v4.5.0...v4.6.0) (2024-04-01)
### Bug Fixes
* Copy APK to output path when it is not being signed ([366f400](https://github.com/ReVanced/revanced-cli/commit/366f400c5a46491f3f262c7ff4b0df1ae3721f74))
* Use correct option description ([45a2ffa](https://github.com/ReVanced/revanced-cli/commit/45a2ffa2dd95ee8ac3c4d466463c9a5b869b8da1))
### Features
* Use more consistent option name ([223629c](https://github.com/ReVanced/revanced-cli/commit/223629c663dcd94d237110e09e4e152aa03867f9))
# [4.6.0-dev.1](https://github.com/ReVanced/revanced-cli/compare/v4.5.1-dev.1...v4.6.0-dev.1) (2024-03-14)
### Bug Fixes
* Use correct option description ([45a2ffa](https://github.com/ReVanced/revanced-cli/commit/45a2ffa2dd95ee8ac3c4d466463c9a5b869b8da1))
### Features
* Use more consistent option name ([223629c](https://github.com/ReVanced/revanced-cli/commit/223629c663dcd94d237110e09e4e152aa03867f9))
## [4.5.1-dev.1](https://github.com/ReVanced/revanced-cli/compare/v4.5.0...v4.5.1-dev.1) (2024-03-12)
### Bug Fixes
* Copy APK to output path when it is not being signed ([366f400](https://github.com/ReVanced/revanced-cli/commit/366f400c5a46491f3f262c7ff4b0df1ae3721f74))
# [4.5.0](https://github.com/ReVanced/revanced-cli/compare/v4.4.2...v4.5.0) (2024-03-11)
### Bug Fixes
* Show path for missing files instead of just the name ([f0f3e56](https://github.com/ReVanced/revanced-cli/commit/f0f3e5614b99b34391e0492177706f9c09781cad))
* Sign APKs correctly ([5ff105c](https://github.com/ReVanced/revanced-cli/commit/5ff105cf6b3fac9cd12478efd10caf90d1ecf589))
### Features
* Remove deprecated CLI options ([48a1a39](https://github.com/ReVanced/revanced-cli/commit/48a1a39b94dd9121c400d28e3e93dec3fc13e3be))
# [4.5.0-dev.1](https://github.com/ReVanced/revanced-cli/compare/v4.4.2...v4.5.0-dev.1) (2024-03-11)
### Bug Fixes
* Show path for missing files instead of just the name ([f0f3e56](https://github.com/ReVanced/revanced-cli/commit/f0f3e5614b99b34391e0492177706f9c09781cad))
* Sign APKs correctly ([5ff105c](https://github.com/ReVanced/revanced-cli/commit/5ff105cf6b3fac9cd12478efd10caf90d1ecf589))
### Features
* Remove deprecated CLI options ([48a1a39](https://github.com/ReVanced/revanced-cli/commit/48a1a39b94dd9121c400d28e3e93dec3fc13e3be))
## [4.4.2](https://github.com/ReVanced/revanced-cli/compare/v4.4.1...v4.4.2) (2024-03-10)
## [4.4.2-dev.2](https://github.com/ReVanced/revanced-cli/compare/v4.4.2-dev.1...v4.4.2-dev.2) (2024-03-10)
## [4.4.2-dev.1](https://github.com/ReVanced/revanced-cli/compare/v4.4.1...v4.4.2-dev.1) (2024-03-09)
## [4.4.1](https://github.com/ReVanced/revanced-cli/compare/v4.4.0...v4.4.1) (2024-03-06)
### Bug Fixes
* Bump dependencies to support BCS keystore ([1c10a77](https://github.com/ReVanced/revanced-cli/commit/1c10a7760d76ea850260ca49b448be7ad121de44))
## [4.4.1-dev.2](https://github.com/ReVanced/revanced-cli/compare/v4.4.1-dev.1...v4.4.1-dev.2) (2024-03-04)
### Bug Fixes
* Bump dependencies to support BCS keystore ([1c10a77](https://github.com/ReVanced/revanced-cli/commit/1c10a7760d76ea850260ca49b448be7ad121de44))
## [4.4.1-dev.1](https://github.com/ReVanced/revanced-cli/compare/v4.4.0...v4.4.1-dev.1) (2024-02-21)
# [4.4.0](https://github.com/ReVanced/revanced-cli/compare/v4.3.0...v4.4.0) (2023-12-28)
### Bug Fixes
* Add missing punctuation in command description ([8210351](https://github.com/ReVanced/revanced-cli/commit/821035107d7264580275f395e9e3fcef91394afd))
### Features
* Log saved patched APK file path ([16109bd](https://github.com/ReVanced/revanced-cli/commit/16109bd8bc6236debf71cbc8db78fe452b2ed00d))
# [4.4.0-dev.2](https://github.com/ReVanced/revanced-cli/compare/v4.4.0-dev.1...v4.4.0-dev.2) (2023-12-18)
### Bug Fixes
* Add missing punctuation in command description ([8210351](https://github.com/ReVanced/revanced-cli/commit/821035107d7264580275f395e9e3fcef91394afd))
# [4.4.0-dev.1](https://github.com/ReVanced/revanced-cli/compare/v4.3.0...v4.4.0-dev.1) (2023-12-01)
### Features
* Log saved patched APK file path ([16109bd](https://github.com/ReVanced/revanced-cli/commit/16109bd8bc6236debf71cbc8db78fe452b2ed00d))
# [4.3.0](https://github.com/ReVanced/revanced-cli/compare/v4.2.0...v4.3.0) (2023-12-01)
### Features
* Add `list-versions` command ([a974b8e](https://github.com/ReVanced/revanced-cli/commit/a974b8ea80acd85f8dc472a3f93b8fd7bea08007))
# [4.3.0-dev.1](https://github.com/ReVanced/revanced-cli/compare/v4.2.0...v4.3.0-dev.1) (2023-11-27)
### Features
* Add `list-versions` command ([a974b8e](https://github.com/ReVanced/revanced-cli/commit/a974b8ea80acd85f8dc472a3f93b8fd7bea08007))
# [4.2.0](https://github.com/ReVanced/revanced-cli/compare/v4.1.0...v4.2.0) (2023-11-26)
### Bug Fixes
* Fix typo ([#300](https://github.com/ReVanced/revanced-cli/issues/300)) ([9d96bb7](https://github.com/ReVanced/revanced-cli/commit/9d96bb7b4cc4538da416db50bd689af1a632fc45))
### Features
* Allow selecting first Adb device, if none supplied automatically by updating dependencies ([e7c3d64](https://github.com/ReVanced/revanced-cli/commit/e7c3d64bf15bf84f3853e7ef699511bf72c13767))
* Exit application with CLI exit code ([36c6a6a](https://github.com/ReVanced/revanced-cli/commit/36c6a6a5f75f2e770a7941b3f83f430f62de13de))
* Make `--out´ option optional ([3765957](https://github.com/ReVanced/revanced-cli/commit/3765957043989fe7a8932a0c548566a78d04fc41))
# [4.2.0-dev.1](https://github.com/ReVanced/revanced-cli/compare/v4.1.1-dev.1...v4.2.0-dev.1) (2023-11-26)
### Features
* Allow selecting first Adb device, if none supplied automatically by updating dependencies ([e7c3d64](https://github.com/ReVanced/revanced-cli/commit/e7c3d64bf15bf84f3853e7ef699511bf72c13767))
* Exit application with CLI exit code ([36c6a6a](https://github.com/ReVanced/revanced-cli/commit/36c6a6a5f75f2e770a7941b3f83f430f62de13de))
* Make `--out´ option optional ([3765957](https://github.com/ReVanced/revanced-cli/commit/3765957043989fe7a8932a0c548566a78d04fc41))
## [4.1.1-dev.1](https://github.com/ReVanced/revanced-cli/compare/v4.1.0...v4.1.1-dev.1) (2023-11-25)
### Bug Fixes
* Fix typo ([#300](https://github.com/ReVanced/revanced-cli/issues/300)) ([9d96bb7](https://github.com/ReVanced/revanced-cli/commit/9d96bb7b4cc4538da416db50bd689af1a632fc45))
# [4.1.0](https://github.com/ReVanced/revanced-cli/compare/v4.0.2...v4.1.0) (2023-11-04)
### Features
* Include or exclude patches by their index in relation to supplied patch bundles ([b2055ce](https://github.com/ReVanced/revanced-cli/commit/b2055ce07df3ab9a9f3f73ab17d8c2cf02f2ae62))
* List patches which are compatible with any app ([#297](https://github.com/ReVanced/revanced-cli/issues/297)) ([0139dfe](https://github.com/ReVanced/revanced-cli/commit/0139dfe0bfa06a13f56dc03e7718aaf644029614))
### Performance Improvements
* Use a `HashSet` to check for included and excluded patches ([616d14f](https://github.com/ReVanced/revanced-cli/commit/616d14f0097c1ee7ba6dc07be417590f6418e8e5))
# [4.1.0-dev.3](https://github.com/ReVanced/revanced-cli/compare/v4.1.0-dev.2...v4.1.0-dev.3) (2023-11-03)
# [4.1.0-dev.2](https://github.com/ReVanced/revanced-cli/compare/v4.1.0-dev.1...v4.1.0-dev.2) (2023-11-03)
### Features
* Include or exclude patches by their index in relation to supplied patch bundles ([b2055ce](https://github.com/ReVanced/revanced-cli/commit/b2055ce07df3ab9a9f3f73ab17d8c2cf02f2ae62))
### Performance Improvements
* Use a `HashSet` to check for included and excluded patches ([616d14f](https://github.com/ReVanced/revanced-cli/commit/616d14f0097c1ee7ba6dc07be417590f6418e8e5))
# [4.1.0-dev.1](https://github.com/ReVanced/revanced-cli/compare/v4.0.3-dev.2...v4.1.0-dev.1) (2023-11-03)
### Features
* List patches which are compatible with any app ([#297](https://github.com/ReVanced/revanced-cli/issues/297)) ([0139dfe](https://github.com/ReVanced/revanced-cli/commit/0139dfe0bfa06a13f56dc03e7718aaf644029614))
## [4.0.3-dev.2](https://github.com/ReVanced/revanced-cli/compare/v4.0.3-dev.1...v4.0.3-dev.2) (2023-10-30)
## [4.0.3-dev.1](https://github.com/ReVanced/revanced-cli/compare/v4.0.2...v4.0.3-dev.1) (2023-10-23)
## [4.0.2](https://github.com/ReVanced/revanced-cli/compare/v4.0.1...v4.0.2) (2023-10-12)
### Bug Fixes
* Move file to output even when mounting ([59dfc98](https://github.com/ReVanced/revanced-cli/commit/59dfc988e351374eb718923d19bd9bdd94e8d3c0))
* Use punctuation in option descriptions ([da4469f](https://github.com/ReVanced/revanced-cli/commit/da4469f402c26ad95898404236b0acf0202907e2))
### Performance Improvements
* Use multiple threads for writing dex files ([28648a1](https://github.com/ReVanced/revanced-cli/commit/28648a1c53520eef8c799504ff61a35947f878b8))
## [4.0.2-dev.3](https://github.com/ReVanced/revanced-cli/compare/v4.0.2-dev.2...v4.0.2-dev.3) (2023-10-10)
### Bug Fixes
* Move file to output even when mounting ([59dfc98](https://github.com/ReVanced/revanced-cli/commit/59dfc988e351374eb718923d19bd9bdd94e8d3c0))
## [4.0.2-dev.2](https://github.com/ReVanced/revanced-cli/compare/v4.0.2-dev.1...v4.0.2-dev.2) (2023-10-10)
### Performance Improvements
* Use multiple threads for writing dex files ([28648a1](https://github.com/ReVanced/revanced-cli/commit/28648a1c53520eef8c799504ff61a35947f878b8))
## [4.0.2-dev.1](https://github.com/ReVanced/revanced-cli/compare/v4.0.1...v4.0.2-dev.1) (2023-10-08)
### Bug Fixes
* Use punctuation in option descriptions ([da4469f](https://github.com/ReVanced/revanced-cli/commit/da4469f402c26ad95898404236b0acf0202907e2))
## [4.0.1](https://github.com/ReVanced/revanced-cli/compare/v4.0.0...v4.0.1) (2023-10-08)
### Bug Fixes
* Correct warning message ([ba573f7](https://github.com/ReVanced/revanced-cli/commit/ba573f73d0e310fdeb8be2831fd40a7188473fff))
## [4.0.1-dev.1](https://github.com/ReVanced/revanced-cli/compare/v4.0.0...v4.0.1-dev.1) (2023-10-07)
### Bug Fixes
* Correct warning message ([e4e339d](https://github.com/ReVanced/revanced-cli/commit/e4e339dff40542d6265de59496545c859312cf11))
# [4.0.0](https://github.com/ReVanced/revanced-cli/compare/v3.1.1...v4.0.0) (2023-10-04)
### Bug Fixes
* Check, if mounting is possible ([3e13fb5](https://github.com/ReVanced/revanced-cli/commit/3e13fb5d56eb2a90c2a4a1ddfc05852b1f70add5))
* Delete temporal files if it exists ([a022feb](https://github.com/ReVanced/revanced-cli/commit/a022febd0c70807ddc3fa9948207a2a70d5191da))
* Do not sign if mounting ([578e16b](https://github.com/ReVanced/revanced-cli/commit/578e16b099fddfd2bb56accb225d04dfcd409b0c))
* Filter logs correctly ([43fc20d](https://github.com/ReVanced/revanced-cli/commit/43fc20d90e0a694b231b17bb7d9ecfa22bb5d9a0))
* Log correct options command ([#262](https://github.com/ReVanced/revanced-cli/issues/262)) ([96c196d](https://github.com/ReVanced/revanced-cli/commit/96c196dcb14e37ad91b751af61ee8382547c1ca3))
* Log logs with levels over warning to error output stream ([075f6ad](https://github.com/ReVanced/revanced-cli/commit/075f6ad56528a667dca1f0bed704cf7e5381026f))
* Only open files for reading and writing if writeable ([3846f72](https://github.com/ReVanced/revanced-cli/commit/3846f721ca015ab39a7e4b8d3f3d61163a6f1650))
* Only set options for filtered patches ([64d9127](https://github.com/ReVanced/revanced-cli/commit/64d9127291ea9a8abe21a0e82721721495094472))
### Features
* Add function to get the most common compatible version ([77d9173](https://github.com/ReVanced/revanced-cli/commit/77d91735ffbbd6e733f08176f535bfd39ece0c29))
* Add option to filter patches to be listed by package name ([50c0f98](https://github.com/ReVanced/revanced-cli/commit/50c0f98ce5927e07839437a2e550aa85f5a7e62d))
* Add option to warn about patches not being found in supplied patch bundles ([e46d855](https://github.com/ReVanced/revanced-cli/commit/e46d85564320f46c6faa54b2d3fa7fca3fa60019))
* Add ReVanced Library subproject ([#265](https://github.com/ReVanced/revanced-cli/issues/265)) ([157278c](https://github.com/ReVanced/revanced-cli/commit/157278c9ba25f0f786c5fe58e3e23f6890107118))
* Do not format patch names ([80a8d88](https://github.com/ReVanced/revanced-cli/commit/80a8d88406b2b04d13dca4fb0d7d7d62e1910317))
* Extend signing API ([592dc1c](https://github.com/ReVanced/revanced-cli/commit/592dc1c64ae4078e73bb71eba11380b301c79dea))
* Improve option descriptions ([d5ea5a0](https://github.com/ReVanced/revanced-cli/commit/d5ea5a0ab1cc015730063e5be94ee18bd88cc906))
* Log stacktrace in new line ([c67e3c7](https://github.com/ReVanced/revanced-cli/commit/c67e3c70c7eaa514cde1bebe775a2216bc4a6074))
* Use ReVanced Library in ReVanced CLI ([7794327](https://github.com/ReVanced/revanced-cli/commit/7794327a11e8a0e0f28176cd45fad797b924c45f))
* Word log message better ([6942b22](https://github.com/ReVanced/revanced-cli/commit/6942b22a68de5e991987ea89882915917aec93a3))
### Performance Improvements
* Do not check, if the options file exists twice ([e3c5550](https://github.com/ReVanced/revanced-cli/commit/e3c55507cf52e697b9ce9d59decc1cbe4cfe5b43))
### BREAKING CHANGES
* This changes many signatures of existing APIs and adds new functions for signing
* This changes the log handler signature
# [4.0.0-dev.5](https://github.com/ReVanced/revanced-cli/compare/v4.0.0-dev.4...v4.0.0-dev.5) (2023-10-04)

View File

@ -6,53 +6,72 @@
srcset="assets/revanced-headline/revanced-headline-vertical-dark.svg"
>
<img
width="256px"
src="assets/revanced-headline/revanced-headline-vertical-light.svg"
>
</picture>
<br>
<a href="https://revanced.app/">
<img height="24px" src="assets/revanced-logo/revanced-logo-round.svg" />
<picture>
<source height="24px" media="(prefers-color-scheme: dark)" srcset="assets/revanced-logo/revanced-logo.svg" />
<img height="24px" src="assets/revanced-logo/revanced-logo.svg" />
</picture>
</a>&nbsp;&nbsp;&nbsp;
<a href="https://github.com/revanced">
<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>&nbsp;&nbsp;&nbsp;
<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>&nbsp;&nbsp;&nbsp;
<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>&nbsp;&nbsp;&nbsp;
<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>&nbsp;&nbsp;&nbsp;
<a href="https://twitter.com/revancedapp">
<img height="24px" src="https://user-images.githubusercontent.com/13122796/178032018-6da37214-7474-4641-a1da-7af7db3a31cd.png" />
<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>&nbsp;&nbsp;&nbsp;
<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" />
</a>&nbsp;&nbsp;&nbsp;
</picture>
</a>
<br>
<br>
Continuing the legacy of Vanced
</p>
# 📙 ReVanced CLI contribution guidelines
# 👋 Contribution guidelines
This document describes how to contribute to ReVanced CLI.
## 📖 Resources to help you get started
* The [documentation](/docs) explains how to use ReVanced CLI
* [Our backlog](https://github.com/orgs/ReVanced/projects/12) is where we keep track of what we're working on
* [Issues](https://github.com/ReVanced/revanced-cli/issues) are where we keep track of bugs and feature requests
- The [documentation](/docs) explains how to use ReVanced CLI
- [Our backlog](https://github.com/orgs/ReVanced/projects/12) is where we keep track of what we're working on
- [Issues](https://github.com/ReVanced/revanced-cli/issues) are where we keep track of bugs and feature requests
## 🙏 Submitting a feature request
Features can be requested by opening an issue using the
[Feature request issue template](https://github.com/ReVanced/revanced-cli/issues/new?assignees=&labels=Feature+request&projects=&template=feature-request.yml&title=feat%3A+).
[Feature request issue template](https://github.com/ReVanced/revanced-cli/issues/new?assignees=&labels=Feature+request&projects=&template=feature_request.yml&title=feat%3A+).
> **Note**
> Requests can be accepted or rejected at the discretion of maintainers of ReVanced CLI.
@ -61,7 +80,7 @@ Features can be requested by opening an issue using the
## 🐞 Submitting a bug report
If you encounter a bug while using ReVanced CLI, open an issue using the
[Bug report issue template](https://github.com/ReVanced/revanced-cli/issues/new?assignees=&labels=Bug+report&projects=&template=bug-report.yml&title=bug%3A+).
[Bug report issue template](https://github.com/ReVanced/revanced-cli/issues/new?assignees=&labels=Bug+report&projects=&template=bug_report.yml&title=bug%3A+).
## 📝 How to contribute
@ -69,7 +88,7 @@ If you encounter a bug while using ReVanced CLI, open an issue using the
with the maintainers of ReVanced CLI. This will help you determine whether your change is acceptable
and whether it is worth your time to implement it
2. Development happens on the `dev` branch. Fork the repository and create your branch from `dev`
3. Commit your changes.
3. Commit your changes
4. Submit a pull request to the `dev` branch of the repository and reference issues
that your pull request closes in the description of your pull request
5. Our team will review your pull request and provide feedback. Once your pull request is approved,

View File

@ -6,56 +6,84 @@
srcset="assets/revanced-headline/revanced-headline-vertical-dark.svg"
>
<img
width="256px"
src="assets/revanced-headline/revanced-headline-vertical-light.svg"
>
</picture>
<br>
<a href="https://revanced.app/">
<img height="24px" src="assets/revanced-logo/revanced-logo-round.svg" />
<picture>
<source height="24px" media="(prefers-color-scheme: dark)" srcset="assets/revanced-logo/revanced-logo.svg" />
<img height="24px" src="assets/revanced-logo/revanced-logo.svg" />
</picture>
</a>&nbsp;&nbsp;&nbsp;
<a href="https://github.com/revanced">
<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>&nbsp;&nbsp;&nbsp;
<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>&nbsp;&nbsp;&nbsp;
<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>&nbsp;&nbsp;&nbsp;
<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>&nbsp;&nbsp;&nbsp;
<a href="https://twitter.com/revancedapp">
<img height="24px" src="https://user-images.githubusercontent.com/13122796/178032018-6da37214-7474-4641-a1da-7af7db3a31cd.png" />
<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>&nbsp;&nbsp;&nbsp;
<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" />
</a>&nbsp;&nbsp;&nbsp;
</picture>
</a>
<br>
<br>
Continuing the legacy of Vanced
</p>
# 💻 ReVanced CLI
![GitHub Workflow Status (with event)](https://img.shields.io/github/actions/workflow/status/ReVanced/revanced-cli/release.yml)
![GPLv3 License](https://img.shields.io/badge/License-GPL%20v3-yellow.svg)
Command line application to use ReVanced.
Command-line application to use ReVanced.
## ❓ About
ReVanced CLI is a command line application to patch apps using ReVanced.
ReVanced CLI also comes with commands to uninstall or install patched apps and list patches from supplied patch bundles.
ReVanced CLI is a command-line application that uses [ReVanced Patcher](https://github.com/revanced/revanced-patcher) to patch Android apps.
## 🚀 Download
## 💪 Features
Some of the features ReVanced CLI provides are:
- 💉 **Patch apps**: Harness ReVanced Patcher to patch Android apps
- 💾 **Install and uninstall apps**: Install and uninstall Apps via ADB,
using the Android package manager or by mounting using root permissions
- 📃 **List patches from patch bundles**: List available patches, compatible packages, and versions
- 💪 **Flexibility and functionality**: Apply any combination of patches to any version of Android apps
## 🔽 Download
You can download the most recent version of ReVanced CLI from
[here](https://github.com/ReVanced/revanced-cli/releases/latest). Learn how to use ReVanced CLI by following the [documentation](/docs).
[here](https://github.com/ReVanced/revanced-cli/releases/latest).
Learn how to use ReVanced CLI by following the [documentation](/docs).
## 📚 Everything else
@ -66,10 +94,14 @@ You can find the contribution guidelines [here](CONTRIBUTING.md).
### 🛠️ Building
In order to build ReVanced CLI, you can follow the [documentation](/docs).
To build a ReVanced CLI, you can follow the [documentation](/docs).
### 📃 Documentation
You can find the documentation of ReVanced CLI [here](/docs).
## 📜 Licence
ReVanced CLI is licensed under the GPLv3 licence. Please see the [licence file](LICENSE) for more information.
ReVanced CLI is licensed under the GPLv3 license. Please see the [license file](LICENSE) for more information.
[tl;dr](https://www.tldrlegal.com/license/gnu-general-public-license-v3-gpl-3) you may copy, distribute and modify ReVanced CLI as long as you track changes/dates in source files.
Any modifications to ReVanced CLI must also be made available under the GPL along with build & install instructions.
Any modifications to ReVanced CLI must also be made available under the GPL, along with build & install instructions.

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

View File

@ -0,0 +1 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg width="100%" height="100%" viewBox="0 0 800 800" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;"><g id="Logo"><g id="Ring"><circle id="Ring-Background" serif:id="Ring Background" cx="400" cy="400" r="400" style="fill:#1b1b1b;"/><path id="Ring1" serif:id="Ring" d="M400,0c220.766,0 400,179.234 400,400c-0,220.766 -179.234,400 -400,400c-220.766,-0 -400,-179.234 -400,-400c0,-220.766 179.234,-400 400,-400Zm-0,36c200.897,-0 364,163.103 364,364c0,200.897 -163.103,364 -364,364c-200.897,0 -364,-163.103 -364,-364c-0,-200.897 163.103,-364 364,-364Z" style="fill:url(#_Linear1);"/></g><g id="Shape"><path id="V-Shape" serif:id="V Shape" d="M538.74,269.872c1.481,-3.382 1.157,-7.283 -0.863,-10.373c-2.021,-3.091 -5.464,-4.954 -9.156,-4.954c-5.148,0 -10.435,0 -14.165,0c-3.1,0 -5.907,1.834 -7.153,4.672c-12.468,28.396 -78.273,178.273 -100.25,228.328c-1.246,2.838 -4.053,4.671 -7.154,4.671c-3.1,0 -5.907,-1.833 -7.153,-4.671c-21.977,-50.055 -87.782,-199.932 -100.25,-228.328c-1.246,-2.838 -4.053,-4.672 -7.153,-4.672c-3.73,0 -9.017,0 -14.164,0c-3.693,0 -7.135,1.863 -9.156,4.954c-2.02,3.09 -2.344,6.991 -0.863,10.373c23.557,53.766 101.872,232.519 117.871,269.034c1.743,3.979 5.674,6.549 10.018,6.549c6.293,-0 15.408,-0 21.701,-0c4.344,-0 8.275,-2.57 10.018,-6.549c15.999,-36.515 94.315,-215.268 117.872,-269.034Z" style="fill:#fff;"/><path id="Diamond" d="M408.119,395.312c-1.675,2.901 -4.77,4.688 -8.119,4.688c-3.349,-0 -6.444,-1.787 -8.119,-4.688c-16.997,-29.44 -56.156,-97.264 -73.153,-126.704c-1.675,-2.901 -1.675,-6.474 0,-9.375c1.675,-2.901 4.77,-4.688 8.119,-4.688c33.995,0 112.311,0 146.306,0c3.349,0 6.444,1.787 8.119,4.688c1.675,2.901 1.675,6.474 -0,9.375c-16.997,29.44 -56.156,97.264 -73.153,126.704Z" style="fill:url(#_Linear2);"/></g></g><defs><linearGradient id="_Linear1" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(4.89859e-14,800,-800,4.89859e-14,400.001,3.31681e-10)"><stop offset="0" style="stop-color:#f04e98;stop-opacity:1"/><stop offset="0.5" style="stop-color:#5f65d4;stop-opacity:1"/><stop offset="1" style="stop-color:#4e98f0;stop-opacity:1"/></linearGradient><linearGradient id="_Linear2" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.77155e-14,289.317,-282.535,1.73003e-14,400,254.545)"><stop offset="0" style="stop-color:#f04e98;stop-opacity:1"/><stop offset="0.5" style="stop-color:#5f65d4;stop-opacity:1"/><stop offset="1" style="stop-color:#4e98f0;stop-opacity:1"/></linearGradient></defs></svg>

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

@ -1,10 +1,32 @@
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
plugins {
kotlin("jvm") version "1.9.0"
alias(libs.plugins.kotlin)
alias(libs.plugins.shadow)
application
`maven-publish`
signing
}
group = "app.revanced"
application {
mainClass = "app.revanced.cli.command.MainCommandKt"
}
repositories {
mavenCentral()
google()
maven {
// A repository must be specified for some reason. "registry" is a dummy.
url = uri("https://maven.pkg.github.com/revanced/registry")
credentials {
username = project.findProperty("gpr.user") as String? ?: System.getenv("GITHUB_ACTOR")
password = project.findProperty("gpr.key") as String? ?: System.getenv("GITHUB_TOKEN")
}
}
}
dependencies {
implementation(libs.revanced.patcher)
implementation(libs.revanced.library)
@ -14,7 +36,15 @@ dependencies {
testImplementation(libs.kotlin.test)
}
kotlin { jvmToolchain(11) }
kotlin {
compilerOptions {
jvmTarget.set(JvmTarget.JVM_11)
}
}
java {
targetCompatibility = JavaVersion.VERSION_11
}
tasks {
test {
@ -29,35 +59,36 @@ tasks {
}
shadowJar {
manifest {
attributes("Main-Class" to "app.revanced.cli.command.MainCommandKt")
}
exclude("/prebuilt/linux/aapt", "/prebuilt/windows/aapt.exe", "/prebuilt/*/aapt_*")
minimize {
exclude(dependency("org.jetbrains.kotlin:.*"))
exclude(dependency("org.bouncycastle:.*"))
exclude(dependency("app.revanced:.*"))
exclude(dependency("app.revanced:revanced-patcher"))
}
}
build {
publish {
dependsOn(shadowJar)
}
}
/*
Dummy task to hack gradle-semantic-release-plugin to release this project.
// Needed by gradle-semantic-release-plugin.
// Tracking: https://github.com/KengoTODA/gradle-semantic-release-plugin/issues/435
Explanation:
SemVer is a standard for versioning libraries.
For that reason the semantic-release plugin uses the "publish" task to publish libraries.
However, this subproject is not a library, and the "publish" task is not available for this subproject.
Because semantic-release is not designed to handle this case, we need to hack it.
// The maven-publish is also necessary to make the signing plugin work.
publishing {
repositories {
mavenLocal()
}
RE: https://github.com/KengoTODA/gradle-semantic-release-plugin/issues/435
*/
register<DefaultTask>("publish") {
group = "publishing"
description = "Dummy task to hack gradle-semantic-release-plugin to release ReVanced CLI"
dependsOn(build)
publications {
create<MavenPublication>("revanced-cli-publication") {
from(components["java"])
}
}
}
signing {
useGpgCmd()
sign(publishing.publications["revanced-cli-publication"])
}

View File

@ -1,14 +1,12 @@
# 💼 Prerequisites
To use ReVanced CLI, you will need to fulfil specific requirements.
To use ReVanced CLI, you will need to fulfill specific requirements.
## 🤝 Requirements
- Java SDK 11 (Azul Zulu JDK or OpenJDK)
- [Android Debug Bridge (adb)](https://developer.android.com/studio/command-line/adb) if you want to install the patched APK file on your device
- An ABI other than ARMv7 such as x86 or x86-64 (or a custom AAPT binary that supports ARMv7)
- ReVanced Patches
- ReVanced Integrations, if the patches require it
- Java Runtime Environment 11 ([Azul Zulu JRE](https://www.azul.com/downloads/?version=java-11-lts&package=jre#zulu) or [OpenJDK](https://jdk.java.net/archive/))
- [Android Debug Bridge (ADB)](https://developer.android.com/studio/command-line/adb) if you want to install the patched APK file on your device
- x86 or x86-64 (For [other architectures](https://github.com/ReVanced/revanced-manager/tree/main/android/app/src/main/jniLibs) use the `--custom-aapt2-binary` option)
## ⏭️ Whats next

View File

@ -1,111 +1,171 @@
# 🛠️ Using ReVanced CLI
Learn how to ReVanced CLI.
Learn how to use ReVanced CLI.
The following examples will show you how to perform basic operations.
You can list patches, patch an app, uninstall, and install an app.
## ⚡ Setup ADB
1. Ensure that ADB is working
```bash
adb shell exit
```
Optionally, you can install the patched APK file on your device by mounting it on top of the original APK file.
You will need root permissions for this. Check if you have root permissions by running the following command:
```bash
adb shell su -c exit
```
2. Get your device's serial
```bash
adb devices
```
## 🔨 Using ReVanced CLI
- ### ⚙️ Show all available options for ReVanced CLI
## 🚀 Show all commands
```bash
java -jar revanced-cli.jar -h
```
- ### 📃 List patches from supplied patch bundles
## 📃 List patches
```bash
java -jar revanced-cli.jar list-patches \
--with-packages \
--with-versions \
--with-options \
revanced-patches.jar [<patch-bundle> ...]
java -jar revanced-cli.jar list-patches --with-packages --with-versions --with-options patches.rvp
```
- ### ⚙️ Generate options from patches using ReVanced CLI
## 💉 Patch an app
This will generate an `options.json` file for the patches from a list of supplied patch bundles.
The file can be supplied to ReVanced CLI later on.
- ```bash
java -jar revanced-cli.jar options \
--path options.json \
--overwrite \
revanced-patches.jar [<patch-bundle> ...]
```
> **Note**: A default `options.json` file will be automatically generated, if it does not exist
without any need for intervention when using the `patch` command.
- ### 💉 Use ReVanced CLI to patch an APK file but install without root permissions
This will install the patched APK file regularly on your device.
To patch an app using the default list of patches, use the `patch` command:
```bash
java -jar revanced-cli.jar patch \
--patch-bundle revanced-patches.jar \
--out output.apk \
--device-serial <device-serial> \
input.apk
java -jar revanced-cli.jar patch -p patches.rvp input.apk
```
- ### 👾 Use ReVanced CLI to patch an APK file but install with root permissions
This will install the patched APK file on your device by mounting it on top of the original APK file.
You can also use multiple RVP files:
```bash
adb install input.apk
java -jar revanced-cli.jar patch \
--patch-bundle revanced-patches.jar \
--include some-other-patch \
--exclude some-patch \
--out patched-output.apk \
--device-serial <device-serial> \
--mount \
input.apk
java -jar revanced-cli.jar patch -p patches.rvp -p another-patches.rvp input.apk
```
> **Note**: Some patches may require integrations
such as [ReVanced Integrations](https://github.com/revanced/revanced-integrations).
Supply them with the option `--merge`. If any patches accepted by ReVanced Patcher require ReVanced Integrations,
they will be merged into the APK file automatically.
To change the default set of enabled or disabled patches, use the option `-e` or `-d` to enable or disable specific patches.
You can use the `list-patches` command to see which patches are enabled by default.
- ### 🗑️ Uninstall a patched APK file
```bash
java -jar revanced-cli.jar utility uninstall \
--package-name <package-name> \
<device-serial>
```
> **Note**: You can unmount an APK file
with the option `--unmount`.
- ### ⚙️ Manually install an APK file
To only enable specific patches, you can use the option `--exclusive` combined with `-e`.
Remember that the options `-e` and `-d` match the patch's name exactly. Here is an example:
```bash
java -jar revanced-cli.jar utility install \
-a input.apk \
<device-serial>
java -jar revanced-cli.jar patch -p patches.rvp --exclusive -e "Patch name" -e "Another patch name" input.apk
```
> **Note**: You can mount an APK file
by supplying the package name of the app to mount the supplied APK file to over the option `--mount`.
You can also use the options `--ei` or `--di` to enable or disable patches by their index.
This is useful, if two patches happen to have the same name, or if typing the names is too cumbersome.
To know the indices of patches, use the command `list-patches`:
```bash
java -jar revanced-cli.jar list-patches patches.rvp
```
Then you can use the indices to enable or disable patches:
```bash
java -jar revanced-cli.jar patch -p patches.rvp --ei 123 --di 456 input.apk
```
You can combine the option `-e`, `-d`, `--ei`, `--di` and `--exclusive`. Here is an example:
```bash
java -jar revanced-cli.jar patch -p patches.rvp --exclusive -e "Patch name" --ei 123 input.apk
```
> [!TIP]
> You can use the option `-i` to automatically install the patched app after patching.
> Make sure ADB is working:
>
> ```bash
> adb shell exit
> ```
> [!TIP]
> You can use the option `--mount` to mount the patched app on top of the un-patched app.
> Make sure you have root permissions and the same app you are patching and mounting over is installed on your device:
>
> ```bash
> adb shell su -c exit
> adb install input.apk
> ```
Patches can have options you can set using the option `-O` alongside the option to include the patch by name or index.
To know the options of a patch, use the option `--with-options` when listing patches:
```bash
java -jar revanced-cli.jar list-patches --with-options patches.rvp
```
Each patch can have multiple options. You can set them using the option `-O`.
For example, to set the options for the patch with the name `Patch name`
with the key `key1` and `key2` to `value1` and `value2` respectively, use the following command:
```bash
java -jar revanced-cli.jar patch -p patches.rvp -e "Patch name" -Okey1=value1 -Okey2=value2 input.apk
```
If you want to set the option value to `null`, you can omit the value:
```bash
java -jar revanced-cli.jar patch -p patches.rvp -i "Patch name" -Okey1 input.apk
```
> [!WARNING]
> Option values are usually typed. If you set a value with the wrong type, the patch can fail.
> The value types can be seen when listing patches with the option `--with-options`.
>
> Example option values:
>
> - String: `string`
> - Boolean: `true`, `false`
> - Integer: `123`
> - Double: `1.0`
> - Float: `1.0f`
> - Long: `1234567890`, `1L`
> - List: `[item1,item2,item3]`
> - List of type `Any`: `[item1,123,true,1.0]`
> - Empty list of type `Any`: `[]`
> - Typed empty list: `int[]`
> - Typed and nested empty list: `[int[]]`
> - List with null value and two empty strings: `[null,\'\',\"\"]`
>
> Quotes and commas escaped in strings (`\"`, `\'`, `\,`) are parsed as part of the string.
> List items are recursively parsed, so you can escape values in lists:
>
> - Escaped integer as a string: `[\'123\']`
> - Escaped boolean as a string: `[\'true\']`
> - Escaped list as a string: `[\'[item1,item2]\']`
> - Escaped null value as a string: `[\'null\']`
> - List with an integer, an integer as a string and a string with a comma, and an escaped list: [`123,\'123\',str\,ing`,`\'[]\'`]
>
> Example command with an escaped integer as a string:
>
> ```bash
> java -jar revanced-cli.jar -p patches.rvp -e "Patch name" -OstringKey=\'1\' input.apk
> ```
## 📦 Install an app manually
```bash
java -jar revanced-cli.jar utility install -a input.apk
```
> [!TIP]
> You can use the option `--mount` to mount the patched app on top of the un-patched app.
> Make sure you have root permissions and the same app you are patching and mounting over is installed on your device:
>
> ```bash
> adb shell su -c exit
> adb install input.apk
> ```
## 🗑️ Uninstall an app manually
Here `<package-name>` is the package name of the app you want to uninstall:
```bash
java -jar revanced-cli.jar utility uninstall --package-name <package-name>
```
If the app is mounted, you need to unmount it by using the option `--unmount`:
```bash
java -jar revanced-cli.jar utility uninstall --package-name <package-name> --unmount
```
> [!TIP]
> By default, the app is installed or uninstalled to the first connected device.
> You can append one or more devices by their serial to install or uninstall an app on your selected choice of devices:
>
> ```bash
> java -jar revanced-cli.jar utility uninstall --package-name <package-name> [<device-serial> ...]
> ```

37
docs/2_building.md Normal file
View File

@ -0,0 +1,37 @@
# 🔨️ Building
Build ReVanced CLI from source.
## 📝 Requirements
- Java Development Kit 11 (Azul Zulu JRE or OpenJDK)
## 🏗️ Building
To build ReVanced CLI, follow these steps:
1. Clone the repository:
```bash
git clone git@github.com:ReVanced/revanced-cli.git
cd revanced-cli
```
2. Build the project:
```bash
./gradlew build
```
> [!NOTE]
> If the build fails due to authentication, you may need to authenticate to GitHub Packages.
> Create a PAT with the scope `read:packages` [here](https://github.com/settings/tokens/new?scopes=read:packages&description=ReVanced) and add your token to ~/.gradle/gradle.properties.
>
> Example `gradle.properties` file:
>
> ```properties
> gpr.user = user
> gpr.key = key
> ```
After the build succeeds, the built JAR file will be located at `build/libs/revanced-cli-<version>-all.jar`.

View File

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

View File

@ -1,4 +1,4 @@
org.gradle.parallel = true
org.gradle.caching = true
kotlin.code.style = official
version = 4.0.0-dev.5
version = 5.0.1

View File

@ -1,17 +1,18 @@
[versions]
shadow = "8.1.1"
kotlin-test = "1.8.20-RC"
kotlinx-coroutines-core = "1.7.3"
picocli = "4.7.3"
revanced-patcher = "16.0.0"
revanced-library = "1.1.1"
kotlin = "2.0.20"
kotlinx = "1.8.1"
picocli = "4.7.6"
revanced-patcher = "21.0.0"
revanced-library = "3.1.0"
[libraries]
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" }
kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlin" }
kotlinx-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "kotlinx" }
picocli = { module = "info.picocli:picocli", version.ref = "picocli" }
revanced-patcher = { module = "app.revanced:revanced-patcher", version.ref = "revanced-patcher" }
revanced-library = { module = "app.revanced:revanced-library", version.ref = "revanced-library" }
revanced-library = { module = "app.revanced:revanced-library-jvm", version.ref = "revanced-library" }
[plugins]
shadow = { id = "com.github.johnrengelman.shadow", version.ref = "shadow" }
kotlin = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" }

Binary file not shown.

View File

@ -1,6 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip
distributionSha256Sum=d725d707bfabd4dfdc958c624003b3c80accc03f7037b5122c4b1d0ef15cecab
distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME

17
gradlew vendored
View File

@ -83,7 +83,8 @@ done
# This is normally unused
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
@ -144,7 +145,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC3045
# shellcheck disable=SC2039,SC3045
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
@ -152,7 +153,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
'' | soft) :;; #(
*)
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC3045
# shellcheck disable=SC2039,SC3045
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
@ -201,11 +202,11 @@ fi
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Collect all arguments for the java command;
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
# shell script including quotes and variable substitutions, so put them in
# double quotes to make sure that they get re-expanded; and
# * put everything else in single quotes, so that it's not re-expanded.
# Collect all arguments for the java command:
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# and any embedded shellness will be escaped.
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
# treated as '${Hostname}' itself on the command line.
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \

20
gradlew.bat vendored
View File

@ -43,11 +43,11 @@ set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if %ERRORLEVEL% equ 0 goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
echo. 1>&2
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
goto fail
@ -57,11 +57,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
echo. 1>&2
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
goto fail

6799
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -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.10.1",
"semantic-release": "^24.1.2"
}
}

View File

@ -1,23 +1 @@
val githubUsername: String = providers.gradleProperty("gpr.user").orNull ?: System.getenv("GITHUB_ACTOR")
val githubPassword: String = providers.gradleProperty("gpr.key").orNull ?: System.getenv("GITHUB_TOKEN")
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
mavenCentral()
mavenLocal()
google()
maven { url = uri("https://jitpack.io") }
listOf("revanced-patcher", "jadb").forEach { repo ->
maven {
url = uri("https://maven.pkg.github.com/revanced/$repo")
credentials {
username = githubUsername
password = githubPassword
}
}
}
}
}
rootProject.name = "revanced-cli"

View File

@ -0,0 +1,105 @@
package app.revanced.cli.command
import picocli.CommandLine
class OptionKeyConverter : CommandLine.ITypeConverter<String> {
override fun convert(value: String): String = value
}
class OptionValueConverter : CommandLine.ITypeConverter<Any?> {
override fun convert(value: String?): Any? {
value ?: return null
return when {
value.startsWith("[") && value.endsWith("]") -> {
val innerValue = value.substring(1, value.length - 1)
buildList {
var nestLevel = 0
var insideQuote = false
var escaped = false
val item = buildString {
for (char in innerValue) {
when (char) {
'\\' -> {
if (escaped || nestLevel != 0) {
append(char)
}
escaped = !escaped
}
'"', '\'' -> {
if (!escaped) {
insideQuote = !insideQuote
} else {
escaped = false
}
append(char)
}
'[' -> {
if (!insideQuote) {
nestLevel++
}
append(char)
}
']' -> {
if (!insideQuote) {
nestLevel--
if (nestLevel == -1) {
return value
}
}
append(char)
}
',' -> if (nestLevel == 0) {
if (insideQuote) {
append(char)
} else {
add(convert(toString()))
setLength(0)
}
} else {
append(char)
}
else -> append(char)
}
}
}
if (item.isNotEmpty()) {
add(convert(item))
}
}
}
value.startsWith("\"") && value.endsWith("\"") -> value.substring(1, value.length - 1)
value.startsWith("'") && value.endsWith("'") -> value.substring(1, value.length - 1)
value.endsWith("f") -> value.dropLast(1).toFloat()
value.endsWith("L") -> value.dropLast(1).toLong()
value.equals("true", ignoreCase = true) -> true
value.equals("false", ignoreCase = true) -> false
value.toIntOrNull() != null -> value.toInt()
value.toLongOrNull() != null -> value.toLong()
value.toDoubleOrNull() != null -> value.toDouble()
value.toFloatOrNull() != null -> value.toFloat()
value == "null" -> null
value == "int[]" -> emptyList<Int>()
value == "long[]" -> emptyList<Long>()
value == "double[]" -> emptyList<Double>()
value == "float[]" -> emptyList<Float>()
value == "boolean[]" -> emptyList<Boolean>()
value == "string[]" -> emptyList<String>()
else -> value
}
}
}

View File

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

View File

@ -1,98 +1,147 @@
package app.revanced.cli.command
import app.revanced.patcher.PatchBundleLoader
import app.revanced.patcher.patch.Package
import app.revanced.patcher.patch.Patch
import app.revanced.patcher.patch.options.PatchOption
import app.revanced.patcher.patch.loadPatchesFromJar
import picocli.CommandLine.*
import picocli.CommandLine.Help.Visibility.ALWAYS
import java.io.File
import java.util.logging.Logger
import app.revanced.patcher.patch.Option as PatchOption
@Command(name = "list-patches", description = ["List patches from supplied patch bundles"])
@Command(
name = "list-patches",
description = ["List patches from supplied RVP files."],
)
internal object ListPatchesCommand : Runnable {
private val logger = Logger.getLogger(ListPatchesCommand::class.java.name)
private val logger = Logger.getLogger(this::class.java.name)
@Parameters(
description = ["Paths to patch bundles"], arity = "1..*"
description = ["Paths to RVP files."],
arity = "1..*",
)
private lateinit var patchBundles: Array<File>
private lateinit var patchesFiles: Set<File>
@Option(
names = ["-d", "--with-descriptions"], description = ["List their descriptions"], showDefaultValue = ALWAYS
names = ["-d", "--with-descriptions"],
description = ["List their descriptions."],
showDefaultValue = ALWAYS,
)
private var withDescriptions: Boolean = true
@Option(
names = ["-p", "--with-packages"],
description = ["List the packages the patches are compatible with"],
showDefaultValue = ALWAYS
description = ["List the packages the patches are compatible with."],
showDefaultValue = ALWAYS,
)
private var withPackages: Boolean = false
@Option(
names = ["-v", "--with-versions"],
description = ["List the versions of the apps the patches are compatible with"],
showDefaultValue = ALWAYS
description = ["List the versions of the apps the patches are compatible with."],
showDefaultValue = ALWAYS,
)
private var withVersions: Boolean = false
@Option(
names = ["-o", "--with-options"], description = ["List the options of the patches"], showDefaultValue = ALWAYS
names = ["-o", "--with-options"],
description = ["List the options of the patches."],
showDefaultValue = ALWAYS,
)
private var withOptions: Boolean = false
@Option(
names = ["-f", "--filter-package-name"], description = ["Filter patches by package name"]
names = ["-u", "--with-universal-patches"],
description = ["List patches which are compatible with any app."],
showDefaultValue = ALWAYS,
)
private var withUniversalPatches: Boolean = true
@Option(
names = ["-i", "--index"],
description = ["List the index of each patch in relation to the supplied RVP files."],
showDefaultValue = ALWAYS,
)
private var withIndex: Boolean = true
@Option(
names = ["-f", "--filter-package-name"],
description = ["Filter patches by package name."],
)
private var packageName: String? = null
override fun run() {
fun Patch.CompatiblePackage.buildString() = buildString {
fun Package.buildString(): String {
val (name, versions) = this
return buildString {
if (withVersions && versions != null) {
appendLine("Package name: $name")
appendLine("Compatible versions:")
append(versions!!.joinToString("\n") { version -> version }.prependIndent("\t"))
} else append("Package name: $name")
append(versions.joinToString("\n") { version -> version }.prependIndent("\t"))
} else {
append("Package name: $name")
}
}
}
fun PatchOption<*>.buildString() = buildString {
fun PatchOption<*>.buildString() =
buildString {
appendLine("Title: $title")
appendLine("Description: $description")
value?.let {
description?.let { appendLine("Description: $it") }
appendLine("Required: $required")
default?.let {
appendLine("Key: $key")
append("Value: $it")
append("Default: $it")
} ?: append("Key: $key")
values?.let { values ->
appendLine("\nPossible values:")
append(values.map { "${it.value} (${it.key})" }.joinToString("\n").prependIndent("\t"))
}
fun Patch<*>.buildString() = buildString {
append("Name: $name")
append("\nType: $type")
}
if (withDescriptions) append("\nDescription: $description")
fun IndexedValue<Patch<*>>.buildString() =
let { (index, patch) ->
buildString {
if (withIndex) appendLine("Index: $index")
if (withOptions && options.isNotEmpty()) {
append("Name: ${patch.name}")
if (withDescriptions) append("\nDescription: ${patch.description}")
append("\nEnabled: ${patch.use}")
if (withOptions && patch.options.isNotEmpty()) {
appendLine("\nOptions:")
append(
options.values.joinToString("\n\n") { option ->
patch.options.values.joinToString("\n\n") { option ->
option.buildString()
}.prependIndent("\t")
}.prependIndent("\t"),
)
}
if (withPackages && compatiblePackages != null) {
if (withPackages && patch.compatiblePackages != null) {
appendLine("\nCompatible packages:")
append(
compatiblePackages!!.joinToString("\n") { it.buildString() }.prependIndent("\t")
patch.compatiblePackages!!.joinToString("\n") {
it.buildString()
}.prependIndent("\t"),
)
}
}
}
fun Patch<*>.anyPackageName(name: String) = compatiblePackages?.any { it.name == name } == true
fun Patch<*>.filterCompatiblePackages(name: String) =
compatiblePackages?.any { (compatiblePackageName, _) -> compatiblePackageName == name }
?: withUniversalPatches
val patches = PatchBundleLoader.Jar(*patchBundles)
val patches = loadPatchesFromJar(patchesFiles).withIndex().toList()
val filtered = packageName?.let { patches.filter { patch -> patch.anyPackageName(it) } } ?: patches
val filtered =
packageName?.let { patches.filter { (_, patch) -> patch.filterCompatiblePackages(it) } } ?: patches
if (filtered.isNotEmpty()) logger.info(filtered.joinToString("\n\n") { it.buildString() })
}

View File

@ -7,33 +7,36 @@ import picocli.CommandLine.Command
import picocli.CommandLine.IVersionProvider
import java.util.*
fun main(args: Array<String>) {
Logger.setDefault()
CommandLine(MainCommand).execute(*args)
CommandLine(MainCommand).execute(*args).let(System::exit)
}
private object CLIVersionProvider : IVersionProvider {
override fun getVersion() = arrayOf(
override fun getVersion() =
arrayOf(
MainCommand::class.java.getResourceAsStream(
"/app/revanced/cli/version.properties"
"/app/revanced/cli/version.properties",
)?.use { stream ->
Properties().apply { load(stream) }.let {
Properties().apply {
load(stream)
}.let {
"ReVanced CLI v${it.getProperty("version")}"
}
} ?: "ReVanced CLI")
} ?: "ReVanced CLI",
)
}
@Command(
name = "revanced-cli",
description = ["Command line application to use ReVanced"],
description = ["Command line application to use ReVanced."],
mixinStandardHelpOptions = true,
versionProvider = CLIVersionProvider::class,
subcommands = [
ListPatchesCommand::class,
PatchCommand::class,
OptionsCommand::class,
ListPatchesCommand::class,
ListCompatibleVersions::class,
UtilityCommand::class,
]
],
)
private object MainCommand

View File

@ -1,54 +0,0 @@
package app.revanced.cli.command
import app.revanced.library.Options
import app.revanced.library.Options.setOptions
import app.revanced.patcher.PatchBundleLoader
import picocli.CommandLine
import picocli.CommandLine.Help.Visibility.ALWAYS
import java.io.File
import java.util.logging.Logger
@CommandLine.Command(
name = "options",
description = ["Generate options file from patches"],
)
internal object OptionsCommand : Runnable {
private val logger = Logger.getLogger(OptionsCommand::class.java.name)
@CommandLine.Parameters(
description = ["Paths to patch bundles"], arity = "1..*"
)
private lateinit var patchBundles: Array<File>
@CommandLine.Option(
names = ["-p", "--path"], description = ["Path to patch options JSON file"], showDefaultValue = ALWAYS
)
private var filePath: File = File("options.json")
@CommandLine.Option(
names = ["-o", "--overwrite"], description = ["Overwrite existing options file"], showDefaultValue = ALWAYS
)
private var overwrite: Boolean = false
@CommandLine.Option(
names = ["-u", "--update"],
description = ["Update existing options by adding missing and removing non-existent options"],
showDefaultValue = ALWAYS
)
private var update: Boolean = false
override fun run() = try {
PatchBundleLoader.Jar(*patchBundles).let { patches ->
val exists = filePath.exists()
if (!exists || overwrite) {
if (exists && update) patches.setOptions(filePath)
Options.serialize(patches, prettyPrint = true).let(filePath::writeText)
} else throw OptionsFileAlreadyExistsException()
}
} catch (ex: OptionsFileAlreadyExistsException) {
logger.severe("Options file already exists, use --overwrite to override it")
}
class OptionsFileAlreadyExistsException : Exception()
}

View File

@ -1,15 +1,16 @@
package app.revanced.cli.command
import app.revanced.library.ApkUtils
import app.revanced.library.Options
import app.revanced.library.Options.setOptions
import app.revanced.library.adb.AdbManager
import app.revanced.patcher.PatchBundleLoader
import app.revanced.patcher.PatchSet
import app.revanced.library.ApkUtils.applyTo
import app.revanced.library.installation.installer.*
import app.revanced.library.setOptions
import app.revanced.patcher.Patcher
import app.revanced.patcher.PatcherOptions
import app.revanced.patcher.PatcherConfig
import app.revanced.patcher.patch.Patch
import app.revanced.patcher.patch.loadPatchesFromJar
import kotlinx.coroutines.runBlocking
import picocli.CommandLine
import picocli.CommandLine.ArgGroup
import picocli.CommandLine.Help.Visibility.ALWAYS
import picocli.CommandLine.Model.CommandSpec
import picocli.CommandLine.Spec
@ -18,314 +19,435 @@ import java.io.PrintWriter
import java.io.StringWriter
import java.util.logging.Logger
@CommandLine.Command(
name = "patch", description = ["Patch an APK file"]
name = "patch",
description = ["Patch an APK file."],
)
internal object PatchCommand : Runnable {
private val logger = Logger.getLogger(PatchCommand::class.java.name)
private val logger = Logger.getLogger(this::class.java.name)
@Spec
lateinit var spec: CommandSpec // injected by picocli
private lateinit var spec: CommandSpec
private lateinit var apk: File
@ArgGroup(exclusive = false, multiplicity = "0..*")
private var selection = mutableSetOf<Selection>()
private var integrations = listOf<File>()
internal class Selection {
@ArgGroup(exclusive = false)
internal var enabled: EnableSelection? = null
private var patchBundles = emptyList<File>()
internal class EnableSelection {
@ArgGroup(multiplicity = "1")
internal lateinit var selector: EnableSelector
internal class EnableSelector {
@CommandLine.Option(
names = ["-e", "--enable"],
description = ["Name of the patch."],
required = true,
)
internal var name: String? = null
@CommandLine.Option(
names = ["-i", "--include"], description = ["List of patches to include"]
names = ["--ei"],
description = ["Index of the patch in the combined list of the supplied RVP files."],
required = true,
)
private var includedPatches = arrayOf<String>()
internal var index: Int? = null
}
@CommandLine.Option(
names = ["-e", "--exclude"], description = ["List of patches to exclude"]
names = ["-O", "--options"],
description = ["Option values keyed by option keys."],
mapFallbackValue = CommandLine.Option.NULL_VALUE,
converter = [OptionKeyConverter::class, OptionValueConverter::class],
)
private var excludedPatches = arrayOf<String>()
internal var options = mutableMapOf<String, Any?>()
}
@ArgGroup(exclusive = false)
internal var disable: DisableSelection? = null
internal class DisableSelection {
@ArgGroup(multiplicity = "1")
internal lateinit var selector: DisableSelector
internal class DisableSelector {
@CommandLine.Option(
names = ["-d", "--disable"],
description = ["Name of the patch."],
required = true,
)
internal var name: String? = null
@CommandLine.Option(
names = ["--options"], description = ["Path to patch options JSON file"], showDefaultValue = ALWAYS
names = ["--di"],
description = ["Index of the patch in the combined list of the supplied RVP files."],
required = true,
)
private var optionsFile: File = File("options.json")
internal var index: Int? = null
}
}
}
@CommandLine.Option(
names = ["--exclusive"],
description = ["Only include patches that are explicitly specified to be included"],
showDefaultValue = ALWAYS
description = ["Disable all patches except the ones enabled."],
showDefaultValue = ALWAYS,
)
private var exclusive = false
@CommandLine.Option(
names = ["-f", "--force"],
description = ["Bypass compatibility checks for the supplied APK's version"],
showDefaultValue = ALWAYS
description = ["Don't check for compatibility with the supplied APK's version."],
showDefaultValue = ALWAYS,
)
private var force: Boolean = false
@CommandLine.Option(
names = ["-o", "--out"], description = ["Path to save the patched APK file to"], required = true
)
private lateinit var outputFilePath: File
private var outputFilePath: File? = null
@CommandLine.Option(
names = ["-d", "--device-serial"], description = ["ADB device serial to install to"], showDefaultValue = ALWAYS
names = ["-o", "--out"],
description = ["Path to save the patched APK file to. Defaults to the same path as the supplied APK file."],
)
@Suppress("unused")
private fun setOutputFilePath(outputFilePath: File?) {
this.outputFilePath = outputFilePath?.absoluteFile
}
@CommandLine.Option(
names = ["-i", "--install"],
description = ["Serial of the ADB device to install to. If not specified, the first connected device will be used."],
// Empty string to indicate that the first connected device should be used.
fallbackValue = "",
arity = "0..1",
)
private var deviceSerial: String? = null
@CommandLine.Option(
names = ["--mount"], description = ["Install by mounting the patched APK file"], showDefaultValue = ALWAYS
names = ["--mount"],
description = ["Install the patched APK file by mounting."],
showDefaultValue = ALWAYS,
)
private var mount: Boolean = false
@CommandLine.Option(
names = ["--keystore"], description = ["Path to the keystore to sign the patched APK file with"],
names = ["--keystore"],
description = [
"Path to the keystore file containing a private key and certificate pair to sign the patched APK file with. " +
"Defaults to the same directory as the supplied APK file.",
],
)
private var keystoreFilePath: File? = null
private var keyStoreFilePath: File? = null
// key store password
@CommandLine.Option(
names = ["--keystore-password"],
description = ["The password of the keystore to sign the patched APK file with"],
description = ["Password of the keystore. Empty password by default."],
)
private var keyStorePassword: String? = null // Empty password by default
@CommandLine.Option(
names = ["--alias"], description = ["The alias of the key from the keystore to sign the patched APK file with"],
showDefaultValue = ALWAYS
names = ["--keystore-entry-alias"],
description = ["Alias of the private key and certificate pair keystore entry."],
showDefaultValue = ALWAYS,
)
private var alias = "ReVanced Key"
private var keyStoreEntryAlias = "ReVanced Key"
@CommandLine.Option(
names = ["--keystore-entry-password"],
description = ["The password of the entry from the keystore for the key to sign the patched APK file with"]
description = ["Password of the keystore entry."],
)
private var password = "" // Empty password by default
private var keyStoreEntryPassword = "" // Empty password by default
@CommandLine.Option(
names = ["--signer"], description = ["The name of the signer to sign the patched APK file with"],
showDefaultValue = ALWAYS
names = ["--signer"],
description = ["The name of the signer to sign the patched APK file with."],
showDefaultValue = ALWAYS,
)
private var signer = "ReVanced"
@CommandLine.Option(
names = ["-r", "--resource-cache"],
description = ["Path to temporary resource cache directory"],
showDefaultValue = ALWAYS
names = ["-t", "--temporary-files-path"],
description = ["Path to store temporary files."],
)
private var resourceCachePath = File("revanced-resource-cache")
private var temporaryFilesPath: File? = null
private var aaptBinaryPath: File? = null
@CommandLine.Option(
names = ["-p", "--purge"],
description = ["Purge the temporary resource cache directory after patching"],
showDefaultValue = ALWAYS
names = ["--purge"],
description = ["Purge temporary files directory after patching."],
showDefaultValue = ALWAYS,
)
private var purge: Boolean = false
@CommandLine.Option(
names = ["-w", "--warn"],
description = ["Warn if a patch can not be found in the supplied patch bundles"],
showDefaultValue = ALWAYS
)
private var warn: Boolean = false
@CommandLine.Parameters(
description = ["APK file to be patched"], arity = "1..1"
description = ["APK file to patch."],
arity = "1",
)
@Suppress("unused")
private fun setApk(apk: File) {
if (!apk.exists()) throw CommandLine.ParameterException(
if (!apk.exists()) {
throw CommandLine.ParameterException(
spec.commandLine(),
"APK file ${apk.name} does not exist"
"APK file ${apk.path} does not exist",
)
}
this.apk = apk
}
@CommandLine.Option(
names = ["-m", "--merge"], description = ["One or more DEX files or containers to merge into the APK"]
)
@Suppress("unused")
private fun setIntegrations(integrations: Array<File>) {
integrations.firstOrNull { !it.exists() }?.let {
throw CommandLine.ParameterException(spec.commandLine(), "Integrations file ${it.name} does not exist")
}
this.integrations += integrations
}
private lateinit var apk: File
@CommandLine.Option(
names = ["-b", "--patch-bundle"], description = ["One or more bundles of patches"], required = true
names = ["-p", "--patches"],
description = ["One or more path to RVP files."],
required = true,
)
@Suppress("unused")
private fun setPatchBundles(patchBundles: Array<File>) {
patchBundles.firstOrNull { !it.exists() }?.let {
throw CommandLine.ParameterException(spec.commandLine(), "Patch bundle ${it.name} does not exist")
private fun setPatchesFile(patchesFiles: Set<File>) {
patchesFiles.firstOrNull { !it.exists() }?.let {
throw CommandLine.ParameterException(spec.commandLine(), "${it.name} can't be found")
}
this.patchBundles = patchBundles.toList()
this.patchesFiles = patchesFiles
}
private var patchesFiles = emptySet<File>()
@CommandLine.Option(
names = ["--custom-aapt2-binary"], description = ["Path to a custom AAPT binary to compile resources with"]
names = ["--custom-aapt2-binary"],
description = ["Path to a custom AAPT binary to compile resources with."],
)
@Suppress("unused")
private fun setAaptBinaryPath(aaptBinaryPath: File) {
if (!aaptBinaryPath.exists()) throw CommandLine.ParameterException(
if (!aaptBinaryPath.exists()) {
throw CommandLine.ParameterException(
spec.commandLine(),
"AAPT binary ${aaptBinaryPath.name} does not exist"
"AAPT binary ${aaptBinaryPath.name} does not exist",
)
}
this.aaptBinaryPath = aaptBinaryPath
}
override fun run() {
val adbManager = deviceSerial?.let { serial -> AdbManager.getAdbManager(serial, mount) }
// region Setup
val outputFilePath =
outputFilePath ?: File("").absoluteFile.resolve(
"${apk.nameWithoutExtension}-patched.${apk.extension}",
)
val temporaryFilesPath =
temporaryFilesPath ?: outputFilePath.parentFile.resolve(
"${outputFilePath.nameWithoutExtension}-temporary-files",
)
val keystoreFilePath =
keyStoreFilePath ?: outputFilePath.parentFile
.resolve("${outputFilePath.nameWithoutExtension}.keystore")
val installer = if (deviceSerial != null) {
val deviceSerial = deviceSerial!!.ifEmpty { null }
try {
if (mount) {
AdbRootInstaller(deviceSerial)
} else {
AdbInstaller(deviceSerial)
}
} catch (e: DeviceNotFoundException) {
if (deviceSerial?.isNotEmpty() == true) {
logger.severe(
"Device with serial $deviceSerial not found to install to. " +
"Ensure the device is connected and the serial is correct when using the --install option.",
)
} else {
logger.severe(
"No device has been found to install to. " +
"Ensure a device is connected when using the --install option.",
)
}
return
}
} else {
null
}
// endregion
// region Load patches
logger.info("Loading patches")
val patches = PatchBundleLoader.Jar(*patchBundles.toTypedArray())
// Warn if a patch can not be found in the supplied patch bundles.
if (warn) patches.map { it.name }.toHashSet().let { availableNames ->
arrayOf(*includedPatches, *excludedPatches).filter { name ->
!availableNames.contains(name)
}
}.let { unknownPatches ->
if (unknownPatches.isEmpty()) return@let
logger.warning("Unknown input of patches:\n${unknownPatches.joinToString("\n")}")
}
val patches = loadPatchesFromJar(patchesFiles)
// endregion
Patcher(
PatcherOptions(
val patcherTemporaryFilesPath = temporaryFilesPath.resolve("patcher")
val (packageName, patcherResult) = Patcher(
PatcherConfig(
apk,
resourceCachePath,
patcherTemporaryFilesPath,
aaptBinaryPath?.path,
resourceCachePath.absolutePath,
)
patcherTemporaryFilesPath.absolutePath,
),
).use { patcher ->
val filteredPatches = patcher.filterPatchSelection(patches).also { patches ->
val packageName = patcher.context.packageMetadata.packageName
val packageVersion = patcher.context.packageMetadata.packageVersion
val filteredPatches = patches.filterPatchSelection(packageName, packageVersion)
logger.info("Setting patch options")
if (optionsFile.exists()) patches.setOptions(optionsFile)
else Options.serialize(patches, prettyPrint = true).let(optionsFile::writeText)
}
val patchesList = patches.toList()
selection.filter { it.enabled != null }.associate {
val enabledSelection = it.enabled!!
// region Patch
(enabledSelection.selector.name ?: patchesList[enabledSelection.selector.index!!].name!!) to
enabledSelection.options
}.let(filteredPatches::setOptions)
val patcherResult = patcher.apply {
acceptIntegrations(integrations)
acceptPatches(filteredPatches.toList())
patcher += filteredPatches
// Execute patches.
runBlocking {
apply(false).collect { patchResult ->
patchResult.exception?.let {
patcher().collect { patchResult ->
val exception = patchResult.exception
?: return@collect logger.info("\"${patchResult.patch}\" succeeded")
StringWriter().use { writer ->
it.printStackTrace(PrintWriter(writer))
logger.severe("${patchResult.patch.name} failed:\n$writer")
}
} ?: logger.info("${patchResult.patch.name} succeeded")
exception.printStackTrace(PrintWriter(writer))
logger.severe("\"${patchResult.patch}\" failed:\n$writer")
}
}
}.get()
// endregion
// region Save
val tempFile = resourceCachePath.resolve(apk.name).apply {
ApkUtils.copyAligned(apk, this, patcherResult)
}
val keystoreFilePath = keystoreFilePath ?: outputFilePath.absoluteFile.parentFile
.resolve("${outputFilePath.nameWithoutExtension}.keystore")
patcher.context.packageMetadata.packageName to patcher.get()
}
if (!mount) ApkUtils.sign(
tempFile,
// region Save.
apk.copyTo(temporaryFilesPath.resolve(apk.name), overwrite = true).apply {
patcherResult.applyTo(this)
}.let { patchedApkFile ->
if (!mount) {
ApkUtils.signApk(
patchedApkFile,
outputFilePath,
ApkUtils.SigningOptions(
signer,
ApkUtils.KeyStoreDetails(
keystoreFilePath,
keyStorePassword,
alias,
password,
signer
keyStoreEntryAlias,
keyStoreEntryPassword,
),
)
)
// endregion
// region Install
adbManager?.install(AdbManager.Apk(outputFilePath, patcher.context.packageMetadata.packageName))
// endregion
} else {
patchedApkFile.copyTo(outputFilePath, overwrite = true)
}
}
logger.info("Saved to $outputFilePath")
// endregion
// region Install.
deviceSerial?.let {
runBlocking {
when (val result = installer!!.install(Installer.Apk(outputFilePath, packageName))) {
RootInstallerResult.FAILURE -> logger.severe("Failed to mount the patched APK file")
is AdbInstallerResult.Failure -> logger.severe(result.exception.toString())
else -> logger.info("Installed the patched APK file")
}
}
}
// endregion
if (purge) {
logger.info("Purging temporary files")
purge(resourceCachePath)
purge(temporaryFilesPath)
}
}
/**
* Filter the patches to be added to the patcher. The filter is based on the following:
* Filter the patches based on the selection.
*
* @param patches The patches to filter.
* @param packageName The package name of the APK file to be patched.
* @param packageVersion The version of the APK file to be patched.
* @return The filtered patches.
*/
private fun Patcher.filterPatchSelection(patches: PatchSet): PatchSet = buildSet {
val packageName = context.packageMetadata.packageName
val packageVersion = context.packageMetadata.packageVersion
private fun Set<Patch<*>>.filterPatchSelection(
packageName: String,
packageVersion: String,
): Set<Patch<*>> = buildSet {
val enabledPatchesByName =
selection.mapNotNull { it.enabled?.selector?.name }.toSet()
val enabledPatchesByIndex =
selection.mapNotNull { it.enabled?.selector?.index }.toSet()
patches.forEach patch@{ patch ->
val disabledPatches =
selection.mapNotNull { it.disable?.selector?.name }.toSet()
val disabledPatchesByIndex =
selection.mapNotNull { it.disable?.selector?.index }.toSet()
this@filterPatchSelection.withIndex().forEach patchLoop@{ (i, patch) ->
val patchName = patch.name!!
val explicitlyExcluded = excludedPatches.contains(patchName)
if (explicitlyExcluded) return@patch logger.info("Excluding $patchName")
val isManuallyDisabled = patchName in disabledPatches || i in disabledPatchesByIndex
if (isManuallyDisabled) return@patchLoop logger.info("\"$patchName\" disabled manually")
// Make sure the patch is compatible with the supplied APK files package name and version.
patch.compatiblePackages?.let { packages ->
packages.singleOrNull { it.name == packageName }?.let { `package` ->
val matchesVersion = force || `package`.versions?.let {
it.any { version -> version == packageVersion }
} ?: true
if (!matchesVersion) return@patch logger.warning(
"$patchName is incompatible with version $packageVersion. "
+ "This patch is only compatible with version "
+ packages.joinToString(";") { pkg ->
"${pkg.name}: ${pkg.versions!!.joinToString(", ")}"
packages.singleOrNull { (name, _) -> name == packageName }?.let { (_, versions) ->
if (versions?.isEmpty() == true) {
return@patchLoop logger.warning("\"$patchName\" incompatible with \"$packageName\"")
}
val matchesVersion =
force || versions?.let { it.any { version -> version == packageVersion } } ?: true
if (!matchesVersion) {
return@patchLoop logger.warning(
"\"$patchName\" incompatible with $packageName $packageVersion " +
"but compatible with " +
packages.joinToString("; ") { (packageName, versions) ->
packageName + " " + versions!!.joinToString(", ")
},
)
}
} ?: return@patchLoop logger.fine(
"\"$patchName\" incompatible with $packageName. " +
"It is only compatible with " +
packages.joinToString(", ") { (name, _) -> name },
)
} ?: return@patch logger.fine(
"$patchName is incompatible with $packageName. "
+ "This patch is only compatible with "
+ packages.joinToString(", ") { `package` -> `package`.name })
return@let
} ?: logger.fine("$patchName has no constraint on packages.")
} ?: logger.fine("\"$patchName\" has no package constraints")
// If the patch is implicitly used, it will be only included if [exclusive] is false.
val implicitlyIncluded = !exclusive && patch.use
// If the patch is explicitly used, it will be included even if [exclusive] is false.
val explicitlyIncluded = includedPatches.contains(patchName)
val isEnabled = !exclusive && patch.use
val isManuallyEnabled = patchName in enabledPatchesByName || i in enabledPatchesByIndex
val included = implicitlyIncluded || explicitlyIncluded
if (!included) return@patch logger.info("$patchName excluded") // Case 1.
logger.fine("Adding $patchName")
if (!(isEnabled || isManuallyEnabled)) {
return@patchLoop logger.info("\"$patchName\" disabled")
}
add(patch)
logger.fine("\"$patchName\" added")
}
}
private fun purge(resourceCachePath: File) {
val result = if (resourceCachePath.deleteRecursively()) "Purged resource cache directory"
else "Failed to purge resource cache directory"
val result =
if (resourceCachePath.deleteRecursively()) {
"Purged resource cache directory"
} else {
"Failed to purge resource cache directory"
}
logger.info(result)
}
}

View File

@ -1,38 +1,63 @@
package app.revanced.cli.command.utility
import app.revanced.library.adb.AdbManager
import app.revanced.library.installation.installer.*
import kotlinx.coroutines.async
import kotlinx.coroutines.awaitAll
import kotlinx.coroutines.runBlocking
import picocli.CommandLine.*
import java.io.File
import java.util.logging.Logger
@Command(
name = "install", description = ["Install an APK file to devices with the supplied ADB device serials"]
name = "install",
description = ["Install an APK file."],
)
internal object InstallCommand : Runnable {
private val logger = Logger.getLogger(InstallCommand::class.java.name)
private val logger = Logger.getLogger(this::class.java.name)
@Parameters(
description = ["ADB device serials"], arity = "1..*"
description = ["Serial of ADB devices. If not supplied, the first connected device will be used."],
arity = "0..*",
)
private lateinit var deviceSerials: Array<String>
private var deviceSerials: Array<String>? = null
@Option(
names = ["-a", "--apk"], description = ["APK file to be installed"], required = true
names = ["-a", "--apk"],
description = ["APK file to be installed."],
required = true,
)
private lateinit var apk: File
@Option(
names = ["-m", "--mount"],
description = ["Mount the supplied APK file over the app with the supplied package name"],
description = ["Mount the supplied APK file over the app with the supplied package name."],
)
private var packageName: String? = null
override fun run() = deviceSerials.forEach { deviceSerial ->
try {
AdbManager.getAdbManager(deviceSerial, packageName != null).install(AdbManager.Apk(apk, packageName))
} catch (e: AdbManager.DeviceNotFoundException) {
override fun run() {
suspend fun install(deviceSerial: String? = null) {
val result = try {
if (packageName != null) {
AdbRootInstaller(deviceSerial)
} else {
AdbInstaller(deviceSerial)
}.install(Installer.Apk(apk, packageName))
} catch (e: Exception) {
logger.severe(e.toString())
}
when (result) {
RootInstallerResult.FAILURE ->
logger.severe("Failed to mount the APK file")
is AdbInstallerResult.Failure ->
logger.severe(result.exception.toString())
else ->
logger.info("Installed the APK file")
}
}
runBlocking {
deviceSerials?.map { async { install(it) } }?.awaitAll() ?: install()
}
}
}

View File

@ -1,36 +1,66 @@
package app.revanced.cli.command.utility
import app.revanced.library.adb.AdbManager
import app.revanced.library.installation.installer.AdbInstaller
import app.revanced.library.installation.installer.AdbInstallerResult
import app.revanced.library.installation.installer.AdbRootInstaller
import app.revanced.library.installation.installer.RootInstallerResult
import kotlinx.coroutines.async
import kotlinx.coroutines.awaitAll
import kotlinx.coroutines.runBlocking
import picocli.CommandLine.*
import picocli.CommandLine.Help.Visibility.ALWAYS
import java.util.logging.Logger
@Command(
name = "uninstall",
description = ["Uninstall a patched app from the devices with the supplied ADB device serials"]
description = ["Uninstall a patched app."],
)
internal object UninstallCommand : Runnable {
private val logger = Logger.getLogger(UninstallCommand::class.java.name)
private val logger = Logger.getLogger(this::class.java.name)
@Parameters(description = ["ADB device serials"], arity = "1..*")
private lateinit var deviceSerials: Array<String>
@Parameters(
description = ["Serial of ADB devices. If not supplied, the first connected device will be used."],
arity = "0..*",
)
private var deviceSerials: Array<String>? = null
@Option(names = ["-p", "--package-name"], description = ["Package name of the app to uninstall"], required = true)
@Option(
names = ["-p", "--package-name"],
description = ["Package name of the app to uninstall."],
required = true,
)
private lateinit var packageName: String
@Option(
names = ["-u", "--unmount"],
description = ["Uninstall by unmounting the patched APK file"],
showDefaultValue = ALWAYS
description = ["Uninstall the patched APK file by unmounting."],
showDefaultValue = ALWAYS,
)
private var unmount: Boolean = false
override fun run() = deviceSerials.forEach { deviceSerial ->
try {
AdbManager.getAdbManager(deviceSerial, unmount).uninstall(packageName)
} catch (e: AdbManager.DeviceNotFoundException) {
override fun run() {
suspend fun uninstall(deviceSerial: String? = null) {
val result = try {
if (unmount) {
AdbRootInstaller(deviceSerial)
} else {
AdbInstaller(deviceSerial)
}.uninstall(packageName)
} catch (e: Exception) {
logger.severe(e.toString())
}
when (result) {
RootInstallerResult.FAILURE ->
logger.severe("Failed to unmount the patched APK file")
is AdbInstallerResult.Failure ->
logger.severe(result.exception.toString())
else -> logger.info("Uninstalled the patched APK file")
}
}
runBlocking {
deviceSerials?.map { async { uninstall(it) } }?.awaitAll() ?: uninstall()
}
}
}

View File

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

View File

@ -0,0 +1,78 @@
package app.revanced.cli.command
import kotlin.test.Test
class OptionValueConverterTest {
@Test
fun `converts to string`() {
"string" convertsTo "string" because "Strings should remain the same"
}
@Test
fun `converts to null`() {
"null" convertsTo null because "null should convert to null"
"\"null\"" convertsTo "null" because "Escaped null should convert to a string"
}
@Test
fun `converts to boolean`() {
"true" convertsTo true because "true should convert to a boolean true"
"True" convertsTo true because "Casing should not matter"
"\"true\"" convertsTo "true" because "Escaped booleans should be converted to strings"
"\'True\'" convertsTo "True" because "Casing in escaped booleans should not matter"
"tr ue" convertsTo "tr ue" because "Malformed booleans should be converted to strings"
}
@Test
fun `converts to numbers`() {
"1" convertsTo 1 because "Integers should convert to integers"
"1.0" convertsTo 1.0 because "Doubles should convert to doubles"
"1.0f" convertsTo 1.0f because "The suffix f should convert to a float"
Long.MAX_VALUE.toString() convertsTo Long.MAX_VALUE because "Values that are too large for an integer should convert to longs"
"1L" convertsTo 1L because "The suffix L should convert to a long"
}
@Test
fun `converts escaped numbers to string`() {
"\"1\"" convertsTo "1" because "Escaped numbers should convert to strings"
"\"1.0\"" convertsTo "1.0" because "Escaped doubles should convert to strings"
"\"1L\"" convertsTo "1L" because "Escaped longs should convert to strings"
"\'1\'" convertsTo "1" because "Single quotes should not be treated as escape symbols"
"\'.0\'" convertsTo ".0" because "Single quotes should not be treated as escape symbols"
"\'1L\'" convertsTo "1L" because "Single quotes should not be treated as escape symbols"
}
@Test
fun `trims escape symbols once`() {
"\"\"\"1\"\"\"" convertsTo "\"\"1\"\"" because "The escape symbols should be trimmed once"
"\'\'\'1\'\'\'" convertsTo "''1''" because "Single quotes should not be treated as escape symbols"
}
@Test
fun `converts lists`() {
"1,2" convertsTo "1,2" because "Lists without square brackets should not be converted to lists"
"[1,2" convertsTo "[1,2" because "Invalid lists should not be converted to lists"
"\"[1,2]\"" convertsTo "[1,2]" because "Lists with escaped square brackets should not be converted to lists"
"[]" convertsTo emptyList<Any>() because "Empty untyped lists should convert to empty lists of any"
"int[]" convertsTo emptyList<Int>() because "Empty typed lists should convert to lists of the specified type"
"[[int[]]]" convertsTo listOf(listOf(emptyList<Int>())) because "Nested typed lists should convert to nested lists of the specified type"
"[\"int[]\"]" convertsTo listOf("int[]") because "Lists of escaped empty typed lists should not be converted to lists"
"[1,2,3]" convertsTo listOf(1, 2, 3) because "Lists of integers should convert to lists of integers"
"[[1]]" convertsTo listOf(listOf(1)) because "Nested lists with one element should convert to nested lists"
"[[1,2],[3,4]]" convertsTo listOf(listOf(1, 2), listOf(3, 4)) because "Nested lists should convert to nested lists"
"[\"1,2\"]" convertsTo listOf("1,2") because "Values in lists should not be split by commas in strings"
"[[\"1,2\"]]" convertsTo listOf(listOf("1,2")) because "Values in nested lists should not be split by commas in strings"
"[\"\\\"\"]" convertsTo listOf("\"") because "Escaped quotes in strings should be converted to quotes"
"[[\"\\\"\"]]" convertsTo listOf(listOf("\"")) because "Escaped quotes in strings nested in lists should be converted to quotes"
"[.1,.2f,,true,FALSE]" convertsTo listOf(.1, .2f, "", true, false) because "Values in lists should be converted to the correct type"
}
private val convert = OptionValueConverter()::convert
private infix fun String.convertsTo(to: Any?) = convert(this) to to
private infix fun Pair<Any?, Any?>.because(reason: String) = assert(this.first == this.second) { reason }
}