feat: Add ability to write patching results to JSON file#25
Merged
Conversation
Contributor
Author
|
Updated results file {
"packageName": "com.rubenmayayo.reddit",
"packageVersion": "1.12.12",
"success": false,
"patchingSteps": [
{
"step": "PATCHING",
"success": true
},
{
"step": "REBUILDING",
"success": true
},
{
"step": "SIGNING",
"success": true
}
],
"appliedPatches": [
{
"name": "Add archive links to context menu"
},
{
"name": "Automatically undelete Imgur images"
},
{
"name": "Automatically undelete Reddit content"
},
{
"name": "Disable ads"
},
{
"name": "Fix /s/ links"
},
{
"name": "Fix Redgifs API"
},
{
"name": "Fix missing audio in video downloads"
},
{
"name": "Intercept HTTP requests"
}
],
"failedPatches": [
{
"patch": {
"name": "Spoof client",
"options": [
{
"key": "client-id",
"value": null
},
{
"key": "redirect-uri",
"value": null
},
{
"key": "user-agent",
"value": null
}
]
},
"reason": "app.morphe.patcher.patch.PatchException: When spoofing client, at least one of clientId, redirectUri or userAgent should be set.\n\tat app.morphe.patches.reddit.customclients.boostforreddit.api.SpoofClientPatchKt.spoofClientPatch$lambda$13$lambda$12(SpoofClientPatch.kt:26)\n\tat app.morphe.patcher.patch.Patch.execute(Patch.kt:71)\n\tat app.morphe.patcher.patch.BytecodePatch.execute$morphe_patcher(Patch.kt:160)\n\tat app.morphe.patcher.Patcher$invoke$1.invokeSuspend$execute(Patcher.kt:84)\n\tat app.morphe.patcher.Patcher$invoke$1.invokeSuspend(Patcher.kt:104)\n\tat app.morphe.patcher.Patcher$invoke$1.invoke(Patcher.kt)\n\tat app.morphe.patcher.Patcher$invoke$1.invoke(Patcher.kt)\n\tat kotlinx.coroutines.flow.SafeFlow.collectSafely(Builders.kt:57)\n\tat kotlinx.coroutines.flow.AbstractFlow.collect(Flow.kt:226)\n\tat app.morphe.cli.command.PatchCommand$run$1$4$1.invokeSuspend(PatchCommand.kt:352)\n\tat kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:34)\n\tat kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:100)\n\tat kotlinx.coroutines.EventLoopImplBase.processNextEvent(EventLoop.common.kt:263)\n\tat kotlinx.coroutines.BlockingCoroutine.joinBlocking(Builders.kt:94)\n\tat kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking(Builders.kt:70)\n\tat kotlinx.coroutines.BuildersKt.runBlocking(Unknown Source)\n\tat kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking$default(Builders.kt:48)\n\tat kotlinx.coroutines.BuildersKt.runBlocking$default(Unknown Source)\n\tat app.morphe.cli.command.PatchCommand.run$lambda$1$2(PatchCommand.kt:351)\n\tat app.morphe.cli.command.model.PatchingResultKt.addStepResult(PatchingResult.kt:26)\n\tat app.morphe.cli.command.PatchCommand.run(PatchCommand.kt:347)\n\tat picocli.CommandLine.executeUserObject(CommandLine.java:2045)\n\tat picocli.CommandLine.access$1500(CommandLine.java:148)\n\tat picocli.CommandLine$RunLast.executeUserObjectOfLastSubcommandWithSameParent(CommandLine.java:2469)\n\tat picocli.CommandLine$RunLast.handle(CommandLine.java:2461)\n\tat picocli.CommandLine$RunLast.handle(CommandLine.java:2423)\n\tat picocli.CommandLine$AbstractParseResultHandler.execute(CommandLine.java:2277)\n\tat picocli.CommandLine$RunLast.execute(CommandLine.java:2425)\n\tat picocli.CommandLine.execute(CommandLine.java:2174)\n\tat app.morphe.cli.command.MainCommandKt.main(MainCommand.kt:12)\n"
}
]
} |
There was a problem hiding this comment.
Pull request overview
This pull request adds functionality to export patching results to a JSON file via the -r/--result-file command-line option. The feature tracks successful and failed patches along with their options, and optionally tracks the results of patching steps (PATCHING, REBUILDING, SIGNING, INSTALLING).
Changes:
- Added Kotlin serialization support with new dependencies (kotlinx-serialization-json) and plugin
- Created model classes to represent patching results, steps, and serializable patch information
- Modified PatchCommand to collect and serialize patching results to a JSON file
Reviewed changes
Copilot reviewed 7 out of 8 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
| gradle/libs.versions.toml | Updated Kotlin version to 2.3.0 and kotlinx to 1.9.0, added kotlinx-serialization-json dependency and kotlin-serialization plugin |
| build.gradle.kts | Added kotlin-serialization plugin and kotlinx-serialization-json dependency |
| src/main/kotlin/app/morphe/cli/command/model/PatchingStep.kt | Created enum to represent different patching steps (PATCHING, REBUILDING, SIGNING, INSTALLING) |
| src/main/kotlin/app/morphe/cli/command/model/PatchingStepResult.kt | Created data class to store the result of each patching step with success status and optional error message |
| src/main/kotlin/app/morphe/cli/command/model/FailedPatch.kt | Created data class to represent a failed patch with its information and failure reason |
| src/main/kotlin/app/morphe/cli/command/model/SerializablePatch.kt | Created serializable representation of a patch with custom serializer to handle options as JSON elements |
| src/main/kotlin/app/morphe/cli/command/model/PatchingResult.kt | Created main result container with applied/failed patches, step results, and a helper function to track step execution |
| src/main/kotlin/app/morphe/cli/command/PatchCommand.kt | Added result-file option, wrapped patching logic with result tracking, and added finally block to write JSON output |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Contributor
Author
|
After changes to logic to rethrow exceptions from installer step: {
"packageName": "com.rubenmayayo.reddit",
"packageVersion": "1.12.12",
"success": false,
"patchingSteps": [
{
"step": "PATCHING",
"success": true
},
{
"step": "REBUILDING",
"success": true
},
{
"step": "SIGNING",
"success": true
},
{
"step": "INSTALLING",
"success": false,
"message": "se.vidstige.jadb.JadbException: Could not install com.rubenmayayo.reddit_1.12.12-210011212_minAPI21(arm64-v8a,armeabi,armeabi-v7a,mips,mips64,x86,x86_64)(nodpi)_apkmirror.com-patched.apk: Failure [INSTALL_FAILED_UPDATE_INCOMPATIBLE: Existing package com.rubenmayayo.reddit signatures do not match newer version; ignoring!]\n"
}
],
"appliedPatches": [
{
"name": "Add archive links to context menu"
},
{
"name": "Automatically undelete Imgur images"
},
{
"name": "Automatically undelete Reddit content"
},
{
"name": "Disable ads"
},
{
"name": "Fix /s/ links"
},
{
"name": "Fix Redgifs API"
},
{
"name": "Fix missing audio in video downloads"
},
{
"name": "Intercept HTTP requests"
}
],
"failedPatches": [
{
"patch": {
"name": "Spoof client",
"options": [
{
"key": "client-id",
"value": null
},
{
"key": "redirect-uri",
"value": null
},
{
"key": "user-agent",
"value": null
}
]
},
"reason": "app.morphe.patcher.patch.PatchException: When spoofing client, at least one of clientId, redirectUri or userAgent should be set.\n\tat app.morphe.patches.reddit.customclients.boostforreddit.api.SpoofClientPatchKt.spoofClientPatch$lambda$13$lambda$12(SpoofClientPatch.kt:26)\n\tat app.morphe.patcher.patch.Patch.execute(Patch.kt:71)\n\tat app.morphe.patcher.patch.BytecodePatch.execute$morphe_patcher(Patch.kt:160)\n\tat app.morphe.patcher.Patcher$invoke$1.invokeSuspend$execute(Patcher.kt:84)\n\tat app.morphe.patcher.Patcher$invoke$1.invokeSuspend(Patcher.kt:104)\n\tat app.morphe.patcher.Patcher$invoke$1.invoke(Patcher.kt)\n\tat app.morphe.patcher.Patcher$invoke$1.invoke(Patcher.kt)\n\tat kotlinx.coroutines.flow.SafeFlow.collectSafely(Builders.kt:57)\n\tat kotlinx.coroutines.flow.AbstractFlow.collect(Flow.kt:226)\n\tat app.morphe.cli.command.PatchCommand$run$1$4$1.invokeSuspend(PatchCommand.kt:351)\n\tat kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:34)\n\tat kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:100)\n\tat kotlinx.coroutines.EventLoopImplBase.processNextEvent(EventLoop.common.kt:263)\n\tat kotlinx.coroutines.BlockingCoroutine.joinBlocking(Builders.kt:94)\n\tat kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking(Builders.kt:70)\n\tat kotlinx.coroutines.BuildersKt.runBlocking(Unknown Source)\n\tat kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking$default(Builders.kt:48)\n\tat kotlinx.coroutines.BuildersKt.runBlocking$default(Unknown Source)\n\tat app.morphe.cli.command.PatchCommand.run$lambda$1$2(PatchCommand.kt:350)\n\tat app.morphe.cli.command.model.PatchingResultKt.addStepResult(PatchingResult.kt:24)\n\tat app.morphe.cli.command.PatchCommand.run(PatchCommand.kt:347)\n\tat picocli.CommandLine.executeUserObject(CommandLine.java:2045)\n\tat picocli.CommandLine.access$1500(CommandLine.java:148)\n\tat picocli.CommandLine$RunLast.executeUserObjectOfLastSubcommandWithSameParent(CommandLine.java:2469)\n\tat picocli.CommandLine$RunLast.handle(CommandLine.java:2461)\n\tat picocli.CommandLine$RunLast.handle(CommandLine.java:2423)\n\tat picocli.CommandLine$AbstractParseResultHandler.execute(CommandLine.java:2277)\n\tat picocli.CommandLine$RunLast.execute(CommandLine.java:2425)\n\tat picocli.CommandLine.execute(CommandLine.java:2174)\n\tat app.morphe.cli.command.MainCommandKt.main(MainCommand.kt:12)\n"
}
]
} |
github-actions Bot
pushed a commit
that referenced
this pull request
Jan 11, 2026
# [1.2.0-dev.1](v1.1.0...v1.2.0-dev.1) (2026-01-11) ### Features * Add ability to write patching results to JSON file ([#25](#25)) ([304b3ea](304b3ea))
AzyrRuthless
pushed a commit
to AzyrRuthless/morphe-cli
that referenced
this pull request
Feb 6, 2026
Adds the ability to dump the patching results to a JSON file by passing `-r`/`--result-file`. The result file contains package metadata, the result of the overall process, the result of each individual step, and a list of successfully applied/failed patches along with the options used and stacktraces (if applicable).
github-actions Bot
pushed a commit
to AzyrRuthless/morphe-cli
that referenced
this pull request
Feb 6, 2026
# [1.0.0-dev.2](v1.0.0-dev.1...v1.0.0-dev.2) (2026-02-06) ### Features * Add ability to write patching results to JSON file ([MorpheApp#25](https://github.com/AzyrRuthless/morphe-cli/issues/25)) ([ed0d1ef](ed0d1ef)) * Update to Morphe patcher / library 1.1.0 ([2445b24](2445b24)) * Update to Morphe patcher 1.1.1 ([8fa5a83](8fa5a83))
github-actions Bot
pushed a commit
to AzyrRuthless/morphe-cli
that referenced
this pull request
Feb 6, 2026
# [1.1.0-dev.1](v1.0.0...v1.1.0-dev.1) (2026-02-06) ### Features * Add ability to write patching results to JSON file ([MorpheApp#25](https://github.com/AzyrRuthless/morphe-cli/issues/25)) ([ed0d1ef](ed0d1ef)) * Update to Morphe patcher / library 1.1.0 ([2445b24](2445b24)) * Update to Morphe patcher 1.1.1 ([8fa5a83](8fa5a83))
github-actions Bot
pushed a commit
to AzyrRuthless/morphe-cli
that referenced
this pull request
Feb 6, 2026
# [1.1.0](v1.0.0...v1.1.0) (2026-02-06) ### Features * Add ability to write patching results to JSON file ([MorpheApp#25](https://github.com/AzyrRuthless/morphe-cli/issues/25)) ([ed0d1ef](ed0d1ef)) * Update to Morphe patcher / library 1.1.0 ([2445b24](2445b24)) * Update to Morphe patcher 1.1.1 ([8fa5a83](8fa5a83))
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds the ability to dump the patching results to a JSON file by passing
-r/--result-file. Currently this only exports the list of successful/failed patches; it may be worth adding the results of dex compilation/aligning/signing as well.Example JSON (after pretty printing)
{ "appliedPatches": [ { "name": "Add archive links to context menu" }, { "name": "Automatically undelete Imgur images" }, { "name": "Automatically undelete Reddit content" }, { "name": "Disable ads" }, { "name": "Fix /s/ links" }, { "name": "Fix Redgifs API" }, { "name": "Fix missing audio in video downloads" }, { "name": "Intercept HTTP requests" } ], "failedPatches": [ { "patch": { "name": "Spoof client", "options": [ { "key": "client-id", "value": null }, { "key": "redirect-uri", "value": null }, { "key": "user-agent", "value": null } ] }, "reason": "app.morphe.patcher.patch.PatchException: When spoofing client, at least one of clientId, redirectUri or userAgent should be set.\n\tat app.morphe.patches.reddit.customclients.boostforreddit.api.SpoofClientPatchKt.spoofClientPatch$lambda$13$lambda$12(SpoofClientPatch.kt:26)\n\tat app.morphe.patcher.patch.Patch.execute(Patch.kt:71)\n\tat app.morphe.patcher.patch.BytecodePatch.execute$morphe_patcher(Patch.kt:160)\n\tat app.morphe.patcher.Patcher$invoke$1.invokeSuspend$execute(Patcher.kt:84)\n\tat app.morphe.patcher.Patcher$invoke$1.invokeSuspend(Patcher.kt:104)\n\tat app.morphe.patcher.Patcher$invoke$1.invoke(Patcher.kt)\n\tat app.morphe.patcher.Patcher$invoke$1.invoke(Patcher.kt)\n\tat kotlinx.coroutines.flow.SafeFlow.collectSafely(Builders.kt:57)\n\tat kotlinx.coroutines.flow.AbstractFlow.collect(Flow.kt:226)\n\tat app.morphe.cli.command.PatchCommand$run$1$4.invokeSuspend(PatchCommand.kt:341)\n\tat kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:34)\n\tat kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:100)\n\tat kotlinx.coroutines.EventLoopImplBase.processNextEvent(EventLoop.common.kt:263)\n\tat kotlinx.coroutines.BlockingCoroutine.joinBlocking(Builders.kt:94)\n\tat kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking(Builders.kt:70)\n\tat kotlinx.coroutines.BuildersKt.runBlocking(Unknown Source)\n\tat kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking$default(Builders.kt:48)\n\tat kotlinx.coroutines.BuildersKt.runBlocking$default(Unknown Source)\n\tat app.morphe.cli.command.PatchCommand.run(PatchCommand.kt:340)\n\tat picocli.CommandLine.executeUserObject(CommandLine.java:2045)\n\tat picocli.CommandLine.access$1500(CommandLine.java:148)\n\tat picocli.CommandLine$RunLast.executeUserObjectOfLastSubcommandWithSameParent(CommandLine.java:2469)\n\tat picocli.CommandLine$RunLast.handle(CommandLine.java:2461)\n\tat picocli.CommandLine$RunLast.handle(CommandLine.java:2423)\n\tat picocli.CommandLine$AbstractParseResultHandler.execute(CommandLine.java:2277)\n\tat picocli.CommandLine$RunLast.execute(CommandLine.java:2425)\n\tat picocli.CommandLine.execute(CommandLine.java:2174)\n\tat app.morphe.cli.command.MainCommandKt.main(MainCommand.kt:12)\n" } ] }