From fbb09f38dce49adc7f63b71bdf2df2ef0b84db04 Mon Sep 17 00:00:00 2001 From: Sculas Date: Tue, 2 Aug 2022 00:31:00 +0200 Subject: [PATCH 1/3] feat: patch options (#81) * feat: Patch Options * refactor: remove delegate property * feat: List patch options * refactor: add setter example to PatchOptionsUsage.kt * docs: add docs for PatchOptions * docs: tidy docs --- .../app/revanced/patcher/patch/Patch.kt | 5 + .../app/revanced/patcher/patch/PatchOption.kt | 100 ++++++++++++++++++ .../patcher/usage/PatchOptionsUsage.kt | 30 ++++++ .../usage/bytecode/ExampleBytecodePatch.kt | 16 +++ 4 files changed, 151 insertions(+) create mode 100644 src/main/kotlin/app/revanced/patcher/patch/PatchOption.kt create mode 100644 src/test/kotlin/app/revanced/patcher/usage/PatchOptionsUsage.kt diff --git a/src/main/kotlin/app/revanced/patcher/patch/Patch.kt b/src/main/kotlin/app/revanced/patcher/patch/Patch.kt index e48c6b3..53a3609 100644 --- a/src/main/kotlin/app/revanced/patcher/patch/Patch.kt +++ b/src/main/kotlin/app/revanced/patcher/patch/Patch.kt @@ -17,4 +17,9 @@ abstract class Patch { * The main function of the [Patch] which the patcher will call. */ abstract fun execute(data: @UnsafeVariance T): PatchResult + + /** + * A list of [PatchOption]s. + */ + open val options: Iterable> = listOf() } \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patcher/patch/PatchOption.kt b/src/main/kotlin/app/revanced/patcher/patch/PatchOption.kt new file mode 100644 index 0000000..216e881 --- /dev/null +++ b/src/main/kotlin/app/revanced/patcher/patch/PatchOption.kt @@ -0,0 +1,100 @@ +package app.revanced.patcher.patch + +/** + * A [Patch] option. + * @param key Unique identifier of the option. Example: _`settings.microg.enabled`_ + * @param default The default value of the option. + * @param title A human-readable title of the option. Example: _MicroG Settings_ + * @param description A human-readable description of the option. Example: _Settings integration for MicroG._ + * @param required Whether the option is required. + */ +@Suppress("MemberVisibilityCanBePrivate") +sealed class PatchOption( + val key: String, + default: T?, + val title: String, + val description: String, + val required: Boolean +) { + var value: T? = default + + /** + * A [PatchOption] representing a [String]. + * @see PatchOption + */ + class StringOption( + key: String, + default: String?, + title: String, + description: String, + required: Boolean = false + ) : PatchOption( + key, default, title, description, required + ) + + /** + * A [PatchOption] representing a [Boolean]. + * @see PatchOption + */ + class BooleanOption( + key: String, + default: Boolean?, + title: String, + description: String, + required: Boolean = false + ) : PatchOption( + key, default, title, description, required + ) + + /** + * A [PatchOption] with a list of allowed options. + * @param options A list of allowed options for the [ListOption]. + * @see PatchOption + */ + sealed class ListOption( + key: String, + default: E?, + val options: Iterable, + title: String, + description: String, + required: Boolean = false + ) : PatchOption( + key, default, title, description, required + ) { + init { + if (default !in options) { + throw IllegalStateException("Default option must be an allowed options") + } + } + } + + /** + * A [ListOption] of type [String]. + * @see ListOption + */ + class StringListOption( + key: String, + default: String?, + options: Iterable, + title: String, + description: String, + required: Boolean = false + ) : ListOption( + key, default, options, title, description, required + ) + + /** + * A [ListOption] of type [Int]. + * @see ListOption + */ + class IntListOption( + key: String, + default: Int?, + options: Iterable, + title: String, + description: String, + required: Boolean = false + ) : ListOption( + key, default, options, title, description, required + ) +} \ No newline at end of file diff --git a/src/test/kotlin/app/revanced/patcher/usage/PatchOptionsUsage.kt b/src/test/kotlin/app/revanced/patcher/usage/PatchOptionsUsage.kt new file mode 100644 index 0000000..2828e45 --- /dev/null +++ b/src/test/kotlin/app/revanced/patcher/usage/PatchOptionsUsage.kt @@ -0,0 +1,30 @@ +package app.revanced.patcher.usage + +import app.revanced.patcher.patch.PatchOption +import app.revanced.patcher.usage.bytecode.ExampleBytecodePatch + +fun patchOptionsUsage() { + val options = ExampleBytecodePatch().options + for (option in options) { + when (option) { + is PatchOption.StringOption -> { + option.value = "Hello World" + } + is PatchOption.BooleanOption -> { + option.value = false + } + is PatchOption.StringListOption -> { + option.value = option.options.first() + for (choice in option.options) { + println(choice) + } + } + is PatchOption.IntListOption -> { + option.value = option.options.first() + for (choice in option.options) { + println(choice) + } + } + } + } +} \ No newline at end of file diff --git a/src/test/kotlin/app/revanced/patcher/usage/bytecode/ExampleBytecodePatch.kt b/src/test/kotlin/app/revanced/patcher/usage/bytecode/ExampleBytecodePatch.kt index 9b6bf0f..c4d91fe 100644 --- a/src/test/kotlin/app/revanced/patcher/usage/bytecode/ExampleBytecodePatch.kt +++ b/src/test/kotlin/app/revanced/patcher/usage/bytecode/ExampleBytecodePatch.kt @@ -7,6 +7,7 @@ import app.revanced.patcher.data.impl.BytecodeData import app.revanced.patcher.extensions.addInstructions import app.revanced.patcher.extensions.or import app.revanced.patcher.extensions.replaceInstruction +import app.revanced.patcher.patch.PatchOption import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patcher.patch.annotations.DependencyType @@ -162,4 +163,19 @@ class ExampleBytecodePatch : BytecodePatch(listOf(ExampleFingerprint)) { ) ) } + + override val options = listOf( + PatchOption.StringOption( + "key", "default", "title", "description", true + ), + PatchOption.BooleanOption( + "key", true, "title", "description" // required defaults to false + ), + PatchOption.StringListOption( + "key", "TEST", listOf("TEST", "TEST1", "TEST2"), "title", "description" + ), + PatchOption.IntListOption( + "key", 1, listOf(1, 2, 3), "title", "description" + ), + ) } From 711b8a25a7c2842270b06e831ee7844a2c86d7c2 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Mon, 1 Aug 2022 22:32:32 +0000 Subject: [PATCH 2/3] chore(release): 2.8.0 [skip ci] # [2.8.0](https://github.com/revanced/revanced-patcher/compare/v2.7.0...v2.8.0) (2022-08-01) ### Bug Fixes * remove requirement for solution [skip ci] ([#80](https://github.com/revanced/revanced-patcher/issues/80)) ([9a4d30e](https://github.com/revanced/revanced-patcher/commit/9a4d30e15234ef62844f035c58a1143674d4c12e)) ### Features * patch options ([#81](https://github.com/revanced/revanced-patcher/issues/81)) ([fbb09f3](https://github.com/revanced/revanced-patcher/commit/fbb09f38dce49adc7f63b71bdf2df2ef0b84db04)) --- CHANGELOG.md | 12 ++++++++++++ gradle.properties | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fc4d292..b8b7297 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,15 @@ +# [2.8.0](https://github.com/revanced/revanced-patcher/compare/v2.7.0...v2.8.0) (2022-08-01) + + +### Bug Fixes + +* remove requirement for solution [skip ci] ([#80](https://github.com/revanced/revanced-patcher/issues/80)) ([9a4d30e](https://github.com/revanced/revanced-patcher/commit/9a4d30e15234ef62844f035c58a1143674d4c12e)) + + +### Features + +* patch options ([#81](https://github.com/revanced/revanced-patcher/issues/81)) ([fbb09f3](https://github.com/revanced/revanced-patcher/commit/fbb09f38dce49adc7f63b71bdf2df2ef0b84db04)) + # [2.7.0](https://github.com/revanced/revanced-patcher/compare/v2.6.0...v2.7.0) (2022-08-01) diff --git a/gradle.properties b/gradle.properties index 74f0367..f5c5a21 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,2 +1,2 @@ kotlin.code.style = official -version = 2.7.0 +version = 2.8.0 From ec1d8a8fba6ed9b493425f2d4045dd0fd747525c Mon Sep 17 00:00:00 2001 From: Sculas Date: Tue, 2 Aug 2022 00:47:32 +0200 Subject: [PATCH 3/3] refactor: remove DependencyType.SOFT (#82) BREAKING-CHANGE: DependencyType.SOFT has now been removed after it was deprecated. There is no direct replacement for this. Please look into Patch Options instead, which supersedes this. --- src/main/kotlin/app/revanced/patcher/Patcher.kt | 6 ------ .../revanced/patcher/patch/annotations/PatchAnnotation.kt | 8 +------- .../patcher/usage/bytecode/ExampleBytecodePatch.kt | 2 +- 3 files changed, 2 insertions(+), 14 deletions(-) diff --git a/src/main/kotlin/app/revanced/patcher/Patcher.kt b/src/main/kotlin/app/revanced/patcher/Patcher.kt index c03db12..eef390f 100644 --- a/src/main/kotlin/app/revanced/patcher/Patcher.kt +++ b/src/main/kotlin/app/revanced/patcher/Patcher.kt @@ -11,7 +11,6 @@ import app.revanced.patcher.patch.Patch import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResultError import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.annotations.DependencyType import app.revanced.patcher.patch.impl.BytecodePatch import app.revanced.patcher.patch.impl.ResourcePatch import app.revanced.patcher.util.ListBackedSet @@ -265,11 +264,6 @@ class Patcher(private val options: PatcherOptions) { // recursively apply all dependency patches patch.dependencies.forEach { val dependency = it.patch.java - if ( // soft dependencies must be included manually. - it.type == DependencyType.SOFT && !data.patches.any { p -> - p.patchName == dependency.patchName - } - ) return@forEach val result = applyPatch(dependency, appliedPatches) if (result.isSuccess()) return@forEach diff --git a/src/main/kotlin/app/revanced/patcher/patch/annotations/PatchAnnotation.kt b/src/main/kotlin/app/revanced/patcher/patch/annotations/PatchAnnotation.kt index 55d8aa4..409b34b 100644 --- a/src/main/kotlin/app/revanced/patcher/patch/annotations/PatchAnnotation.kt +++ b/src/main/kotlin/app/revanced/patcher/patch/annotations/PatchAnnotation.kt @@ -43,11 +43,5 @@ enum class DependencyType { /** * Enforces that the dependency is applied, even if it was not selected. */ - HARD, - - /** - * Applies the dependency only if it was selected. - */ - @Deprecated("Will be removed when Patch Options is implemented.") - SOFT + HARD } \ No newline at end of file diff --git a/src/test/kotlin/app/revanced/patcher/usage/bytecode/ExampleBytecodePatch.kt b/src/test/kotlin/app/revanced/patcher/usage/bytecode/ExampleBytecodePatch.kt index c4d91fe..0a21d5e 100644 --- a/src/test/kotlin/app/revanced/patcher/usage/bytecode/ExampleBytecodePatch.kt +++ b/src/test/kotlin/app/revanced/patcher/usage/bytecode/ExampleBytecodePatch.kt @@ -38,7 +38,7 @@ import org.jf.dexlib2.util.Preconditions @Description("Example demonstration of a bytecode patch.") @ExampleResourceCompatibility @Version("0.0.1") -@DependsOn(ExampleBytecodePatch::class, DependencyType.SOFT) +@DependsOn(ExampleBytecodePatch::class, DependencyType.HARD) class ExampleBytecodePatch : BytecodePatch(listOf(ExampleFingerprint)) { // This function will be executed by the patcher. // You can treat it as a constructor