Skip to content

Commit

Permalink
Merge pull request #37 from SettingDust/feature/updates-need-newer
Browse files Browse the repository at this point in the history
feat: update need newer file
  • Loading branch information
juraj-hrivnak authored Oct 8, 2024
2 parents 435d51f + 3149b7c commit 52a0824
Show file tree
Hide file tree
Showing 10 changed files with 113 additions and 31 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package teksturepako.pakku

import kotlinx.serialization.KSerializer
import kotlinx.serialization.descriptors.PrimitiveKind
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import java.time.Instant

/**
* A serializer for [Instant] that uses the ISO 8601 representation.
*
* JSON example: `"2020-12-09T09:16:56.000124Z"`
*
* @see Instant.toString
* @see Instant.parse
*/
object InstantIso8601Serializer : KSerializer<Instant>
{

override val descriptor: SerialDescriptor =
PrimitiveSerialDescriptor("java.time.Instant", PrimitiveKind.STRING)

override fun deserialize(decoder: Decoder): Instant =
Instant.parse(decoder.decodeString())

override fun serialize(encoder: Encoder, value: Instant) {
encoder.encodeString(value.toString())
}

}
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
package teksturepako.pakku.api.actions.update

import com.github.michaelbull.result.Err
import com.github.michaelbull.result.Ok
import com.github.michaelbull.result.Result
import com.github.michaelbull.result.get
import kotlinx.coroutines.async
import kotlinx.coroutines.coroutineScope
import teksturepako.pakku.api.actions.ActionError
import teksturepako.pakku.api.data.ConfigFile
import teksturepako.pakku.api.platforms.GitHub
import teksturepako.pakku.api.platforms.Multiplatform.platforms
import teksturepako.pakku.api.projects.Project
import teksturepako.pakku.api.projects.UpdateStrategy
import teksturepako.pakku.api.projects.combineWith
import teksturepako.pakku.api.projects.inheritPropertiesFrom
import java.time.Instant

