feat: Allow getting most common compatible versions for all packages

This commit is contained in:
oSumAtrIX
2023-11-27 21:03:23 +01:00
parent 34171b534b
commit 96845ba265
2 changed files with 59 additions and 50 deletions

View File

@@ -1,14 +1,14 @@
package app.revanced.library package app.revanced.library
import app.revanced.patcher.PatchSet import app.revanced.patcher.PatchSet
import java.util.* import app.revanced.patcher.patch.Patch
private typealias PackageName = String typealias PackageName = String
private typealias Version = String typealias Version = String
private typealias Count = Int typealias Count = Int
private typealias VersionMap = SortedMap<Version, Count> typealias VersionMap = LinkedHashMap<Version, Count>
internal typealias PackageNameMap = Map<PackageName, VersionMap> typealias PackageNameMap = Map<PackageName, VersionMap>
/** /**
* Utility functions for working with patches. * Utility functions for working with patches.
@@ -26,7 +26,7 @@ object PatchUtils {
"Use getMostCommonCompatibleVersions instead.", "Use getMostCommonCompatibleVersions instead.",
ReplaceWith( ReplaceWith(
"getMostCommonCompatibleVersions(patches, setOf(packageName))" + "getMostCommonCompatibleVersions(patches, setOf(packageName))" +
".entries.firstOrNull()?.value?.keys?.firstOrNull()", ".entries.firstOrNull()?.value?.keys?.firstOrNull()",
), ),
) )
fun getMostCommonCompatibleVersion( fun getMostCommonCompatibleVersion(
@@ -48,30 +48,32 @@ object PatchUtils {
* Get the count of versions for each compatible package from a supplied set of [patches] ordered by the most common version. * 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 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. * @param countUnusedPatches Whether to count patches that are not used.
* @return A map of package names to a map of versions to their count. * @return A map of package names to a map of versions to their count.
*/ */
fun getMostCommonCompatibleVersions( fun getMostCommonCompatibleVersions(
patches: PatchSet, patches: PatchSet,
packageNames: Set<String>, packageNames: Set<String>? = null,
countUnusedPatches: Boolean = false, countUnusedPatches: Boolean = false,
): PackageNameMap { ): PackageNameMap = buildMap {
val wantedPackages = packageNames.toHashSet() fun filterWantedPackages(compatiblePackages: Iterable<Patch.CompatiblePackage>): Iterable<Patch.CompatiblePackage> {
return buildMap { val wantedPackages = packageNames?.toHashSet() ?: return compatiblePackages
patches return compatiblePackages.filter { it.name in wantedPackages }
.filter { it.use || countUnusedPatches } }
.flatMap { it.compatiblePackages ?: emptyList() }
.filter { it.name in wantedPackages }
.forEach { compatiblePackage ->
compatiblePackage.versions?.let { versions ->
val versionMap = getOrPut(compatiblePackage.name) { sortedMapOf() }
versions.forEach { version -> patches
versionMap[version] = versionMap.getOrDefault(version, 0) + 1 .filter { it.use || countUnusedPatches }
} .flatMap { it.compatiblePackages ?: emptyList() }
.let(::filterWantedPackages)
.forEach { compatiblePackage ->
val versionMap = getOrPut(compatiblePackage.name) { linkedMapOf() }
compatiblePackage.versions?.let { versions ->
versions.forEach { version ->
versionMap[version] = versionMap.getOrDefault(version, 0) + 1
} }
} }
} }
} }
} }

View File

@@ -25,43 +25,50 @@ internal object PatchUtilsTest {
@Test @Test
fun `return common versions correctly ordered for each package`() { fun `return common versions correctly ordered for each package`() {
assertEqualsVersions( fun assertEqualsExpected(compatiblePackageNames: Set<String>?) = assertEqualsVersions(
expected = expected =
mapOf( mapOf(
"some.package" to sortedMapOf("a" to 3, "b" to 2, "c" to 1), "some.package" to linkedMapOf("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.package" to linkedMapOf("b" to 3, "c" to 2, "d" to 1),
"some.other.other.package" to sortedMapOf("a" to 1, "b" to 1), "some.other.other.package" to linkedMapOf("a" to 1, "b" to 1),
"some.other.other.other.package" to sortedMapOf(), "some.other.other.other.package" to linkedMapOf(),
), ),
patches, patches,
compatiblePackageNames = compatiblePackageNames,
setOf(
"some.package",
"some.other.package",
"some.other.other.package",
"some.other.other.other.package",
),
countUnusedPatches = true, countUnusedPatches = true,
) )
assertEqualsExpected(
compatiblePackageNames = setOf(
"some.package",
"some.other.package",
"some.other.other.package",
"some.other.other.other.package",
),
)
assertEqualsExpected(
compatiblePackageNames = null
)
} }
@Test @Test
fun `return common versions correctly ordered for each package without counting unused patches`() { fun `return common versions correctly ordered for each package without counting unused patches`() {
assertEqualsVersions( assertEqualsVersions(
expected = expected =
mapOf( mapOf(
"some.package" to sortedMapOf("a" to 1), "some.package" to linkedMapOf("a" to 1),
"some.other.package" to sortedMapOf("b" to 2, "c" to 2, "d" to 1), "some.other.package" to linkedMapOf("b" to 2, "c" to 2, "d" to 1),
"some.other.other.package" to sortedMapOf("a" to 1, "b" to 1), "some.other.other.package" to linkedMapOf("a" to 1, "b" to 1),
), ),
patches, patches,
compatiblePackageNames = compatiblePackageNames =
setOf( setOf(
"some.package", "some.package",
"some.other.package", "some.other.package",
"some.other.other.package", "some.other.other.package",
"some.other.other.other.package", "some.other.other.other.package",
), ),
countUnusedPatches = false, countUnusedPatches = false,
) )
} }
@@ -78,7 +85,7 @@ internal object PatchUtilsTest {
@Test @Test
fun `return empty set of versions because no compatible package is constrained to a version`() { fun `return empty set of versions because no compatible package is constrained to a version`() {
assertEqualsVersions( assertEqualsVersions(
expected = mapOf("some.package" to sortedMapOf()), expected = mapOf("some.package" to linkedMapOf()),
patches = setOf(newPatch("some.package")), patches = setOf(newPatch("some.package")),
compatiblePackageNames = setOf("some.package"), compatiblePackageNames = setOf("some.package"),
countUnusedPatches = true, countUnusedPatches = true,
@@ -121,7 +128,7 @@ internal object PatchUtilsTest {
private fun assertEqualsVersions( private fun assertEqualsVersions(
expected: PackageNameMap, expected: PackageNameMap,
patches: PatchSet, patches: PatchSet,
compatiblePackageNames: Set<String>, compatiblePackageNames: Set<String>?,
countUnusedPatches: Boolean = false, countUnusedPatches: Boolean = false,
) = assertEquals( ) = assertEquals(
expected, expected,