diff --git a/build.gradle.kts b/build.gradle.kts index 6444909a..d81f86b5 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -37,6 +37,9 @@ tasks { events("PASSED", "SKIPPED", "FAILED") } } + processResources { + expand("projectVersion" to project.version) + } } java { diff --git a/src/main/kotlin/app/revanced/patcher/Patcher.kt b/src/main/kotlin/app/revanced/patcher/Patcher.kt index 00623e96..d3eb328f 100644 --- a/src/main/kotlin/app/revanced/patcher/Patcher.kt +++ b/src/main/kotlin/app/revanced/patcher/Patcher.kt @@ -6,6 +6,7 @@ import app.revanced.patcher.data.impl.findIndexed import app.revanced.patcher.extensions.PatchExtensions.dependencies import app.revanced.patcher.extensions.PatchExtensions.deprecated import app.revanced.patcher.extensions.PatchExtensions.patchName +import app.revanced.patcher.extensions.PatchExtensions.sincePatcherVersion import app.revanced.patcher.extensions.nullOutputStream import app.revanced.patcher.fingerprint.method.utils.MethodFingerprintUtils.resolve import app.revanced.patcher.patch.Patch @@ -15,6 +16,7 @@ import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patcher.patch.impl.BytecodePatch import app.revanced.patcher.patch.impl.ResourcePatch import app.revanced.patcher.util.ListBackedSet +import app.revanced.patcher.util.VersionReader import brut.androlib.Androlib import brut.androlib.meta.UsesFramework import brut.androlib.options.BuildOptions @@ -36,7 +38,8 @@ import java.io.Closeable import java.io.File import java.nio.file.Files -val NAMER = BasicDexFileNamer() +private val NAMER = BasicDexFileNamer() +private val VERSION = VersionReader.read() /** * The ReVanced Patcher. @@ -244,6 +247,15 @@ class Patcher(private val options: PatcherOptions) { * @param patches [Patch]es The patches to add. */ fun addPatches(patches: Iterable>>) { + for (patch in patches) { + val needsVersion = patch.sincePatcherVersion + if (needsVersion != null && needsVersion > VERSION) { + logger.error("Patch '${patch.patchName}' requires Patcher version $needsVersion or higher") + logger.error("Current Patcher version is $VERSION") + logger.warn("Skipping '${patch.patchName}'!") + continue // TODO: continue or halt/throw? + } + } data.patches.addAll(patches) } diff --git a/src/main/kotlin/app/revanced/patcher/annotation/SincePatcher.kt b/src/main/kotlin/app/revanced/patcher/annotation/SincePatcher.kt new file mode 100644 index 00000000..880096d2 --- /dev/null +++ b/src/main/kotlin/app/revanced/patcher/annotation/SincePatcher.kt @@ -0,0 +1,13 @@ +package app.revanced.patcher.annotation + +import app.revanced.patcher.patch.Patch +import app.revanced.patcher.Patcher + +/** + * Declares a [Patch] deprecated for removal. + * @param version The minimum version of the [Patcher] this [Patch] supports. + */ +@Target(AnnotationTarget.CLASS) +@Retention(AnnotationRetention.RUNTIME) +@MustBeDocumented +annotation class SincePatcher(val version: String) diff --git a/src/main/kotlin/app/revanced/patcher/extensions/AnnotationExtensions.kt b/src/main/kotlin/app/revanced/patcher/extensions/AnnotationExtensions.kt index 6c26d84c..91d44c79 100644 --- a/src/main/kotlin/app/revanced/patcher/extensions/AnnotationExtensions.kt +++ b/src/main/kotlin/app/revanced/patcher/extensions/AnnotationExtensions.kt @@ -58,6 +58,7 @@ object PatchExtensions { if (cl == Patch::class) null else cl } } + val Class>.sincePatcherVersion get() = recursiveAnnotation(SincePatcher::class)?.version @JvmStatic fun Class>.dependsOn(patch: Class>): Boolean { diff --git a/src/main/kotlin/app/revanced/patcher/util/VersionReader.kt b/src/main/kotlin/app/revanced/patcher/util/VersionReader.kt new file mode 100644 index 00000000..6fc15a55 --- /dev/null +++ b/src/main/kotlin/app/revanced/patcher/util/VersionReader.kt @@ -0,0 +1,18 @@ +package app.revanced.patcher.util + +import java.util.* + +internal object VersionReader { + @JvmStatic + private val props = Properties().apply { + load( + VersionReader::class.java.getResourceAsStream("/revanced-patcher/version.properties") + ?: throw IllegalStateException("Could not load version.properties") + ) + } + + @JvmStatic + fun read(): String { + return props.getProperty("version") ?: throw IllegalStateException("Version not found") + } +} \ No newline at end of file diff --git a/src/main/resources/revanced-patcher/version.properties b/src/main/resources/revanced-patcher/version.properties new file mode 100644 index 00000000..308c9f8e --- /dev/null +++ b/src/main/resources/revanced-patcher/version.properties @@ -0,0 +1 @@ +version=${projectVersion} \ No newline at end of file diff --git a/src/test/kotlin/app/revanced/patcher/util/VersionReaderTest.kt b/src/test/kotlin/app/revanced/patcher/util/VersionReaderTest.kt new file mode 100644 index 00000000..2ad670cc --- /dev/null +++ b/src/test/kotlin/app/revanced/patcher/util/VersionReaderTest.kt @@ -0,0 +1,20 @@ +package app.revanced.patcher.util + +import org.junit.jupiter.api.Test + +import org.junit.jupiter.api.Assertions.* + +internal class VersionReaderTest { + @Test + fun read() { + val version = VersionReader.read() + assertNotNull(version) + assertTrue(version.isNotEmpty()) + val parts = version.split(".") + assertEquals(3, parts.size) + parts.forEach { + assertTrue(it.toInt() >= 0) + } + println(version) + } +} \ No newline at end of file