Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 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
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,6 @@ import ca.cgagnier.wlednativeandroid.model.Version
import ca.cgagnier.wlednativeandroid.model.VersionWithAssets
import kotlinx.coroutines.flow.Flow

/**
* nightly tag is not supported at the moment. Exclude it from results.
* TODO: Add support for nightly tags. This will need special handling since the tag itself never
* changes. Probably need a new Branch option for it too.
*/
private const val IGNORED_TAG = "nightly"

@Dao
interface VersionDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
Expand All @@ -38,31 +31,6 @@ interface VersionDao {
@Query("SELECT * FROM version WHERE repositoryId = :repositoryId")
suspend fun getVersionsByRepository(repositoryId: Long): List<Version>

@Transaction
@Query(
"""
SELECT * FROM version
WHERE repositoryId = :repositoryId
AND isPrerelease = 0
AND tagName != '$IGNORED_TAG'
ORDER BY publishedDate DESC
LIMIT 1
""",
)
suspend fun getLatestStableVersionWithAssets(repositoryId: Long): VersionWithAssets?

@Transaction
@Query(
"""
SELECT * FROM version
WHERE repositoryId = :repositoryId
AND tagName != '$IGNORED_TAG'
ORDER BY publishedDate DESC
LIMIT 1
""",
)
suspend fun getLatestBetaVersionWithAssets(repositoryId: Long): VersionWithAssets?

@Transaction
@Query("SELECT * FROM version WHERE repositoryId = :repositoryId AND tagName = :tagName LIMIT 1")
suspend fun getVersionByTagName(repositoryId: Long, tagName: String): VersionWithAssets?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,13 @@ import ca.cgagnier.wlednativeandroid.model.Version
import ca.cgagnier.wlednativeandroid.model.VersionWithAssets
import javax.inject.Inject
Comment thread
Moustachauve marked this conversation as resolved.

/**
* nightly tag is not supported at the moment. Exclude it from results.
* TODO: Add support for nightly tags. This will need special handling since the tag itself never
* changes. Probably need a new Branch option for it too.
*/
private const val IGNORED_TAG = "nightly"

class VersionWithAssetsRepository @Inject constructor(
private val database: DevicesDatabase,
private val repositoryDao: RepositoryDao,
Expand Down Expand Up @@ -76,12 +83,46 @@ class VersionWithAssetsRepository @Inject constructor(
}
}

suspend fun getLatestStableVersionWithAssets(repositoryId: Long): VersionWithAssets? =
versionDao.getLatestStableVersionWithAssets(repositoryId)
suspend fun getLatestStableVersionWithAssets(repositoryId: Long): VersionWithAssets? {
val latestVersion = getLatestVersion(
versionDao.getVersionsByRepository(repositoryId).filter { !it.isPrerelease && it.tagName != IGNORED_TAG },
)
return latestVersion?.let { versionDao.getVersionByTagName(repositoryId, it.tagName) }
}

suspend fun getLatestBetaVersionWithAssets(repositoryId: Long): VersionWithAssets? =
versionDao.getLatestBetaVersionWithAssets(repositoryId)
suspend fun getLatestBetaVersionWithAssets(repositoryId: Long): VersionWithAssets? {
val latestVersion = getLatestVersion(
versionDao.getVersionsByRepository(repositoryId).filter { it.tagName != IGNORED_TAG },
)
return latestVersion?.let { versionDao.getVersionByTagName(repositoryId, it.tagName) }
}

suspend fun getVersionByTag(repositoryId: Long, tagName: String): VersionWithAssets? =
versionDao.getVersionByTagName(repositoryId, tagName)

companion object {
val SemVerComparator =
Comparator<Pair<ca.cgagnier.wlednativeandroid.model.Version, com.vdurmont.semver4j.Semver?>> { v1, v2 ->
val semver1 = v1.second
val semver2 = v2.second

if (semver1 != null && semver2 != null) {
semver1.compareTo(semver2)
} else if (semver1 != null) {
1
} else if (semver2 != null) {
-1
} else {
v1.first.publishedDate.compareTo(v2.first.publishedDate)
}
}

fun getLatestVersion(
versions: List<ca.cgagnier.wlednativeandroid.model.Version>,
): ca.cgagnier.wlednativeandroid.model.Version? = versions.map {
it to runCatching {
com.vdurmont.semver4j.Semver(it.tagName, com.vdurmont.semver4j.Semver.SemverType.LOOSE)
}.getOrNull()
}.maxWithOrNull(SemVerComparator)?.first
}
Comment thread
Moustachauve marked this conversation as resolved.
Outdated
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package ca.cgagnier.wlednativeandroid.repository

import ca.cgagnier.wlednativeandroid.model.Version
import ca.cgagnier.wlednativeandroid.model.VersionWithAssets
Comment thread
Moustachauve marked this conversation as resolved.
import org.junit.Assert.assertEquals
import org.junit.Test

class VersionWithAssetsRepositoryTest {

@Test
fun semVerComparator_sortsCorrectly() {
val versions = listOf(
createVersion("0.14.0", "2023-01-01T00:00:00Z"),
createVersion("0.15.0", "2023-06-01T00:00:00Z"),
createVersion("0.15.5", "2023-07-01T00:00:00Z"),
createVersion("16.0.0", "2022-01-01T00:00:00Z"), // Older date, newer semver
createVersion("invalid-tag", "2024-01-01T00:00:00Z"), // Fallback to date
createVersion("invalid-old", "2023-12-01T00:00:00Z"), // Fallback to date
).shuffled()

val parsedVersions = versions.map {
it to runCatching {
com.vdurmont.semver4j.Semver(it.tagName, com.vdurmont.semver4j.Semver.SemverType.LOOSE)
}.getOrNull()
}
val sorted = parsedVersions.sortedWith(VersionWithAssetsRepository.SemVerComparator).map { it.first }
Comment thread
Moustachauve marked this conversation as resolved.
Outdated

// Invalid semver tags are sorted by date and placed before valid semver tags
assertEquals("invalid-old", sorted[0].tagName)
assertEquals("invalid-tag", sorted[1].tagName)
// Valid semver tags are sorted by semver
assertEquals("0.14.0", sorted[2].tagName)
assertEquals("0.15.0", sorted[3].tagName)
assertEquals("0.15.5", sorted[4].tagName)
assertEquals("16.0.0", sorted[5].tagName)

val latest = VersionWithAssetsRepository.getLatestVersion(versions)
assertEquals("16.0.0", latest?.tagName)
}

private fun createVersion(tagName: String, publishedDate: String): Version = Version(
id = 0,
repositoryId = 0,
tagName = tagName,
name = tagName,
description = "",
isPrerelease = false,
publishedDate = publishedDate,
htmlUrl = "",
)
}