@@ -19,12 +19,18 @@ import java.net.URL
1919object LumaUpdateManager {
2020 private const val VERSION_QUERY_PATH = " managedApps:getReleaseVersions"
2121 private val apkPattern = Regex (""" .*\.apk$""" , RegexOption .IGNORE_CASE )
22+ private val versionSeparatorPattern = Regex (" [._-]" )
2223 private val json = Json { ignoreUnknownKeys = true }
2324
2425 data class AvailableUpdate (
2526 val versionName : String ,
2627 )
2728
29+ private data class ParsedVersion (
30+ val core : List <Int >,
31+ val prerelease : List <String >,
32+ )
33+
2834 suspend fun fetchAvailableUpdate (context : Context ): AvailableUpdate ? =
2935 withContext(Dispatchers .IO ) {
3036 val latestVersion = fetchLatestVersion(context) ? : return @withContext null
@@ -155,19 +161,44 @@ object LumaUpdateManager {
155161 left : String ,
156162 right : String ,
157163 ): Int {
158- val leftParts = left.split(' .' , ' -' , ' _' )
159- val rightParts = right.split(' .' , ' -' , ' _' )
160- val maxSize = maxOf(leftParts.size, rightParts.size)
164+ val leftVersion = parseVersion(left)
165+ val rightVersion = parseVersion(right)
166+ val coreSize = maxOf(leftVersion.core.size, rightVersion.core.size)
167+
168+ for (index in 0 until coreSize) {
169+ val comparison =
170+ leftVersion.core.getOrElse(index) { 0 }.compareTo(
171+ rightVersion.core.getOrElse(index) { 0 },
172+ )
173+ if (comparison != 0 ) {
174+ return comparison
175+ }
176+ }
177+
178+ if (leftVersion.prerelease.isEmpty() && rightVersion.prerelease.isEmpty()) {
179+ return 0
180+ }
161181
162- for (index in 0 until maxSize) {
163- val leftPart = leftParts.getOrNull(index).orEmpty()
164- val rightPart = rightParts.getOrNull(index).orEmpty()
182+ if (leftVersion.prerelease.isEmpty()) {
183+ return 1
184+ }
185+
186+ if (rightVersion.prerelease.isEmpty()) {
187+ return - 1
188+ }
189+
190+ val prereleaseSize = maxOf(leftVersion.prerelease.size, rightVersion.prerelease.size)
191+ for (index in 0 until prereleaseSize) {
192+ val leftPart = leftVersion.prerelease.getOrNull(index) ? : return - 1
193+ val rightPart = rightVersion.prerelease.getOrNull(index) ? : return 1
165194 val leftNumber = leftPart.toIntOrNull()
166195 val rightNumber = rightPart.toIntOrNull()
167196
168197 val comparison =
169198 when {
170199 leftNumber != null && rightNumber != null -> leftNumber.compareTo(rightNumber)
200+ leftNumber != null -> - 1
201+ rightNumber != null -> 1
171202 else -> leftPart.compareTo(rightPart)
172203 }
173204
@@ -179,6 +210,30 @@ object LumaUpdateManager {
179210 return 0
180211 }
181212
213+ private fun parseVersion (versionName : String ): ParsedVersion {
214+ val tokens =
215+ versionSeparatorPattern
216+ .split(normalizeVersion(versionName))
217+ .filter { it.isNotBlank() }
218+
219+ val core = mutableListOf<Int >()
220+ var prereleaseStart = tokens.size
221+
222+ tokens.forEachIndexed { index, token ->
223+ val number = token.toIntOrNull()
224+ if (prereleaseStart == tokens.size && number != null ) {
225+ core + = number
226+ } else if (prereleaseStart == tokens.size) {
227+ prereleaseStart = index
228+ }
229+ }
230+
231+ return ParsedVersion (
232+ core = core,
233+ prerelease = tokens.drop(prereleaseStart),
234+ )
235+ }
236+
182237 private fun downloadReleaseApk (
183238 context : Context ,
184239 versionName : String ,
0 commit comments