/**
* Requests new data for provided [projects] from all platforms and updates them based on platform-specific slugs,
Expand All @@ -22,7 +27,7 @@ suspend fun updateMultipleProjectsWithFiles(
projects: MutableSet<Project>,
configFile: ConfigFile?,
numberOfFiles: Int
): MutableSet<Project> = coroutineScope {
): Result<MutableSet<Project>, ActionError> = coroutineScope {
val ghProjects = async {
projects.filter { project ->
GitHub.serialName in project.slug.keys
Expand All @@ -34,29 +39,39 @@ suspend fun updateMultipleProjectsWithFiles(
}
}

return@coroutineScope platforms.fold(projects.map { it.copy(files = mutableSetOf()) }.toMutableSet()) { acc, platform ->

val listOfIds = projects.mapNotNull { it.id[platform.serialName] }

platform.requestMultipleProjectsWithFiles(mcVersions, loaders, listOfIds, numberOfFiles)
.inheritPropertiesFrom(configFile)
.forEach { newProject ->
acc.find { accProject ->
accProject.slug[platform.serialName] == newProject.slug[platform.serialName]
}?.let { accProject ->
// Combine projects
(accProject + newProject).get()?.let x@ { combinedProject ->
if (combinedProject.hasNoFiles()) return@x // Do not update project if files are missing
acc -= accProject
acc += combinedProject
val combinedProjectsToOldFiles = projects.associateTo(mutableMapOf()) { it.copy(files = mutableSetOf()) to it.files }

return@coroutineScope Ok(
platforms.fold(combinedProjectsToOldFiles.keys.toMutableSet()) { acc, platform ->

val listOfIds = projects.mapNotNull { it.id[platform.serialName] }

platform.requestMultipleProjectsWithFiles(mcVersions, loaders, listOfIds, Int.MAX_VALUE)
.inheritPropertiesFrom(configFile).forEach { newProject ->
acc.find { accProject ->
accProject.slug[platform.serialName] == newProject.slug[platform.serialName]
}?.also { accProject ->
// Combine projects
val accFiles = combinedProjectsToOldFiles[accProject]
?: return@coroutineScope Err(ActionError("Failed to combine project ${accProject.pakkuId} when updating. Report it to Pakku's developer."))
val accPublished = accFiles.find { it.type == platform.serialName }?.datePublished
if (accPublished != null && accPublished != Instant.MIN)
newProject.files.removeIf { it.type == platform.serialName && it.datePublished < accPublished }
(accProject + newProject).get()
?.copy(files = (newProject.files.take(numberOfFiles) + accProject.files).toMutableSet())
?.let x@{ combinedProject ->
if (combinedProject.hasNoFiles()) return@x // Do not update project if files are missing
combinedProjectsToOldFiles[combinedProject] = accFiles
combinedProjectsToOldFiles -= accProject
acc -= accProject
acc += combinedProject
}
}
}
}

acc
}.combineWith(ghProjects.await()).filter { newProject ->
projects.none { oldProject ->
oldProject == newProject
} && newProject.updateStrategy == UpdateStrategy.LATEST
}.toMutableSet()
acc
}.combineWith(ghProjects.await()).filter { newProject ->
newProject !in projects && newProject.updateStrategy == UpdateStrategy.LATEST
}.toMutableSet()
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import teksturepako.pakku.debug
import teksturepako.pakku.debugIfEmpty
import teksturepako.pakku.io.getEnvOrNull
import teksturepako.pakku.io.toMurmur2
import java.time.Instant

@Suppress("MemberVisibilityCanBePrivate")
object CurseForge : Platform(
Expand Down Expand Up @@ -171,6 +172,7 @@ object CurseForge : Platform(
.filter { it.relationType == 3 }
.map { it.modId.toString() }.toMutableSet(),
size = this.fileLength,
datePublished = Instant.parse(fileDate)
).fetchAlternativeDownloadUrl()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import teksturepako.pakku.api.models.gh.GhRepoModel
import teksturepako.pakku.api.projects.Project
import teksturepako.pakku.api.projects.ProjectFile
import teksturepako.pakku.api.projects.ProjectType
import java.time.Instant

object GitHub : Http(), Provider
{
Expand Down Expand Up @@ -56,6 +57,7 @@ object GitHub : Http(), Provider
hashes = null,
requiredDependencies = null,
size = asset.size,
datePublished = Instant.parse(publishedAt ?: createdAt)
)
}.asReversed()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import teksturepako.pakku.api.models.mr.MrVersionModel
import teksturepako.pakku.api.projects.*
import teksturepako.pakku.debug
import teksturepako.pakku.debugIfEmpty
import java.time.Instant
import kotlin.system.exitProcess
import kotlin.time.Duration.Companion.seconds

Expand Down Expand Up @@ -173,6 +174,7 @@ object Modrinth : Platform(
.filter { "required" in it.dependencyType }
.mapNotNull { it.projectId }.toMutableSet(),
size = versionFile.size,
datePublished = Instant.parse(this.datePublished)
)
}.asReversed() // Reverse to make non source files first
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import com.github.michaelbull.result.Result
import com.github.michaelbull.result.get
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import teksturepako.pakku.InstantIso8601Serializer
import teksturepako.pakku.api.actions.ActionError
import teksturepako.pakku.api.actions.ActionError.ProjDiffPLinks
import teksturepako.pakku.api.actions.ActionError.ProjDiffTypes
Expand All @@ -16,6 +17,7 @@ import teksturepako.pakku.api.platforms.Multiplatform
import teksturepako.pakku.api.platforms.Platform
import teksturepako.pakku.api.platforms.Provider
import teksturepako.pakku.io.filterPath
import java.time.Instant

/**
* Represents a project. (E.g. a mod, resource pack, shader, etc.)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package teksturepako.pakku.api.projects
import kotlinx.serialization.Required
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import teksturepako.pakku.InstantIso8601Serializer
import teksturepako.pakku.api.actions.ActionError
import teksturepako.pakku.api.actions.ActionError.HashMismatch
import teksturepako.pakku.api.actions.ActionError.NoHashes
Expand All @@ -11,6 +12,7 @@ import teksturepako.pakku.api.data.LockFile
import teksturepako.pakku.api.data.workingPath
import teksturepako.pakku.io.createHash
import java.nio.file.Path
import java.time.Instant
import kotlin.io.path.Path

@Serializable
Expand All @@ -27,6 +29,7 @@ data class ProjectFile(
val hashes: MutableMap<String, String>? = null,
@SerialName("required_dependencies") val requiredDependencies: MutableSet<String>? = null,
val size: Int = 0,
@SerialName("date_published") val datePublished: @Serializable(with = InstantIso8601Serializer::class) Instant = Instant.MIN,
)
{
// -- PARENT --
Expand Down
9 changes: 8 additions & 1 deletion src/commonMain/kotlin/teksturepako/pakku/cli/cmd/Ls.kt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import com.github.ajalt.clikt.parameters.types.int
import com.github.ajalt.mordant.table.grid
import com.github.ajalt.mordant.terminal.danger
import com.github.ajalt.mordant.terminal.info
import com.github.michaelbull.result.getOrElse
import com.github.michaelbull.result.getOrThrow
import kotlinx.coroutines.async
import kotlinx.coroutines.runBlocking
import teksturepako.pakku.api.actions.update.updateMultipleProjectsWithFiles
Expand All @@ -18,6 +20,7 @@ import teksturepako.pakku.api.data.LockFile
import teksturepako.pakku.cli.ui.getFlavoredName
import teksturepako.pakku.cli.ui.getFlavoredSlug
import teksturepako.pakku.cli.ui.getFlavoredUpdateMsg
import teksturepako.pakku.cli.ui.pError

class Ls : CliktCommand()
{
Expand All @@ -43,7 +46,11 @@ class Ls : CliktCommand()
lockFile.getMcVersions(),
lockFile.getLoaders(),
projects.toMutableSet(), ConfigFile.readOrNull(), numberOfFiles = 1
)
).getOrElse {
terminal.pError(it)
echo()
mutableSetOf()
}
} else null

terminal.println(grid {
Expand Down
22 changes: 16 additions & 6 deletions src/commonMain/kotlin/teksturepako/pakku/cli/cmd/Status.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,14 @@ import com.github.ajalt.clikt.core.Context
import com.github.ajalt.clikt.core.terminal
import com.github.ajalt.mordant.table.grid
import com.github.ajalt.mordant.terminal.danger
import com.github.michaelbull.result.getOrElse
import com.github.michaelbull.result.getOrThrow
import kotlinx.coroutines.runBlocking
import teksturepako.pakku.api.actions.update.updateMultipleProjectsWithFiles
import teksturepako.pakku.api.data.ConfigFile
import teksturepako.pakku.api.data.LockFile
import teksturepako.pakku.api.platforms.Platform
import teksturepako.pakku.api.platforms.Provider
import teksturepako.pakku.api.projects.containProject
import teksturepako.pakku.cli.ui.*

Expand Down Expand Up @@ -73,17 +76,24 @@ class Status: CliktCommand()
currentProjects.toMutableSet(),
ConfigFile.readOrNull(),
numberOfFiles = 1
)
).getOrElse {
terminal.pError(it)
echo()
return@runBlocking
}

fun projStatus()
{
terminal.println(grid {
currentProjects.filter { updatedProjects containProject it }.map { project ->
row(project.getFlavoredSlug(), project.getFlavoredName(terminal.theme))

val updatedProject = updatedProjects.find { it isAlmostTheSameAs project }
updatedProject?.run {

row(project.getFlavoredSlug(), project.getFlavoredName(terminal.theme)) {
val updatedProject = updatedProjects.find { it isAlmostTheSameAs project }
updatedProject?.run {
for (file in files)
{
cell("${Provider.getProvider(file.type)?.shortName ?: file.type}: ${file.fileName}")
}
}
}
}
})
Expand Down
9 changes: 8 additions & 1 deletion src/commonMain/kotlin/teksturepako/pakku/cli/cmd/Update.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,15 @@ import com.github.ajalt.clikt.parameters.arguments.argument
import com.github.ajalt.clikt.parameters.arguments.multiple
import com.github.ajalt.clikt.parameters.options.flag
import com.github.ajalt.clikt.parameters.options.option
import com.github.ajalt.mordant.terminal.danger
import com.github.michaelbull.result.getOrElse
import kotlinx.coroutines.runBlocking
import teksturepako.pakku.api.actions.update.updateMultipleProjectsWithFiles
import teksturepako.pakku.api.data.ConfigFile
import teksturepako.pakku.api.data.LockFile
import teksturepako.pakku.cli.ui.getFullMsg
import teksturepako.pakku.cli.ui.pDanger
import teksturepako.pakku.cli.ui.pError
import teksturepako.pakku.cli.ui.pSuccess

class Update : CliktCommand()
Expand Down Expand Up @@ -44,7 +47,11 @@ class Update : CliktCommand()

val updatedProjects = updateMultipleProjectsWithFiles(
lockFile.getMcVersions(), lockFile.getLoaders(), currentProjects.toMutableSet(), ConfigFile.readOrNull(), numberOfFiles = 1
)
).getOrElse {
terminal.pError(it)
echo()
return@runBlocking
}

for (updatedProject in updatedProjects)
{
Expand Down

0 comments on commit 52a0824

Please sign in to comment.