@@ -6,41 +6,68 @@ import java.util.Properties
66import java.util.logging.Logger
77
88object UpdateChecker {
9- private val logger = Logger .getLogger(this ::class .java.name)
10-
11- fun check (): String? {
9+ fun check (logger : Logger ): String? {
1210 try {
11+ // Current version of this CLI.
1312 val currentVersion = javaClass.getResourceAsStream(" /app/morphe/cli/version.properties" )
1413 ?.use { stream ->
1514 Properties ().apply { load(stream) }.getProperty(" version" )
16- }
17- ? : return null
15+ } ? : return null
1816
19- val connection = URL ( " https://api.github.com/repos/MorpheApp/morphe-cli/releases/latest " )
20- .openConnection() as HttpURLConnection
17+ // Check if the user is using dev or stable release.
18+ val isDev = currentVersion.contains( " dev " )
2119
20+ val url = if (isDev) {
21+ // If on dev and a new stable release is available, then this
22+ // ref still is correct because after a stable release dev branch is same as main.
23+ " https://raw.githubusercontent.com/MorpheApp/morphe-cli/refs/heads/dev/gradle.properties"
24+ } else {
25+ " https://raw.githubusercontent.com/MorpheApp/morphe-cli/refs/heads/main/gradle.properties"
26+ }
27+
28+ val connection = URL (url).openConnection() as HttpURLConnection
2229 connection.connectTimeout = 3000
2330 connection.readTimeout = 3000
24- connection.setRequestProperty(" Accept" , " application/vnd.github.v3+json" )
2531
2632 val response = connection.inputStream.bufferedReader().use { it.readText() }
2733 connection.disconnect()
2834
29- val latestVersion = Regex (""" "tag_name"\s*:\s*"v?([^"]+)"""" ).find(response)
30- ?.groupValues?.get(1 ) ? : return null
35+ val latestVersion = Properties ().apply {
36+ load(response.byteInputStream())
37+ }.getProperty(" version" ) ? : return null
3138
3239 if (isNewerVersion(currentVersion, latestVersion)) {
33- return " Update available: v$latestVersion (current: v$currentVersion ). Download from https://github.com/MorpheApp/morphe-cli/releases/latest"
40+ // Warning message for when the user is to about to move from dev -> stable edge case.
41+ val trackChangesMessage = if (isDev && ! latestVersion.contains(" dev" )) {
42+ " \n Notice: The latest CLI is a stable release. Updating to that will stop dev " +
43+ " update notifications. To keep receiving dev updates, skip stable update " +
44+ " and wait for the next dev release."
45+ } else " "
46+
47+ val downloadLink = if (isDev) {
48+ " https://github.com/MorpheApp/morphe-cli/releases/"
49+ } else {
50+ " https://github.com/MorpheApp/morphe-cli/releases/latest"
51+ }
52+
53+ return " Update available: v$latestVersion (current: v$currentVersion )" +
54+ " $trackChangesMessage \n Download from $downloadLink "
3455 }
35- } catch (e: Exception ) {
36- logger.fine(" Update check failed: ${e.message} " )
56+ return null
57+
58+ } catch (ex: Exception ) {
59+ logger.fine(" Could not check for CLI update: $ex " )
60+ return null
3761 }
38- return null
3962 }
4063
4164 private fun isNewerVersion (current : String , latest : String ): Boolean {
42- val currentParts = current.split(" ." ).mapNotNull { it.toIntOrNull() }
43- val latestParts = latest.split(" ." ).mapNotNull { it.toIntOrNull() }
65+ // Strip trailing "-dev" or similar suffixes for numeric comparison
66+ val cleanCurrent = current.substringBefore(" -" )
67+ val cleanLatest = latest.substringBefore(" -" )
68+
69+ val currentParts = cleanCurrent.split(" ." ).mapNotNull { it.toIntOrNull() }
70+ val latestParts = cleanLatest.split(" ." ).mapNotNull { it.toIntOrNull() }
4471
4572 val length = maxOf(currentParts.size, latestParts.size)
4673 for (i in 0 until length) {
@@ -49,6 +76,10 @@ object UpdateChecker {
4976 if (l > c) return true
5077 if (l < c) return false
5178 }
79+
80+ // If numeric versions are identical, standard release is "newer" than dev release
81+ if (current.contains(" dev" ) && ! latest.contains(" dev" )) return true
82+
5283 return false
5384 }
5485}
0 commit comments