mirror of
https://github.com/ReVanced/revanced-library.git
synced 2026-01-12 14:26:17 +00:00
Compare commits
6 Commits
v1.4.0-dev
...
v1.4.0-dev
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cdf94ffeca | ||
|
|
37434cf4a4 | ||
|
|
73c97abedd | ||
|
|
762b7e3bc0 | ||
|
|
e4be6dbccd | ||
|
|
96845ba265 |
13
CHANGELOG.md
13
CHANGELOG.md
@@ -1,3 +1,16 @@
|
||||
# [1.4.0-dev.2](https://github.com/ReVanced/revanced-library/compare/v1.4.0-dev.1...v1.4.0-dev.2) (2023-11-27)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Differentiate no package compatibility to any version compatibility ([762b7e3](https://github.com/ReVanced/revanced-library/commit/762b7e3bc01e2ca33dfcdbb1b5028d60ef6e0a48))
|
||||
* Sort the version maps by the most common version ([e4be6db](https://github.com/ReVanced/revanced-library/commit/e4be6dbccd86700ffafe7cd8395e845bbd3d5138))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* Allow getting most common compatible versions for all packages ([96845ba](https://github.com/ReVanced/revanced-library/commit/96845ba265e6dc208c7ac96f5e58734209cd1720))
|
||||
|
||||
# [1.4.0-dev.1](https://github.com/ReVanced/revanced-library/compare/v1.3.0...v1.4.0-dev.1) (2023-11-27)
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
org.gradle.parallel = true
|
||||
org.gradle.caching = true
|
||||
kotlin.code.style = official
|
||||
version = 1.4.0-dev.1
|
||||
version = 1.4.0-dev.2
|
||||
|
||||
@@ -4,7 +4,7 @@ bcpkix-jdk18on = "1.76"
|
||||
jackson-module-kotlin = "2.14.3"
|
||||
jadb = "1.2.1"
|
||||
kotlin-reflect = "1.9.10"
|
||||
kotlin-test = "1.9.10"
|
||||
kotlin-test = "1.9.20"
|
||||
revanced-patcher = "19.0.0"
|
||||
binary-compatibility-validator = "0.13.2"
|
||||
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
package app.revanced.library
|
||||
|
||||
import app.revanced.patcher.PatchSet
|
||||
import java.util.*
|
||||
import app.revanced.patcher.patch.Patch
|
||||
|
||||
private typealias PackageName = String
|
||||
private typealias Version = String
|
||||
private typealias Count = Int
|
||||
typealias PackageName = String
|
||||
typealias Version = String
|
||||
typealias Count = Int
|
||||
|
||||
private typealias VersionMap = SortedMap<Version, Count>
|
||||
internal typealias PackageNameMap = Map<PackageName, VersionMap>
|
||||
typealias VersionMap = LinkedHashMap<Version, Count>
|
||||
typealias PackageNameMap = Map<PackageName, VersionMap>
|
||||
|
||||
/**
|
||||
* Utility functions for working with patches.
|
||||
@@ -48,30 +48,46 @@ object PatchUtils {
|
||||
* Get the count of versions for each compatible package from a supplied set of [patches] ordered by the most common version.
|
||||
*
|
||||
* @param patches The set of patches to check.
|
||||
* @param packageNames The names of the compatible packages.
|
||||
* @param packageNames The names of the compatible packages to include. If null, all packages will be included.
|
||||
* @param countUnusedPatches Whether to count patches that are not used.
|
||||
* @return A map of package names to a map of versions to their count.
|
||||
*/
|
||||
fun getMostCommonCompatibleVersions(
|
||||
patches: PatchSet,
|
||||
packageNames: Set<String>,
|
||||
packageNames: Set<String>? = null,
|
||||
countUnusedPatches: Boolean = false,
|
||||
): PackageNameMap {
|
||||
val wantedPackages = packageNames.toHashSet()
|
||||
return buildMap {
|
||||
): PackageNameMap =
|
||||
buildMap {
|
||||
fun filterWantedPackages(compatiblePackages: Iterable<Patch.CompatiblePackage>): Iterable<Patch.CompatiblePackage> {
|
||||
val wantedPackages = packageNames?.toHashSet() ?: return compatiblePackages
|
||||
return compatiblePackages.filter { it.name in wantedPackages }
|
||||
}
|
||||
|
||||
patches
|
||||
.filter { it.use || countUnusedPatches }
|
||||
.flatMap { it.compatiblePackages ?: emptyList() }
|
||||
.filter { it.name in wantedPackages }
|
||||
.let(::filterWantedPackages)
|
||||
.forEach { compatiblePackage ->
|
||||
compatiblePackage.versions?.let { versions ->
|
||||
val versionMap = getOrPut(compatiblePackage.name) { sortedMapOf() }
|
||||
if (compatiblePackage.versions?.isEmpty() == true) {
|
||||
return@forEach
|
||||
}
|
||||
|
||||
val versionMap = getOrPut(compatiblePackage.name) { linkedMapOf() }
|
||||
|
||||
compatiblePackage.versions?.let { versions ->
|
||||
versions.forEach { version ->
|
||||
versionMap[version] = versionMap.getOrDefault(version, 0) + 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Sort the version maps by the most common version.
|
||||
forEach { (packageName, versionMap) ->
|
||||
this[packageName] =
|
||||
versionMap
|
||||
.asIterable()
|
||||
.sortedWith(compareByDescending { it.value })
|
||||
.associate { it.key to it.value } as VersionMap
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,30 +10,64 @@ import kotlin.test.assertEquals
|
||||
internal object PatchUtilsTest {
|
||||
private val patches =
|
||||
arrayOf(
|
||||
newPatch("some.package", "a"),
|
||||
newPatch("some.package", "a", "b", use = false),
|
||||
newPatch("some.package", "a", "b", "c", use = false),
|
||||
newPatch("some.other.package", "b", use = false),
|
||||
newPatch("some.other.package", "b", "c"),
|
||||
newPatch("some.other.package", "b", "c", "d"),
|
||||
newPatch("some.package", setOf("a")),
|
||||
newPatch("some.package", setOf("a", "b"), use = false),
|
||||
newPatch("some.package", setOf("a", "b", "c"), use = false),
|
||||
newPatch("some.other.package", setOf("b"), use = false),
|
||||
newPatch("some.other.package", setOf("b", "c")),
|
||||
newPatch("some.other.package", setOf("b", "c", "d")),
|
||||
newPatch("some.other.other.package"),
|
||||
newPatch("some.other.other.package", "a"),
|
||||
newPatch("some.other.other.package", "b"),
|
||||
newPatch("some.other.other.package", setOf("a")),
|
||||
newPatch("some.other.other.package", setOf("b")),
|
||||
newPatch("some.other.other.other.package", use = false),
|
||||
newPatch("some.other.other.other.package", use = false),
|
||||
).toSet()
|
||||
|
||||
@Test
|
||||
fun `return common versions correctly ordered for each package`() {
|
||||
fun `empty because package is incompatible with any version`() {
|
||||
assertEqualsVersions(
|
||||
expected =
|
||||
mapOf(
|
||||
"some.package" to sortedMapOf("a" to 3, "b" to 2, "c" to 1),
|
||||
"some.other.package" to sortedMapOf("b" to 3, "c" to 2, "d" to 1),
|
||||
"some.other.other.package" to sortedMapOf("a" to 1, "b" to 1),
|
||||
"some.other.other.other.package" to sortedMapOf(),
|
||||
),
|
||||
expected = emptyMap(),
|
||||
patches = setOf(newPatch("some.package", emptySet(), use = true)),
|
||||
compatiblePackageNames = setOf("some.package"),
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `empty list of versions because package is unconstrained to any version`() {
|
||||
assertEqualsVersions(
|
||||
expected = mapOf("some.package" to linkedMapOf()),
|
||||
patches = setOf(newPatch("some.package")),
|
||||
compatiblePackageNames = setOf("some.package"),
|
||||
countUnusedPatches = true,
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `empty because no known package was supplied`() {
|
||||
assertEqualsVersions(
|
||||
expected = emptyMap(),
|
||||
patches,
|
||||
compatiblePackageNames = setOf("unknown.package"),
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `common versions correctly ordered for each package`() {
|
||||
fun assertEqualsExpected(compatiblePackageNames: Set<String>?) =
|
||||
assertEqualsVersions(
|
||||
expected =
|
||||
mapOf(
|
||||
"some.package" to linkedMapOf("a" to 3, "b" to 2, "c" to 1),
|
||||
"some.other.package" to linkedMapOf("b" to 3, "c" to 2, "d" to 1),
|
||||
"some.other.other.package" to linkedMapOf("a" to 1, "b" to 1),
|
||||
"some.other.other.other.package" to linkedMapOf(),
|
||||
),
|
||||
patches,
|
||||
compatiblePackageNames,
|
||||
countUnusedPatches = true,
|
||||
)
|
||||
|
||||
assertEqualsExpected(
|
||||
compatiblePackageNames =
|
||||
setOf(
|
||||
"some.package",
|
||||
@@ -41,18 +75,21 @@ internal object PatchUtilsTest {
|
||||
"some.other.other.package",
|
||||
"some.other.other.other.package",
|
||||
),
|
||||
countUnusedPatches = true,
|
||||
)
|
||||
|
||||
assertEqualsExpected(
|
||||
compatiblePackageNames = null,
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `return common versions correctly ordered for each package without counting unused patches`() {
|
||||
fun `common versions correctly ordered for each package without counting unused patches`() {
|
||||
assertEqualsVersions(
|
||||
expected =
|
||||
mapOf(
|
||||
"some.package" to sortedMapOf("a" to 1),
|
||||
"some.other.package" to sortedMapOf("b" to 2, "c" to 2, "d" to 1),
|
||||
"some.other.other.package" to sortedMapOf("a" to 1, "b" to 1),
|
||||
"some.package" to linkedMapOf("a" to 1),
|
||||
"some.other.package" to linkedMapOf("b" to 2, "c" to 2, "d" to 1),
|
||||
"some.other.other.package" to linkedMapOf("a" to 1, "b" to 1),
|
||||
),
|
||||
patches,
|
||||
compatiblePackageNames =
|
||||
@@ -66,30 +103,11 @@ internal object PatchUtilsTest {
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `return an empty map because no known package was supplied`() {
|
||||
assertEqualsVersions(
|
||||
expected = emptyMap(),
|
||||
patches,
|
||||
compatiblePackageNames = setOf("unknown.package"),
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `return empty set of versions because no compatible package is constrained to a version`() {
|
||||
assertEqualsVersions(
|
||||
expected = mapOf("some.package" to sortedMapOf()),
|
||||
patches = setOf(newPatch("some.package")),
|
||||
compatiblePackageNames = setOf("some.package"),
|
||||
countUnusedPatches = true,
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `return 'a' because it is the most common version`() {
|
||||
val patches =
|
||||
arrayOf("a", "a", "c", "d", "a", "b", "c", "d", "a", "b", "c", "d")
|
||||
.map { version -> newPatch("some.package", version) }
|
||||
.map { version -> newPatch("some.package", setOf(version)) }
|
||||
.toSet()
|
||||
|
||||
assertEqualsVersion("a", patches, "some.package")
|
||||
@@ -102,7 +120,7 @@ internal object PatchUtilsTest {
|
||||
|
||||
@Test
|
||||
fun `return null because no patch is compatible with the supplied package name`() {
|
||||
val patches = setOf(newPatch("some.package", "a"))
|
||||
val patches = setOf(newPatch("some.package", setOf("a")))
|
||||
|
||||
assertEqualsVersion(null, patches, "other.package")
|
||||
}
|
||||
@@ -121,7 +139,7 @@ internal object PatchUtilsTest {
|
||||
private fun assertEqualsVersions(
|
||||
expected: PackageNameMap,
|
||||
patches: PatchSet,
|
||||
compatiblePackageNames: Set<String>,
|
||||
compatiblePackageNames: Set<String>?,
|
||||
countUnusedPatches: Boolean = false,
|
||||
) = assertEquals(
|
||||
expected,
|
||||
@@ -135,6 +153,7 @@ internal object PatchUtilsTest {
|
||||
) {
|
||||
// Test both the deprecated and the new method.
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
assertEquals(
|
||||
expected,
|
||||
PatchUtils.getMostCommonCompatibleVersion(patches, compatiblePackageName),
|
||||
@@ -149,7 +168,7 @@ internal object PatchUtilsTest {
|
||||
|
||||
private fun newPatch(
|
||||
packageName: String,
|
||||
vararg versions: String,
|
||||
versions: Set<String>? = null,
|
||||
use: Boolean = true,
|
||||
) = object : BytecodePatch() {
|
||||
init {
|
||||
@@ -158,7 +177,7 @@ internal object PatchUtilsTest {
|
||||
val compatiblePackagesField = Patch::class.java.getDeclaredField("compatiblePackages")
|
||||
|
||||
compatiblePackagesField.isAccessible = true
|
||||
compatiblePackagesField.set(this, setOf(CompatiblePackage(packageName, versions.toSet())))
|
||||
compatiblePackagesField.set(this, setOf(CompatiblePackage(packageName, versions?.toSet())))
|
||||
|
||||
val useField = Patch::class.java.getDeclaredField("use")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user