Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: prefer the loader by order in lock file #36

Merged
merged 4 commits into from
Oct 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ kotlin {
val commonTest by getting {
dependencies {
implementation(kotlin("test"))
implementation("io.mockk:mockk:1.13.12")
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ object CurseForge : Platform(

// -- FILES --

private const val LOADER_VERSION_TYPE_ID = 68441
internal const val LOADER_VERSION_TYPE_ID = 68441

private fun List<CfModModel.File>.filterFileModels(
mcVersions: List<String>, loaders: List<String>
Expand All @@ -124,10 +124,19 @@ object CurseForge : Platform(
.filter { it.gameVersionTypeId == LOADER_VERSION_TYPE_ID } // Filter to loader only
.takeIf { it.isNotEmpty() }
?.map { it.gameVersionName.lowercase() }?.any {
loaders.any { loader -> loader == it } || it in validLoaders // Check default valid loaders
it in loaders || it in validLoaders // Check default valid loaders
} ?: true // If no loaders found, accept model
}
SettingDust marked this conversation as resolved.
Show resolved Hide resolved

internal fun List<CfModModel.File>.sortByLoaders(loaders: List<String>) = this.sortedWith { fileA, fileB ->
val aLoaders = fileA.sortableGameVersions.filter { it.gameVersionTypeId == LOADER_VERSION_TYPE_ID }
.map { it.gameVersionName.lowercase() }
val bLoaders = fileB.sortableGameVersions.filter { it.gameVersionTypeId == LOADER_VERSION_TYPE_ID }
.map { it.gameVersionName.lowercase() }
loaders.indexOfFirst { it in aLoaders }.let { if (it == -1) loaders.size else it }
.minus(loaders.indexOfFirst { it in bLoaders }.let { if (it == -1) loaders.size else it })
}

private fun CfModModel.File.toProjectFile(gameVersionTypeIds: List<Int>): ProjectFile
{
return ProjectFile(
Expand Down Expand Up @@ -192,6 +201,7 @@ object CurseForge : Platform(
this.requestProjectBody(requestUrl) ?: return mutableSetOf()
).data
.filterFileModels(mcVersions, loaders)
.sortByLoaders(loaders)
.map { it.toProjectFile(gameVersionTypeIds) }
.debugIfEmpty {
println("${this::class.simpleName}#requestProjectFiles: file is null")
Expand Down Expand Up @@ -223,6 +233,7 @@ object CurseForge : Platform(
).data
.filterFileModels(mcVersions, loaders)
.sortedByDescending { it.fileDate }
.sortByLoaders(loaders)
.map { it.toProjectFile(gameVersionTypeIds) }
.debugIfEmpty {
println("${this::class.simpleName}#requestMultipleProjectFiles: file is null")
Expand Down
12 changes: 10 additions & 2 deletions src/commonMain/kotlin/teksturepako/pakku/api/platforms/Modrinth.kt
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import teksturepako.pakku.api.models.mr.GetVersionsFromHashesRequest
import teksturepako.pakku.api.models.mr.MrProjectModel
import teksturepako.pakku.api.models.mr.MrVersionModel
import teksturepako.pakku.api.projects.*
import teksturepako.pakku.debug
import teksturepako.pakku.debugIfEmpty
import kotlin.system.exitProcess
import kotlin.time.Duration.Companion.seconds
Expand Down Expand Up @@ -139,10 +140,15 @@ object Modrinth : Platform(
version.gameVersions.any { it in mcVersions } && version.loaders
.takeIf { it.isNotEmpty() }
?.map { it.lowercase() }?.any {
loaders.any { loader -> loader == it } || it in validLoaders // Check default valid loaders
it in loaders || it in validLoaders // Check default valid loaders
} ?: true // If no loaders found, accept model
}

internal fun List<MrVersionModel>.sortByLoaders(loaders: List<String>) = this.sortedWith { aVersion, bVersion ->
loaders.indexOfFirst { it in aVersion.loaders }.let { if (it == -1) loaders.size else it }
.minus(loaders.indexOfFirst { it in bVersion.loaders }.let { if (it == -1) loaders.size else it })
}

private fun MrVersionModel.toProjectFiles(): List<ProjectFile>
{
return this.files.sortedBy { it.primary }.map { versionFile ->
Expand Down Expand Up @@ -182,6 +188,7 @@ object Modrinth : Platform(
this.requestProjectBody("project/$projectId/version") ?: return mutableSetOf()
)
.filterFileModels(mcVersions, loaders)
.sortByLoaders(loaders)
.flatMap { version -> version.toProjectFiles() }
.debugIfEmpty {
println("${this::class.simpleName}#requestProjectFiles: file is null")
Expand Down Expand Up @@ -213,8 +220,9 @@ object Modrinth : Platform(
}
.awaitAll()
.flatten()
.sortedByDescending { it.datePublished }
.filterFileModels(mcVersions, loaders)
.sortedByDescending { it.datePublished }
.sortByLoaders(loaders)
.flatMap { version -> version.toProjectFiles() }
.toMutableSet()
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,129 @@
package teksturepako.pakku.api.platforms

import io.mockk.every
import io.mockk.mockk
import teksturepako.pakku.api.models.cf.CfModModel
import teksturepako.pakku.api.platforms.CurseForge.LOADER_VERSION_TYPE_ID
import teksturepako.pakku.api.platforms.CurseForge.sortByLoaders
import kotlin.test.Test
import kotlin.test.assertContentEquals
import kotlin.test.assertEquals

class CurseForgeTest
{
@Test
fun requestProject()
{
}

@Test
fun sortByLoaders_WithValidLoaders_ShouldSortCorrectly() {
val files = listOf(
mockk<CfModModel.File> {
every { sortableGameVersions } returns listOf(
mockk<CfModModel.File.SortableGameVersion> {
every { gameVersionTypeId } returns LOADER_VERSION_TYPE_ID
every { gameVersionName } returns "loaderB"
},
mockk<CfModModel.File.SortableGameVersion> {
every { gameVersionTypeId } returns LOADER_VERSION_TYPE_ID
every { gameVersionName } returns "loaderC"
}
)
},
mockk<CfModModel.File> {
every { sortableGameVersions } returns listOf(
mockk<CfModModel.File.SortableGameVersion> {
every { gameVersionTypeId } returns LOADER_VERSION_TYPE_ID
every { gameVersionName } returns "loaderA"
},
mockk<CfModModel.File.SortableGameVersion> {
every { gameVersionTypeId } returns LOADER_VERSION_TYPE_ID
every { gameVersionName } returns "loaderB"
}
)
},
mockk<CfModModel.File> {
every { sortableGameVersions } returns listOf(
mockk<CfModModel.File.SortableGameVersion> {
every { gameVersionTypeId } returns LOADER_VERSION_TYPE_ID
every { gameVersionName } returns "loaderB"
},
mockk<CfModModel.File.SortableGameVersion> {
every { gameVersionTypeId } returns LOADER_VERSION_TYPE_ID
every { gameVersionName } returns "loaderB"
}
)
},
mockk<CfModModel.File> {
every { sortableGameVersions } returns listOf(
mockk<CfModModel.File.SortableGameVersion> {
every { gameVersionTypeId } returns LOADER_VERSION_TYPE_ID
every { gameVersionName } returns "loaderA"
},
mockk<CfModModel.File.SortableGameVersion> {
every { gameVersionTypeId } returns LOADER_VERSION_TYPE_ID
every { gameVersionName } returns "loaderC"
}
)
}
)

val loaders = listOf("loadera", "loaderb", "loaderc")
val sortedFiles = files.toList().sortByLoaders(loaders)

assertContentEquals(listOf(files[1], files[3], files[0], files[2]), sortedFiles)
}

@Test
fun sortByLoaders_WithNoMatchingLoaders_ShouldNotChangeOrder() {
val files = listOf(
mockk<CfModModel.File> {
every { sortableGameVersions } returns listOf(
mockk<CfModModel.File.SortableGameVersion> {
every { gameVersionTypeId } returns LOADER_VERSION_TYPE_ID
every { gameVersionName } returns "loaderB"
}
)
},
mockk<CfModModel.File> {
every { sortableGameVersions } returns listOf(
mockk<CfModModel.File.SortableGameVersion> {
every { gameVersionTypeId } returns LOADER_VERSION_TYPE_ID
every { gameVersionName } returns "loaderA"
}
)
}
)

val loaders = listOf("loader1", "loader2")
val sortedFiles = files.toList().sortByLoaders(loaders)
assertContentEquals(files, sortedFiles)
}

@Test
fun sortByLoaders_WithSomeMatchingLoaders_ShouldSortCorrectly() {
val files = listOf(
mockk<CfModModel.File> {
every { sortableGameVersions } returns listOf(
mockk<CfModModel.File.SortableGameVersion> {
every { gameVersionTypeId } returns LOADER_VERSION_TYPE_ID
every { gameVersionName } returns "loaderA"
}
)
},
mockk<CfModModel.File> {
every { sortableGameVersions } returns listOf(
mockk<CfModModel.File.SortableGameVersion> {
every { gameVersionTypeId } returns LOADER_VERSION_TYPE_ID
every { gameVersionName } returns "loader1"
}
)
}
)

val loaders = listOf("loader1", "loader2")
val sortedFiles = files.toList().sortByLoaders(loaders)
assertEquals(files[0], sortedFiles[1])
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package teksturepako.pakku.api.platforms

import io.mockk.every
import io.mockk.mockk
import teksturepako.pakku.api.models.mr.MrVersionModel
import teksturepako.pakku.api.platforms.Modrinth.sortByLoaders
import kotlin.test.Test
import kotlin.test.assertContentEquals
import kotlin.test.assertEquals

class ModrinthTest
{
@Test
fun sortByLoaders_WithValidLoaders_ShouldSortCorrectly() {
val versions = listOf(
mockk<MrVersionModel> {
every { loaders } returns listOf("loaderb", "loaderc")
},
mockk<MrVersionModel> {
every { loaders } returns listOf("loadera", "loaderb")
},
mockk<MrVersionModel> {
every { loaders } returns listOf("loaderb", "loaderb")
},
mockk<MrVersionModel> {
every { loaders } returns listOf("loadera", "loaderc")
}
)

val loaders = listOf("loadera", "loaderb", "loaderc")
val sortedVersions = versions.toList().sortByLoaders(loaders)

assertContentEquals(listOf(versions[1], versions[3], versions[0], versions[2]), sortedVersions)
}

@Test
fun sortByLoaders_WithNoMatchingLoaders_ShouldNotChangeOrder() {
val versions = listOf(
mockk<MrVersionModel> {
every { loaders } returns listOf("loaderB")
},
mockk<MrVersionModel> {
every { loaders } returns listOf("loaderA")
}
)

val loaders = listOf("loader1", "loader2")
val sortedVersions = versions.toList().sortByLoaders(loaders)

assertContentEquals(versions, sortedVersions)
}

@Test
fun sortByLoaders_WithSomeMatchingLoaders_ShouldSortCorrectly() {
val versions = listOf(
mockk<MrVersionModel> {
every { loaders } returns listOf("loadera")
},
mockk<MrVersionModel> {
every { loaders } returns listOf("loader1")
}
)

val loaders = listOf("loader1", "loader2")
val sortedVersions = versions.toList().sortByLoaders(loaders)

assertEquals(versions[0], sortedVersions[1])
}
}
Loading