Compare commits

...

56 Commits

Author SHA1 Message Date
semantic-release-bot
1957a2c4ff chore(release): 2.20.0-dev.1 [skip ci]
# [2.20.0-dev.1](https://github.com/revanced/revanced-cli/compare/v2.19.0...v2.20.0-dev.1) (2023-01-01)

### Bug Fixes

* do not list compatible packages if patches do not define them ([31e4a41](31e4a41dd2))

### Features

* remove option `--with-descriptions` ([07a423b](07a423b19e))
2023-01-01 17:12:07 +00:00
oSumAtrIX
07a423b19e feat: remove option --with-descriptions 2023-01-01 18:11:10 +01:00
oSumAtrIX
31e4a41dd2 fix: do not list compatible packages if patches do not define them 2023-01-01 18:11:10 +01:00
semantic-release-bot
8284c1048f chore(release): 2.19.0 [skip ci]
# [2.19.0](https://github.com/revanced/revanced-cli/compare/v2.18.2...v2.19.0) (2022-12-31)

### Features

* improve description of options ([#185](https://github.com/revanced/revanced-cli/issues/185)) ([b69e784](b69e784785))
2022-12-31 18:22:25 +00:00
oSumAtrIX
9c64f5ec3e chore: merge branch dev to main (#184) 2022-12-31 19:20:26 +01:00
semantic-release-bot
f4c447e71b chore(release): 2.19.0-dev.1 [skip ci]
# [2.19.0-dev.1](https://github.com/revanced/revanced-cli/compare/v2.18.2...v2.19.0-dev.1) (2022-12-31)

### Features

* improve description of options ([#185](https://github.com/revanced/revanced-cli/issues/185)) ([b69e784](b69e784785))
2022-12-31 18:19:03 +00:00
oSumAtrIX
b69e784785 feat: improve description of options (#185) 2022-12-31 19:17:57 +01:00
oSumAtrIX
ccce9c926d ci: do not escape in environment variable MESSAGE 2022-12-29 19:07:33 +01:00
oSumAtrIX
dc4ab22f41 chore: bump patcher dependency version 2022-12-18 22:20:20 +01:00
semantic-release-bot
25d8ad4aaf chore(release): 2.18.2 [skip ci]
## [2.18.2](https://github.com/revanced/revanced-cli/compare/v2.18.1...v2.18.2) (2022-12-16)

### Bug Fixes

* exclude patcher dependency from minimizing ([d5794b9](d5794b94ca))
2022-12-16 16:10:17 +00:00
oSumAtrIX
3d9436e691 chore: merge branch dev to main (#180) 2022-12-16 17:08:38 +01:00
semantic-release-bot
ee70423527 chore(release): 2.18.2-dev.1 [skip ci]
## [2.18.2-dev.1](https://github.com/revanced/revanced-cli/compare/v2.18.1...v2.18.2-dev.1) (2022-12-16)

### Bug Fixes

* exclude patcher dependency from minimizing ([d5794b9](d5794b94ca))
2022-12-16 15:54:28 +00:00
oSumAtrIX
d5794b94ca fix: exclude patcher dependency from minimizing 2022-12-16 16:53:01 +01:00
oSumAtrIX
3160d894da chore: merge branch dev to main (#179) 2022-12-16 01:25:15 +01:00
oSumAtrIX
545597959a refactor: remove unused class ZipFileUtils 2022-12-16 01:23:37 +01:00
semantic-release-bot
a6db0edc70 chore(release): 2.18.1 [skip ci]
## [2.18.1](https://github.com/revanced/revanced-cli/compare/v2.18.0...v2.18.1) (2022-12-15)

### Bug Fixes

* don't log when package is incompatible and `exclusive` option is used ([ad81a1b](ad81a1b656))
2022-12-15 23:50:16 +00:00
oSumAtrIX
ff0d3dd224 chore: merge branch dev to main (#178) 2022-12-15 23:43:46 +01:00
semantic-release-bot
d9a1fd33ed chore(release): 2.18.1-dev.1 [skip ci]
## [2.18.1-dev.1](https://github.com/revanced/revanced-cli/compare/v2.18.0...v2.18.1-dev.1) (2022-12-15)

### Bug Fixes

* don't log when package is incompatible and `exclusive` option is used ([ad81a1b](ad81a1b656))
2022-12-15 22:43:16 +00:00
oSumAtrIX
ad81a1b656 fix: don't log when package is incompatible and exclusive option is used 2022-12-15 23:41:42 +01:00
oSumAtrIX
8c2aeff2cf build: exclude Bouncy Castle dependency from minimizing 2022-12-15 23:41:42 +01:00
semantic-release-bot
eb6c659f5b chore(release): 2.18.0 [skip ci]
# [2.18.0](https://github.com/revanced/revanced-cli/compare/v2.17.0...v2.18.0) (2022-12-15)

### Bug Fixes

* start with uppercase in log message ([ae91b0d](ae91b0d597))
* use correct prefix in log message ([1a67cd8](1a67cd81da))

### Features

* simplify log message ([74d73ca](74d73ca3a7))
2022-12-15 21:11:11 +00:00
semantic-release-bot
bac4f839c9 chore(release): 2.18.0 [skip ci]
# [2.18.0](https://github.com/revanced/revanced-cli/compare/v2.17.0...v2.18.0) (2022-12-15)

### Bug Fixes

* start with uppercase in log message ([ae91b0d](ae91b0d597))
* use correct prefix in log message ([1a67cd8](1a67cd81da))

### Features

* simplify log message ([74d73ca](74d73ca3a7))
2022-12-15 21:06:50 +00:00
oSumAtrIX
c1e7215d31 chore: merge branch dev to main (#176) 2022-12-15 22:05:59 +01:00
semantic-release-bot
18d132123f chore(release): 2.18.0-dev.1 [skip ci]
# [2.18.0-dev.1](https://github.com/revanced/revanced-cli/compare/v2.17.1-dev.2...v2.18.0-dev.1) (2022-12-15)

### Bug Fixes

* start with uppercase in log message ([ae91b0d](ae91b0d597))
* use correct prefix in log message ([1a67cd8](1a67cd81da))

### Features

* simplify log message ([74d73ca](74d73ca3a7))
2022-12-15 21:04:58 +00:00
oSumAtrIX
74d73ca3a7 feat: simplify log message 2022-12-15 22:03:47 +01:00
oSumAtrIX
ae91b0d597 fix: start with uppercase in log message 2022-12-15 22:03:29 +01:00
oSumAtrIX
1a67cd81da fix: use correct prefix in log message 2022-12-15 22:00:08 +01:00
oSumAtrIX
9b9fad7cc0 chore: merge branch dev to main (#174) 2022-12-15 21:46:55 +01:00
oSumAtrIX
1620305b4a ci: do not release on build commit type 2022-12-15 19:47:48 +01:00
semantic-release-bot
d906edbe78 chore(release): 2.17.1-dev.2 [skip ci]
## [2.17.1-dev.2](https://github.com/revanced/revanced-cli/compare/v2.17.1-dev.1...v2.17.1-dev.2) (2022-12-15)
2022-12-15 18:34:01 +00:00
oSumAtrIX
4e53638cb9 build: exclude Kotlin standard library dependencies from minimizing 2022-12-15 19:32:08 +01:00
semantic-release-bot
7d1f200621 chore(release): 2.17.1-dev.1 [skip ci]
## [2.17.1-dev.1](https://github.com/revanced/revanced-cli/compare/v2.17.0...v2.17.1-dev.1) (2022-12-15)
2022-12-15 00:01:17 +00:00
oSumAtrIX
a7db6cb8f1 build: do not comment on successful releases 2022-12-15 01:00:22 +01:00
semantic-release-bot
d61ab058da chore(release): 2.17.0 [skip ci]
# [2.17.0](https://github.com/revanced/revanced-cli/compare/v2.16.1...v2.17.0) (2022-12-14)

### Bug Fixes

* invalid header when writing a `ZipFile` ([#169](https://github.com/revanced/revanced-cli/issues/169)) ([6e703eb](6e703eb8e8))

### Features

* improve missing compatibility annotation tracing log ([2c7eb72](2c7eb7274c))
* trace logs when compatibility annotation is missing ([#166](https://github.com/revanced/revanced-cli/issues/166)) ([c590bf5](c590bf559c))
2022-12-14 23:48:26 +00:00
oSumAtrIX
235c2742ec chore: merge branch dev to main (#173) 2022-12-15 00:39:03 +01:00
semantic-release-bot
8a964efd00 chore(release): 2.17.0-dev.3 [skip ci]
# [2.17.0-dev.3](https://github.com/revanced/revanced-cli/compare/v2.17.0-dev.2...v2.17.0-dev.3) (2022-12-14)

### Features

* improve missing compatibility annotation tracing log ([2c7eb72](2c7eb7274c))
2022-12-14 23:37:35 +00:00
oSumAtrIX
8114d1dca0 build: remove unnecessary step 2022-12-15 00:32:48 +01:00
oSumAtrIX
5a7cadd96d build: remove manifest attributes 2022-12-15 00:32:47 +01:00
oSumAtrIX
1c5983b803 build: minimize shadow jar 2022-12-15 00:32:47 +01:00
oSumAtrIX
2c7eb7274c feat: improve missing compatibility annotation tracing log 2022-12-15 00:32:47 +01:00
oSumAtrIX
512152fb66 ci: stash before rebasing 2022-12-15 00:32:47 +01:00
oSumAtrIX
8793b5fc65 chore: merge branch dev to main (#167) 2022-12-14 01:18:05 +01:00
semantic-release-bot
39c490d6b7 chore(release): 2.17.0-dev.2 [skip ci]
# [2.17.0-dev.2](https://github.com/revanced/revanced-cli/compare/v2.17.0-dev.1...v2.17.0-dev.2) (2022-12-14)

### Bug Fixes

* invalid header when writing a `ZipFile` ([#169](https://github.com/revanced/revanced-cli/issues/169)) ([6e703eb](6e703eb8e8))
2022-12-14 00:16:38 +00:00
oSumAtrIX
6e703eb8e8 fix: invalid header when writing a ZipFile (#169) 2022-12-14 01:14:00 +01:00
oSumAtrIX
c677eb9792 ci: back-merge releases back into dev branch 2022-12-14 01:13:45 +01:00
oSumAtrIX
75c8ea4639 chore: bump patcher dependency version 2022-12-14 01:13:00 +01:00
semantic-release-bot
b69dd52ca9 chore(release): 2.17.0-dev.1 [skip ci]
# [2.17.0-dev.1](https://github.com/revanced/revanced-cli/compare/v2.16.1...v2.17.0-dev.1) (2022-12-11)

### Features

* trace logs when compatibility annotation is missing ([#166](https://github.com/revanced/revanced-cli/issues/166)) ([c590bf5](c590bf559c))
2022-12-11 19:10:19 +00:00
oSumAtrIX
c590bf559c feat: trace logs when compatibility annotation is missing (#166) 2022-12-11 20:08:52 +01:00
oSumAtrIX
ec0b847419 chore: merge branch dev to main (#165) 2022-12-11 05:19:08 +01:00
oSumAtrIX
b3cf32e89d ci: open pull requests to merge dev to main (#164) 2022-12-11 05:16:51 +01:00
oSumAtrIX
8a1199ba9a ci: refactor release workflow 2022-12-11 05:14:23 +01:00
oSumAtrIX
25b45800a1 chore: bump patcher dependency version 2022-12-02 04:04:25 +01:00
oSumAtrIX
2fe3303a27 chore: bump patcher dependency version 2022-12-02 02:35:35 +01:00
semantic-release-bot
04339f0654 chore(release): 2.16.1 [skip ci]
## [2.16.1](https://github.com/revanced/revanced-cli/compare/v2.16.0...v2.16.1) (2022-11-22)
2022-11-22 23:37:24 +00:00
oSumAtrIX
456428a836 build: bump dependencies 2022-11-23 00:33:45 +01:00
oSumAtrIX
c9ae379c77 feat!: apply changes from ReVanced Patcher 2022-11-23 00:20:48 +01:00
18 changed files with 6465 additions and 212 deletions

24
.github/workflows/pull_request.yml vendored Normal file
View File

@@ -0,0 +1,24 @@
name: PR to main
on:
push:
branches:
- dev
workflow_dispatch:
env:
MESSAGE: merge branch `${{ github.head_ref || github.ref_name }}` to `main`
jobs:
pull-request:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Open pull request
uses: repo-sync/pull-request@v2
with:
destination_branch: 'main'
pr_title: 'chore: ${{ env.MESSAGE }}'
pr_body: 'This pull request will ${{ env.MESSAGE }}.'
pr_draft: true

View File

@@ -22,19 +22,16 @@ jobs:
uses: actions/setup-java@v3 uses: actions/setup-java@v3
with: with:
java-version: '17' java-version: '17'
distribution: 'temurin' distribution: 'zulu'
cache: gradle cache: gradle
- name: Setup Node.js - name: Setup Node.js
uses: actions/setup-node@v3 uses: actions/setup-node@v3
with: with:
node-version: "lts/*" node-version: "latest"
- name: Build with Gradle cache: 'npm'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: ./gradlew build clean
- name: Setup semantic-release - name: Setup semantic-release
run: npm install -g semantic-release @semantic-release/git @semantic-release/changelog gradle-semantic-release-plugin -D run: npm install semantic-release @saithodev/semantic-release-backmerge @semantic-release/git @semantic-release/changelog gradle-semantic-release-plugin -D
- name: Release - name: Create release
env: env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: npx semantic-release run: npx semantic-release

5
.gitignore vendored
View File

@@ -113,6 +113,9 @@ gradle-app.setting
# # Work around https://youtrack.jetbrains.com/issue/IDEA-116898 # # Work around https://youtrack.jetbrains.com/issue/IDEA-116898
# gradle/wrapper/gradle-wrapper.properties # gradle/wrapper/gradle-wrapper.properties
# Dependency directories
node_modules/
# ReVanced CLI
revanced-cache/ revanced-cache/
options.toml options.toml
.idea/vcs.xml

2
.idea/.gitignore generated vendored
View File

@@ -7,3 +7,5 @@
/dataSources/ /dataSources/
/dataSources.local.xml /dataSources.local.xml
/kotlinc.xml /kotlinc.xml
/vcs.xml
/codeStyles

View File

@@ -7,11 +7,7 @@
} }
], ],
"plugins": [ "plugins": [
["@semantic-release/commit-analyzer", { "@semantic-release/commit-analyzer",
"releaseRules": [
{"type": "build", "release": "patch"}
]
}],
"@semantic-release/release-notes-generator", "@semantic-release/release-notes-generator",
"@semantic-release/changelog", "@semantic-release/changelog",
"gradle-semantic-release-plugin", "gradle-semantic-release-plugin",
@@ -31,7 +27,15 @@
{ {
"path": "build/libs/*all.jar" "path": "build/libs/*all.jar"
} }
] ],
successComment: false
}
],
[
"@saithodev/semantic-release-backmerge",
{
branches: [{from: "main", to: "dev"}],
clearWorkspace: true
} }
] ]
] ]

View File

@@ -1,3 +1,136 @@
# [2.20.0-dev.1](https://github.com/revanced/revanced-cli/compare/v2.19.0...v2.20.0-dev.1) (2023-01-01)
### Bug Fixes
* do not list compatible packages if patches do not define them ([31e4a41](https://github.com/revanced/revanced-cli/commit/31e4a41dd20f5fa62f840cd8e3b92fe0814eda87))
### Features
* remove option `--with-descriptions` ([07a423b](https://github.com/revanced/revanced-cli/commit/07a423b19ec72e9f020aeb0222f4ced571036dbe))
# [2.19.0](https://github.com/revanced/revanced-cli/compare/v2.18.2...v2.19.0) (2022-12-31)
### Features
* improve description of options ([#185](https://github.com/revanced/revanced-cli/issues/185)) ([b69e784](https://github.com/revanced/revanced-cli/commit/b69e784785f7f262f83b35c4f241c90036169fc7))
# [2.19.0-dev.1](https://github.com/revanced/revanced-cli/compare/v2.18.2...v2.19.0-dev.1) (2022-12-31)
### Features
* improve description of options ([#185](https://github.com/revanced/revanced-cli/issues/185)) ([b69e784](https://github.com/revanced/revanced-cli/commit/b69e784785f7f262f83b35c4f241c90036169fc7))
## [2.18.2](https://github.com/revanced/revanced-cli/compare/v2.18.1...v2.18.2) (2022-12-16)
### Bug Fixes
* exclude patcher dependency from minimizing ([d5794b9](https://github.com/revanced/revanced-cli/commit/d5794b94ca19c9287190a3b863c97a089893cc07))
## [2.18.2-dev.1](https://github.com/revanced/revanced-cli/compare/v2.18.1...v2.18.2-dev.1) (2022-12-16)
### Bug Fixes
* exclude patcher dependency from minimizing ([d5794b9](https://github.com/revanced/revanced-cli/commit/d5794b94ca19c9287190a3b863c97a089893cc07))
## [2.18.1](https://github.com/revanced/revanced-cli/compare/v2.18.0...v2.18.1) (2022-12-15)
### Bug Fixes
* don't log when package is incompatible and `exclusive` option is used ([ad81a1b](https://github.com/revanced/revanced-cli/commit/ad81a1b656586226f8b7b8d1123c52b0f3f2e6f7))
## [2.18.1-dev.1](https://github.com/revanced/revanced-cli/compare/v2.18.0...v2.18.1-dev.1) (2022-12-15)
### Bug Fixes
* don't log when package is incompatible and `exclusive` option is used ([ad81a1b](https://github.com/revanced/revanced-cli/commit/ad81a1b656586226f8b7b8d1123c52b0f3f2e6f7))
# [2.18.0](https://github.com/revanced/revanced-cli/compare/v2.17.0...v2.18.0) (2022-12-15)
### Bug Fixes
* start with uppercase in log message ([ae91b0d](https://github.com/revanced/revanced-cli/commit/ae91b0d597b107a152e1b630b8c16a795a7ca3b3))
* use correct prefix in log message ([1a67cd8](https://github.com/revanced/revanced-cli/commit/1a67cd81da5ed7f259b6dbaeb66a7eef4a113034))
### Features
* simplify log message ([74d73ca](https://github.com/revanced/revanced-cli/commit/74d73ca3a7ba2f5da872fe9a241629e1c143cd4e))
# [2.18.0](https://github.com/revanced/revanced-cli/compare/v2.17.0...v2.18.0) (2022-12-15)
### Bug Fixes
* start with uppercase in log message ([ae91b0d](https://github.com/revanced/revanced-cli/commit/ae91b0d597b107a152e1b630b8c16a795a7ca3b3))
* use correct prefix in log message ([1a67cd8](https://github.com/revanced/revanced-cli/commit/1a67cd81da5ed7f259b6dbaeb66a7eef4a113034))
### Features
* simplify log message ([74d73ca](https://github.com/revanced/revanced-cli/commit/74d73ca3a7ba2f5da872fe9a241629e1c143cd4e))
# [2.18.0-dev.1](https://github.com/revanced/revanced-cli/compare/v2.17.1-dev.2...v2.18.0-dev.1) (2022-12-15)
### Bug Fixes
* start with uppercase in log message ([ae91b0d](https://github.com/revanced/revanced-cli/commit/ae91b0d597b107a152e1b630b8c16a795a7ca3b3))
* use correct prefix in log message ([1a67cd8](https://github.com/revanced/revanced-cli/commit/1a67cd81da5ed7f259b6dbaeb66a7eef4a113034))
### Features
* simplify log message ([74d73ca](https://github.com/revanced/revanced-cli/commit/74d73ca3a7ba2f5da872fe9a241629e1c143cd4e))
## [2.17.1-dev.2](https://github.com/revanced/revanced-cli/compare/v2.17.1-dev.1...v2.17.1-dev.2) (2022-12-15)
## [2.17.1-dev.1](https://github.com/revanced/revanced-cli/compare/v2.17.0...v2.17.1-dev.1) (2022-12-15)
# [2.17.0](https://github.com/revanced/revanced-cli/compare/v2.16.1...v2.17.0) (2022-12-14)
### Bug Fixes
* invalid header when writing a `ZipFile` ([#169](https://github.com/revanced/revanced-cli/issues/169)) ([6e703eb](https://github.com/revanced/revanced-cli/commit/6e703eb8e8d7da0e52266c4965f37bc8aafb409c))
### Features
* improve missing compatibility annotation tracing log ([2c7eb72](https://github.com/revanced/revanced-cli/commit/2c7eb7274c713dfbcb53c5f3b6a9205c751914fa))
* trace logs when compatibility annotation is missing ([#166](https://github.com/revanced/revanced-cli/issues/166)) ([c590bf5](https://github.com/revanced/revanced-cli/commit/c590bf559c4d2d2667c2af0c0da23d4706fcd4b7))
# [2.17.0-dev.3](https://github.com/revanced/revanced-cli/compare/v2.17.0-dev.2...v2.17.0-dev.3) (2022-12-14)
### Features
* improve missing compatibility annotation tracing log ([2c7eb72](https://github.com/revanced/revanced-cli/commit/2c7eb7274c713dfbcb53c5f3b6a9205c751914fa))
# [2.17.0-dev.2](https://github.com/revanced/revanced-cli/compare/v2.17.0-dev.1...v2.17.0-dev.2) (2022-12-14)
### Bug Fixes
* invalid header when writing a `ZipFile` ([#169](https://github.com/revanced/revanced-cli/issues/169)) ([6e703eb](https://github.com/revanced/revanced-cli/commit/6e703eb8e8d7da0e52266c4965f37bc8aafb409c))
# [2.17.0-dev.1](https://github.com/revanced/revanced-cli/compare/v2.16.1...v2.17.0-dev.1) (2022-12-11)
### Features
* trace logs when compatibility annotation is missing ([#166](https://github.com/revanced/revanced-cli/issues/166)) ([c590bf5](https://github.com/revanced/revanced-cli/commit/c590bf559c4d2d2667c2af0c0da23d4706fcd4b7))
## [2.16.1](https://github.com/revanced/revanced-cli/compare/v2.16.0...v2.16.1) (2022-11-22)
# [2.16.0](https://github.com/revanced/revanced-cli/compare/v2.15.1...v2.16.0) (2022-11-20) # [2.16.0](https://github.com/revanced/revanced-cli/compare/v2.15.1...v2.16.0) (2022-11-20)

View File

@@ -25,10 +25,10 @@ repositories {
dependencies { dependencies {
implementation(kotlin("reflect")) implementation(kotlin("reflect"))
implementation("app.revanced:revanced-patcher:6.0.2") implementation("app.revanced:revanced-patcher:6.3.2")
implementation("info.picocli:picocli:4.7.0") implementation("info.picocli:picocli:4.7.0")
implementation("com.android.tools.build:apksig:7.2.1")
implementation("com.github.revanced:jadb:master-SNAPSHOT") // updated fork implementation("com.github.revanced:jadb:master-SNAPSHOT") // updated fork
implementation("com.android.tools.build:apksig:7.2.1")
implementation("org.bouncycastle:bcpkix-jdk15on:1.70") implementation("org.bouncycastle:bcpkix-jdk15on:1.70")
implementation("cc.ekblad:4koma:1.1.0") implementation("cc.ekblad:4koma:1.1.0")
} }
@@ -40,8 +40,11 @@ tasks {
shadowJar { shadowJar {
manifest { manifest {
attributes("Main-Class" to "app.revanced.cli.main.MainKt") attributes("Main-Class" to "app.revanced.cli.main.MainKt")
attributes("Implementation-Title" to project.name) }
attributes("Implementation-Version" to project.version) minimize {
exclude(dependency("org.jetbrains.kotlin:.*"))
exclude(dependency("org.bouncycastle:.*"))
exclude(dependency("app.revanced:.*"))
} }
} }
// Dummy task to fix the Gradle semantic-release plugin. // Dummy task to fix the Gradle semantic-release plugin.

View File

@@ -1,2 +1,2 @@
kotlin.code.style = official kotlin.code.style = official
version = 2.16.0 version = 2.20.0-dev.1

6107
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

8
package.json Normal file
View File

@@ -0,0 +1,8 @@
{
"devDependencies": {
"@semantic-release/changelog": "^6.0.2",
"@semantic-release/git": "^10.0.1",
"gradle-semantic-release-plugin": "^1.7.4",
"semantic-release": "^19.0.5"
}
}

View File

@@ -1,12 +1,37 @@
package app.revanced.cli.aligning package app.revanced.cli.aligning
import app.revanced.cli.command.MainCommand.logger import app.revanced.cli.command.MainCommand.logger
import app.revanced.patcher.PatcherResult
import app.revanced.utils.signing.align.ZipAligner import app.revanced.utils.signing.align.ZipAligner
import app.revanced.utils.signing.align.zip.ZipFile
import app.revanced.utils.signing.align.zip.structures.ZipEntry
import java.io.File import java.io.File
object Aligning { object Aligning {
fun align(inputFile: File, outputFile: File) { fun align(result: PatcherResult, inputFile: File, outputFile: File) {
logger.info("Aligning ${inputFile.name} to ${outputFile.name}") logger.info("Aligning ${inputFile.name} to ${outputFile.name}")
ZipAligner.align(inputFile, outputFile)
if (outputFile.exists()) outputFile.delete()
ZipFile(outputFile).use { file ->
result.dexFiles.forEach {
file.addEntryCompressData(
ZipEntry.createWithName(it.name),
it.stream.readBytes()
)
}
result.resourceFile?.let {
file.copyEntriesFromFileAligned(
ZipFile(it),
ZipAligner::getEntryAlignment
)
}
file.copyEntriesFromFileAligned(
ZipFile(inputFile),
ZipAligner::getEntryAlignment
)
}
} }
} }

View File

@@ -49,7 +49,7 @@ internal object MainCommand : Runnable {
} }
class PatchArgs { class PatchArgs {
@Option(names = ["-b", "--bundles"], description = ["One or more bundles of patches"], required = true) @Option(names = ["-b", "--bundle"], description = ["One or more bundles of patches"], required = true)
var patchBundles = arrayOf<String>() var patchBundles = arrayOf<String>()
@Option(names = ["--options"], description = ["Configuration file for all patch options"]) @Option(names = ["--options"], description = ["Configuration file for all patch options"])
@@ -63,7 +63,7 @@ internal object MainCommand : Runnable {
} }
class ListingArgs { class ListingArgs {
@Option(names = ["-l", "--list"], description = ["List patches only"], required = true) @Option(names = ["-l", "--list"], description = ["List patches"], required = true)
var listOnly: Boolean = false var listOnly: Boolean = false
@Option(names = ["--with-versions"], description = ["List patches with compatible versions"]) @Option(names = ["--with-versions"], description = ["List patches with compatible versions"])
@@ -71,9 +71,6 @@ internal object MainCommand : Runnable {
@Option(names = ["--with-packages"], description = ["List patches with compatible packages"]) @Option(names = ["--with-packages"], description = ["List patches with compatible packages"])
var withPackages: Boolean = false var withPackages: Boolean = false
@Option(names = ["--with-descriptions"], description = ["List patches with their descriptions"])
var withDescriptions: Boolean = true
} }
class PatchingArgs { class PatchingArgs {
@@ -87,7 +84,7 @@ internal object MainCommand : Runnable {
names = ["--exclusive"], names = ["--exclusive"],
description = ["Only installs the patches you include, not including any patch by default"] description = ["Only installs the patches you include, not including any patch by default"]
) )
var defaultExclude = false var exclusive = false
@Option(names = ["-i", "--include"], description = ["Include patches"]) @Option(names = ["-i", "--include"], description = ["Include patches"])
var includedPatches = arrayOf<String>() var includedPatches = arrayOf<String>()
@@ -151,16 +148,14 @@ internal object MainCommand : Runnable {
Adb(outputFile, patcher.context.packageMetadata.packageName, args.deploy!!, !pArgs.mount) Adb(outputFile, patcher.context.packageMetadata.packageName, args.deploy!!, !pArgs.mount)
} }
val patchedFile = File(pArgs.cacheDirectory).resolve("${outputFile.nameWithoutExtension}_raw.apk")
// start the patcher // start the patcher
Patcher.start(patcher, patchedFile, allPatches) val result = Patcher.start(patcher, allPatches)
val cacheDirectory = File(pArgs.cacheDirectory) val cacheDirectory = File(pArgs.cacheDirectory)
// align the file // align the file
val alignedFile = cacheDirectory.resolve("${outputFile.nameWithoutExtension}_aligned.apk") val alignedFile = cacheDirectory.resolve("${outputFile.nameWithoutExtension}_aligned.apk")
Aligning.align(patchedFile, alignedFile) Aligning.align(result, args.inputFile, alignedFile)
// sign the file // sign the file
val finalFile = if (!pArgs.mount) { val finalFile = if (!pArgs.mount) {
@@ -222,7 +217,7 @@ internal object MainCommand : Runnable {
for (patchBundlePath in args.patchArgs?.patchBundles!!) for (patch in PatchBundle.Jar(patchBundlePath) for (patchBundlePath in args.patchArgs?.patchBundles!!) for (patch in PatchBundle.Jar(patchBundlePath)
.loadPatches()) { .loadPatches()) {
if (patch.patchName in logged) continue if (patch.patchName in logged) continue
for (compatiblePackage in patch.compatiblePackages!!) { for (compatiblePackage in patch.compatiblePackages ?: continue) {
val packageEntryStr = buildString { val packageEntryStr = buildString {
// Add package if flag is set // Add package if flag is set
if (args.patchArgs?.listingArgs?.withPackages == true) { if (args.patchArgs?.listingArgs?.withPackages == true) {
@@ -230,14 +225,15 @@ internal object MainCommand : Runnable {
append(packageName) append(packageName)
append("\t") append("\t")
} }
// Add patch name // Add patch name
val patchName = patch.patchName.padStart(25) val patchName = patch.patchName.padStart(25)
append(patchName) append(patchName)
// Add description if flag is set. // Add description if flag is set.
if (args.patchArgs?.listingArgs?.withDescriptions == true) {
append("\t") append("\t")
append(patch.description) append(patch.description)
}
// Add compatible versions, if flag is set // Add compatible versions, if flag is set
if (args.patchArgs?.listingArgs?.withVersions == true) { if (args.patchArgs?.listingArgs?.withVersions == true) {
val compatibleVersions = compatiblePackage.versions.joinToString(separator = ", ") val compatibleVersions = compatiblePackage.versions.joinToString(separator = ", ")

View File

@@ -1,24 +1,17 @@
package app.revanced.cli.patcher package app.revanced.cli.patcher
import app.revanced.cli.command.MainCommand.args import app.revanced.patcher.PatcherResult
import app.revanced.cli.command.MainCommand.logger
import app.revanced.patcher.data.Context import app.revanced.patcher.data.Context
import app.revanced.patcher.patch.Patch import app.revanced.patcher.patch.Patch
import app.revanced.utils.filesystem.ZipFileSystemUtils
import app.revanced.utils.patcher.addPatchesFiltered import app.revanced.utils.patcher.addPatchesFiltered
import app.revanced.utils.patcher.applyPatchesVerbose import app.revanced.utils.patcher.applyPatchesVerbose
import app.revanced.utils.patcher.mergeFiles import app.revanced.utils.patcher.mergeFiles
import java.io.File
import java.nio.file.Files
internal object Patcher { internal object Patcher {
internal fun start( internal fun start(
patcher: app.revanced.patcher.Patcher, patcher: app.revanced.patcher.Patcher,
output: File,
allPatches: List<Class<out Patch<Context>>> allPatches: List<Class<out Patch<Context>>>
) { ): PatcherResult {
val inputFile = args.inputFile
// merge files like necessary integrations // merge files like necessary integrations
patcher.mergeFiles() patcher.mergeFiles()
// add patches, but filter incompatible or excluded patches // add patches, but filter incompatible or excluded patches
@@ -26,28 +19,6 @@ internal object Patcher {
// apply patches // apply patches
patcher.applyPatchesVerbose() patcher.applyPatchesVerbose()
// write output file return patcher.save()
if (output.exists()) Files.delete(output.toPath())
inputFile.copyTo(output)
val result = patcher.save()
ZipFileSystemUtils(output).use { outputFileSystem ->
// replace all dex files
result.dexFiles.forEach {
logger.info("Writing dex file ${it.name}")
outputFileSystem.write(it.name, it.stream.readAllBytes())
}
result.resourceFile?.let {
logger.info("Writing resources...")
ZipFileSystemUtils(it).use { resourceFileSystem ->
val resourceFiles = resourceFileSystem.getFile(File.separator)
outputFileSystem.writePathRecursively(resourceFiles)
}
}
result.doNotCompress?.let { outputFileSystem.uncompress(*it.toTypedArray()) }
}
} }
} }

View File

@@ -1,64 +0,0 @@
package app.revanced.utils.filesystem
import java.io.Closeable
import java.io.File
import java.nio.file.FileSystems
import java.nio.file.Files
import java.nio.file.Path
import java.util.zip.ZipEntry
internal class ZipFileSystemUtils(
file: File
) : Closeable {
private var zipFileSystem = FileSystems.newFileSystem(file.toPath(), mapOf("noCompression" to true))
private fun Path.deleteRecursively() {
if (!Files.exists(this)) {
throw IllegalStateException("File exists in real folder but not in zip file system")
}
if (Files.isDirectory(this)) {
Files.list(this).forEach { path ->
path.deleteRecursively()
}
}
Files.delete(this)
}
internal fun getFile(path: String) = zipFileSystem.getPath(path)
internal fun writePathRecursively(path: Path) {
Files.list(path).use { fileStream ->
fileStream.forEach { filePath ->
val fileSystemPath = filePath.getRelativePath(path)
fileSystemPath.deleteRecursively()
}
}
Files.walk(path).use { fileStream ->
// don't include build directory
// by skipping the root node.
fileStream.skip(1).forEach { filePath ->
val relativePath = filePath.getRelativePath(path)
if (Files.isDirectory(filePath)) {
Files.createDirectory(relativePath)
return@forEach
}
Files.copy(filePath, relativePath)
}
}
}
internal fun write(path: String, content: ByteArray) = Files.write(zipFileSystem.getPath(path), content)
private fun Path.getRelativePath(path: Path): Path = zipFileSystem.getPath(path.relativize(this).toString())
// TODO: figure out why the file system is uncompressed by default and how to fix it
internal fun uncompress(vararg paths: String) =
paths.forEach { Files.setAttribute(zipFileSystem.getPath(it), "zip:method", ZipEntry.STORED) }
override fun close() = zipFileSystem.close()
}

View File

@@ -6,7 +6,6 @@ import app.revanced.cli.command.MainCommand.logger
import app.revanced.patcher.Patcher import app.revanced.patcher.Patcher
import app.revanced.patcher.data.Context import app.revanced.patcher.data.Context
import app.revanced.patcher.extensions.PatchExtensions.compatiblePackages import app.revanced.patcher.extensions.PatchExtensions.compatiblePackages
import app.revanced.patcher.extensions.PatchExtensions.deprecated
import app.revanced.patcher.extensions.PatchExtensions.include import app.revanced.patcher.extensions.PatchExtensions.include
import app.revanced.patcher.extensions.PatchExtensions.patchName import app.revanced.patcher.extensions.PatchExtensions.patchName
import app.revanced.patcher.patch.Patch import app.revanced.patcher.patch.Patch
@@ -19,26 +18,11 @@ fun Patcher.addPatchesFiltered(allPatches: List<Class<out Patch<Context>>>) {
allPatches.forEach patchLoop@{ patch -> allPatches.forEach patchLoop@{ patch ->
val compatiblePackages = patch.compatiblePackages val compatiblePackages = patch.compatiblePackages
val patchName = patch.patchName val patchName = patch.patchName
val prefix = "Skipping $patchName, reason"
val args = MainCommand.args.patchArgs?.patchingArgs!! val args = MainCommand.args.patchArgs?.patchingArgs!!
if (args.excludedPatches.contains(patchName)) { val prefix = "Skipping $patchName"
logger.info("$prefix: manually excluded")
return@patchLoop
} else if ((!patch.include || args.defaultExclude) && !args.includedPatches.contains(patchName)) {
logger.info("$prefix: excluded by default")
return@patchLoop
}
patch.deprecated?.let { (reason, replacement) -> if (compatiblePackages == null) logger.trace("$patchName: No constraint on packages.")
logger.warn("$prefix: deprecated: $reason")
if (replacement != null) logger.warn("Either use ${replacement.java.patchName} instead or include it manually")
return@patchLoop
}
if (compatiblePackages == null) logger.warn("$prefix: Missing compatibility annotation. Continuing.")
else { else {
if (!compatiblePackages.any { it.name == packageName }) { if (!compatiblePackages.any { it.name == packageName }) {
logger.trace("$prefix: Incompatible with $packageName. This patch is only compatible with ${ logger.trace("$prefix: Incompatible with $packageName. This patch is only compatible with ${
@@ -58,6 +42,14 @@ fun Patcher.addPatchesFiltered(allPatches: List<Class<out Patch<Context>>>) {
} }
} }
if (args.excludedPatches.contains(patchName)) {
logger.info("$prefix: Manually excluded")
return@patchLoop
} else if ((!patch.include || args.exclusive) && !args.includedPatches.contains(patchName)) {
logger.info("$prefix: Excluded by default")
return@patchLoop
}
logger.trace("Adding $patchName") logger.trace("Adding $patchName")
includedPatches.add(patch) includedPatches.add(patch)
} }

View File

@@ -1,28 +1,11 @@
package app.revanced.utils.signing.align package app.revanced.utils.signing.align
import app.revanced.utils.signing.align.zip.ZipFile import app.revanced.utils.signing.align.zip.structures.ZipEntry
import java.io.File
internal object ZipAligner { internal object ZipAligner {
private const val DEFAULT_ALIGNMENT = 4 private const val DEFAULT_ALIGNMENT = 4
private const val LIBRARY_ALIGNMENT = 4096 private const val LIBRARY_ALIGNMENT = 4096
fun align(input: File, output: File) { fun getEntryAlignment(entry: ZipEntry): Int? =
val inputZip = ZipFile(input) if (entry.compression.toUInt() != 0u) null else if (entry.fileName.endsWith(".so")) LIBRARY_ALIGNMENT else DEFAULT_ALIGNMENT
val outputZip = ZipFile(output)
for (entry in inputZip.entries) {
val data = inputZip.getDataForEntry(entry)
if (entry.compression == 0.toUShort()) {
val alignment = if (entry.fileName.endsWith(".so")) LIBRARY_ALIGNMENT else DEFAULT_ALIGNMENT
outputZip.addEntryAligned(entry, data, alignment)
} else {
outputZip.addEntry(entry, data)
}
}
outputZip.finish()
}
} }

View File

@@ -2,15 +2,21 @@ package app.revanced.utils.signing.align.zip
import app.revanced.utils.signing.align.zip.structures.ZipEndRecord import app.revanced.utils.signing.align.zip.structures.ZipEndRecord
import app.revanced.utils.signing.align.zip.structures.ZipEntry import app.revanced.utils.signing.align.zip.structures.ZipEntry
import java.io.Closeable
import java.io.File import java.io.File
import java.io.RandomAccessFile import java.io.RandomAccessFile
import java.nio.ByteBuffer import java.nio.ByteBuffer
import java.nio.channels.FileChannel import java.nio.channels.FileChannel
import java.util.zip.CRC32
import java.util.zip.Deflater
class ZipFile(val file: File) { class ZipFile(file: File) : Closeable {
var entries: MutableList<ZipEntry> = mutableListOf() var entries: MutableList<ZipEntry> = mutableListOf()
private val filePointer: RandomAccessFile = RandomAccessFile(file, "rw") private val filePointer: RandomAccessFile = RandomAccessFile(file, "rw")
private var CDNeedsRewrite = false
private val compressionLevel = 5
init { init {
//if file isn't empty try to load entries //if file isn't empty try to load entries
@@ -53,7 +59,8 @@ class ZipFile(val file: File) {
return buildList(numberOfEntries) { return buildList(numberOfEntries) {
for (i in 1..numberOfEntries) { for (i in 1..numberOfEntries) {
add(ZipEntry.fromCDE(filePointer).also add(
ZipEntry.fromCDE(filePointer).also
{ {
//for some reason the local extra field can be different from the central one //for some reason the local extra field can be different from the central one
it.readLocalExtra( it.readLocalExtra(
@@ -68,8 +75,8 @@ class ZipFile(val file: File) {
} }
} }
private fun writeCDE() { private fun writeCD() {
val CDEStart = filePointer.channel.position().toUInt() val CDStart = filePointer.channel.position().toUInt()
entries.forEach { entries.forEach {
filePointer.channel.write(it.toCDE()) filePointer.channel.write(it.toCDE())
@@ -82,15 +89,17 @@ class ZipFile(val file: File) {
0u, 0u,
entriesCount, entriesCount,
entriesCount, entriesCount,
filePointer.channel.position().toUInt() - CDEStart, filePointer.channel.position().toUInt() - CDStart,
CDEStart, CDStart,
"" ""
) )
filePointer.channel.write(endRecord.toECD()) filePointer.channel.write(endRecord.toECD())
} }
fun addEntry(entry: ZipEntry, data: ByteBuffer) { private fun addEntry(entry: ZipEntry, data: ByteBuffer) {
CDNeedsRewrite = true
entry.localHeaderOffset = filePointer.channel.position().toUInt() entry.localHeaderOffset = filePointer.channel.position().toUInt()
filePointer.channel.write(entry.toLFH()) filePointer.channel.write(entry.toLFH())
@@ -99,7 +108,34 @@ class ZipFile(val file: File) {
entries.add(entry) entries.add(entry)
} }
fun addEntryAligned(entry: ZipEntry, data: ByteBuffer, alignment: Int) { fun addEntryCompressData(entry: ZipEntry, data: ByteArray) {
val compressor = Deflater(compressionLevel, true)
compressor.setInput(data)
compressor.finish()
val uncompressedSize = data.size
val compressedData =
ByteArray(uncompressedSize) //i'm guessing compression won't make the data bigger
val compressedDataLength = compressor.deflate(compressedData)
val compressedBuffer =
ByteBuffer.wrap(compressedData.take(compressedDataLength).toByteArray())
compressor.end()
val crc = CRC32()
crc.update(data)
entry.compression = 8u //deflate compression
entry.uncompressedSize = uncompressedSize.toUInt()
entry.compressedSize = compressedDataLength.toUInt()
entry.crc32 = crc.value.toUInt()
addEntry(entry, compressedBuffer)
}
private fun addEntryCopyData(entry: ZipEntry, data: ByteBuffer, alignment: Int? = null) {
alignment?.let {
//calculate where data would end up //calculate where data would end up
val dataOffset = filePointer.filePointer + entry.LFHSize val dataOffset = filePointer.filePointer + entry.LFHSize
@@ -111,6 +147,7 @@ class ZipFile(val file: File) {
entry.localExtraField = entry.localExtraField =
entry.localExtraField.copyOf((entry.localExtraField.size + (alignment - mod)).toInt()) entry.localExtraField.copyOf((entry.localExtraField.size + (alignment - mod)).toInt())
} }
}
addEntry(entry, data) addEntry(entry, data)
} }
@@ -123,8 +160,17 @@ class ZipFile(val file: File) {
) )
} }
fun finish() { fun copyEntriesFromFileAligned(file: ZipFile, entryAlignment: (entry: ZipEntry) -> Int?) {
writeCDE() for (entry in file.entries) {
if (entries.any { it.fileName == entry.fileName }) continue //don't add duplicates
val data = file.getDataForEntry(entry)
addEntryCopyData(entry, data, entryAlignment(entry))
}
}
override fun close() {
if (CDNeedsRewrite) writeCD()
filePointer.close() filePointer.close()
} }
} }

View File

@@ -9,12 +9,12 @@ data class ZipEntry(
val version: UShort, val version: UShort,
val versionNeeded: UShort, val versionNeeded: UShort,
val flags: UShort, val flags: UShort,
val compression: UShort, var compression: UShort,
val modificationTime: UShort, val modificationTime: UShort,
val modificationDate: UShort, val modificationDate: UShort,
val crc32: UInt, var crc32: UInt,
val compressedSize: UInt, var compressedSize: UInt,
val uncompressedSize: UInt, var uncompressedSize: UInt,
val diskNumber: UShort, val diskNumber: UShort,
val internalAttributes: UShort, val internalAttributes: UShort,
val externalAttributes: UInt, val externalAttributes: UInt,
@@ -22,7 +22,7 @@ data class ZipEntry(
val fileName: String, val fileName: String,
val extraField: ByteArray, val extraField: ByteArray,
val fileComment: String, val fileComment: String,
var localExtraField: ByteArray = ByteArray(0), //seperate for alignment var localExtraField: ByteArray = ByteArray(0), //separate for alignment
) { ) {
val LFHSize: Int val LFHSize: Int
get() = LFH_HEADER_SIZE + fileName.toByteArray(Charsets.UTF_8).size + localExtraField.size get() = LFH_HEADER_SIZE + fileName.toByteArray(Charsets.UTF_8).size + localExtraField.size
@@ -37,6 +37,27 @@ data class ZipEntry(
const val LFH_HEADER_SIZE = 30 const val LFH_HEADER_SIZE = 30
const val LFH_SIGNATURE = 0x04034b50u const val LFH_SIGNATURE = 0x04034b50u
fun createWithName(fileName: String): ZipEntry {
return ZipEntry(
0x1403u, //made by unix, version 20
0u,
0u,
0u,
0x0821u, //seems to be static time google uses, no idea
0x0221u, //same as above
0u,
0u,
0u,
0u,
0u,
0u,
0u,
fileName,
ByteArray(0),
""
)
}
fun fromCDE(input: DataInput): ZipEntry { fun fromCDE(input: DataInput): ZipEntry {
val signature = input.readUIntLE() val signature = input.readUIntLE()
@@ -55,7 +76,7 @@ data class ZipEntry(
val fileNameLength = input.readUShortLE() val fileNameLength = input.readUShortLE()
var fileName = "" var fileName = ""
val extraFieldLength = input.readUShortLE() val extraFieldLength = input.readUShortLE()
var extraField = ByteArray(extraFieldLength.toInt()) val extraField = ByteArray(extraFieldLength.toInt())
val fileCommentLength = input.readUShortLE() val fileCommentLength = input.readUShortLE()
var fileComment = "" var fileComment = ""
val diskNumber = input.readUShortLE() val diskNumber = input.readUShortLE()
@@ -63,7 +84,8 @@ data class ZipEntry(
val externalAttributes = input.readUIntLE() val externalAttributes = input.readUIntLE()
val localHeaderOffset = input.readUIntLE() val localHeaderOffset = input.readUIntLE()
val variableFieldsLength = fileNameLength.toInt() + extraFieldLength.toInt() + fileCommentLength.toInt() val variableFieldsLength =
fileNameLength.toInt() + extraFieldLength.toInt() + fileCommentLength.toInt()
if (variableFieldsLength > 0) { if (variableFieldsLength > 0) {
val fileNameBytes = ByteArray(fileNameLength.toInt()) val fileNameBytes = ByteArray(fileNameLength.toInt())
@@ -77,7 +99,8 @@ data class ZipEntry(
fileComment = fileCommentBytes.toString(Charsets.UTF_8) fileComment = fileCommentBytes.toString(Charsets.UTF_8)
} }
flags = (flags and 0b1000u.inv().toUShort()) //disable data descriptor flag as they are not used flags = (flags and 0b1000u.inv()
.toUShort()) //disable data descriptor flag as they are not used
return ZipEntry( return ZipEntry(
version, version,
@@ -134,7 +157,8 @@ data class ZipEntry(
val nameBytes = fileName.toByteArray(Charsets.UTF_8) val nameBytes = fileName.toByteArray(Charsets.UTF_8)
val commentBytes = fileComment.toByteArray(Charsets.UTF_8) val commentBytes = fileComment.toByteArray(Charsets.UTF_8)
val buffer = ByteBuffer.allocate(CDE_HEADER_SIZE + nameBytes.size + extraField.size + commentBytes.size) val buffer =
ByteBuffer.allocate(CDE_HEADER_SIZE + nameBytes.size + extraField.size + commentBytes.size)
.also { it.order(ByteOrder.LITTLE_ENDIAN) } .also { it.order(ByteOrder.LITTLE_ENDIAN) }
buffer.putUInt(CDE_SIGNATURE) buffer.putUInt(CDE_SIGNATURE)
@@ -163,4 +187,3 @@ data class ZipEntry(
return buffer return buffer
} }
} }