Skip to content

Commit dc60c41

Browse files
committed
Move SemVer to util
Additionally, move out the version compatibility logic and convert the tests to Kotlin.
1 parent 0610fb3 commit dc60c41

File tree

7 files changed

+151
-384
lines changed

7 files changed

+151
-384
lines changed

src/main/kotlin/com/coder/gateway/CoderSupportedVersions.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package com.coder.gateway
22

3-
import com.coder.gateway.sdk.CoderSemVer
3+
import com.coder.gateway.util.SemVer
44
import com.intellij.DynamicBundle
55
import org.jetbrains.annotations.NonNls
66
import org.jetbrains.annotations.PropertyKey
@@ -9,8 +9,8 @@ import org.jetbrains.annotations.PropertyKey
99
private const val BUNDLE = "version.CoderSupportedVersions"
1010

1111
object CoderSupportedVersions : DynamicBundle(BUNDLE) {
12-
val minCompatibleCoderVersion = CoderSemVer.parse(message("minCompatibleCoderVersion"))
13-
val maxCompatibleCoderVersion = CoderSemVer.parse(message("maxCompatibleCoderVersion"))
12+
val minCompatibleCoderVersion = SemVer.parse(message("minCompatibleCoderVersion"))
13+
val maxCompatibleCoderVersion = SemVer.parse(message("maxCompatibleCoderVersion"))
1414

1515
@JvmStatic
1616
@Suppress("SpreadOperator")

src/main/kotlin/com/coder/gateway/sdk/CoderCLIManager.kt

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ package com.coder.gateway.sdk
33
import com.coder.gateway.models.WorkspaceAgentModel
44
import com.coder.gateway.services.CoderSettingsState
55
import com.coder.gateway.util.Arch
6+
import com.coder.gateway.util.InvalidVersionException
7+
import com.coder.gateway.util.SemVer
68
import com.coder.gateway.util.OS
79
import com.coder.gateway.util.getArch
810
import com.coder.gateway.util.getOS
@@ -314,13 +316,13 @@ class CoderCLIManager @JvmOverloads constructor(
314316
*
315317
* Throws if it could not be determined.
316318
*/
317-
fun version(): CoderSemVer {
319+
fun version(): SemVer {
318320
val raw = exec("version", "--output", "json")
319321
val json = Gson().fromJson(raw, Version::class.java)
320322
if (json?.version == null) {
321323
throw MissingVersionException("No version found in output")
322324
}
323-
return CoderSemVer.parse(json.version)
325+
return SemVer.parse(json.version)
324326
}
325327

326328
/**
@@ -335,7 +337,7 @@ class CoderCLIManager @JvmOverloads constructor(
335337
} catch (e: Exception) {
336338
when (e) {
337339
is JsonSyntaxException,
338-
is IllegalArgumentException -> {
340+
is InvalidVersionException -> {
339341
logger.info("Got invalid version from $localBinaryPath: ${e.message}")
340342
return false
341343
}
@@ -350,7 +352,7 @@ class CoderCLIManager @JvmOverloads constructor(
350352
}
351353

352354
val buildVersion = try {
353-
CoderSemVer.parse(rawBuildVersion)
355+
SemVer.parse(rawBuildVersion)
354356
} catch (e: IllegalArgumentException) {
355357
logger.info("Got invalid build version: $rawBuildVersion")
356358
return false
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,12 @@
1-
package com.coder.gateway.sdk
2-
3-
import com.coder.gateway.CoderSupportedVersions
4-
5-
class CoderSemVer(private val major: Long = 0, private val minor: Long = 0, private val patch: Long = 0) : Comparable<CoderSemVer> {
1+
package com.coder.gateway.util
62

3+
class SemVer(private val major: Long = 0, private val minor: Long = 0, private val patch: Long = 0) : Comparable<SemVer> {
74
init {
85
require(major >= 0) { "Coder major version must be a positive number" }
96
require(minor >= 0) { "Coder minor version must be a positive number" }
107
require(patch >= 0) { "Coder minor version must be a positive number" }
118
}
129

13-
fun isInClosedRange(start: CoderSemVer, endInclusive: CoderSemVer) = this in start..endInclusive
14-
15-
1610
override fun toString(): String {
1711
return "CoderSemVer(major=$major, minor=$minor, patch=$patch)"
1812
}
@@ -21,7 +15,7 @@ class CoderSemVer(private val major: Long = 0, private val minor: Long = 0, priv
2115
if (this === other) return true
2216
if (javaClass != other?.javaClass) return false
2317

24-
other as CoderSemVer
18+
other as SemVer
2519

2620
if (major != other.major) return false
2721
if (minor != other.minor) return false
@@ -37,53 +31,29 @@ class CoderSemVer(private val major: Long = 0, private val minor: Long = 0, priv
3731
return result
3832
}
3933

40-
override fun compareTo(other: CoderSemVer): Int {
34+
override fun compareTo(other: SemVer): Int {
4135
if (major > other.major) return 1
4236
if (major < other.major) return -1
4337
if (minor > other.minor) return 1
4438
if (minor < other.minor) return -1
4539
if (patch > other.patch) return 1
4640
if (patch < other.patch) return -1
47-
4841
return 0
4942
}
5043

5144
companion object {
5245
private val pattern = """^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$""".toRegex()
5346

5447
@JvmStatic
55-
fun isValidVersion(semVer: String) = pattern.matchEntire(semVer.trimStart('v')) != null
56-
57-
@JvmStatic
58-
fun parse(semVer: String): CoderSemVer {
59-
val matchResult = pattern.matchEntire(semVer.trimStart('v')) ?: throw IllegalArgumentException("$semVer could not be parsed")
60-
return CoderSemVer(
48+
fun parse(semVer: String): SemVer {
49+
val matchResult = pattern.matchEntire(semVer.trimStart('v')) ?: throw InvalidVersionException("$semVer could not be parsed")
50+
return SemVer(
6151
if (matchResult.groupValues[1].isNotEmpty()) matchResult.groupValues[1].toLong() else 0,
6252
if (matchResult.groupValues[2].isNotEmpty()) matchResult.groupValues[2].toLong() else 0,
6353
if (matchResult.groupValues[3].isNotEmpty()) matchResult.groupValues[3].toLong() else 0,
6454
)
6555
}
66-
67-
/**
68-
* Check to see if the plugin is compatible with the provided version.
69-
* Throws if not valid.
70-
*/
71-
@JvmStatic
72-
fun checkVersionCompatibility(buildVersion: String) {
73-
if (!isValidVersion(buildVersion)) {
74-
throw InvalidVersionException("Invalid version $buildVersion")
75-
}
76-
77-
if (!parse(buildVersion).isInClosedRange(
78-
CoderSupportedVersions.minCompatibleCoderVersion,
79-
CoderSupportedVersions.maxCompatibleCoderVersion
80-
)
81-
) {
82-
throw IncompatibleVersionException("Incompatible version $buildVersion")
83-
}
84-
}
8556
}
8657
}
8758

8859
class InvalidVersionException(message: String) : Exception(message)
89-
class IncompatibleVersionException(message: String) : Exception(message)

src/main/kotlin/com/coder/gateway/views/steps/CoderWorkspacesStepView.kt

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,16 @@ package com.coder.gateway.views.steps
22

33
import com.coder.gateway.CoderGatewayBundle
44
import com.coder.gateway.CoderRemoteConnectionHandle
5+
import com.coder.gateway.CoderSupportedVersions
56
import com.coder.gateway.icons.CoderIcons
67
import com.coder.gateway.models.CoderWorkspacesWizardModel
78
import com.coder.gateway.models.TokenSource
89
import com.coder.gateway.models.WorkspaceAgentModel
910
import com.coder.gateway.models.WorkspaceVersionStatus
1011
import com.coder.gateway.sdk.CoderCLIManager
1112
import com.coder.gateway.sdk.CoderRestClientService
12-
import com.coder.gateway.sdk.CoderSemVer
13-
import com.coder.gateway.sdk.IncompatibleVersionException
14-
import com.coder.gateway.sdk.InvalidVersionException
13+
import com.coder.gateway.util.SemVer
14+
import com.coder.gateway.util.InvalidVersionException
1515
import com.coder.gateway.util.OS
1616
import com.coder.gateway.sdk.ResponseException
1717
import com.coder.gateway.sdk.TemplateIconDownloader
@@ -537,8 +537,16 @@ class CoderWorkspacesStepView(val setNextButtonEnabled: (Boolean) -> Unit) : Cod
537537

538538
try {
539539
logger.info("Checking compatibility with Coder version ${clientService.buildVersion}...")
540-
CoderSemVer.checkVersionCompatibility(clientService.buildVersion)
541-
logger.info("${clientService.buildVersion} is compatible")
540+
val ver = SemVer.parse(clientService.buildVersion)
541+
if (ver in CoderSupportedVersions.minCompatibleCoderVersion..CoderSupportedVersions.maxCompatibleCoderVersion) {
542+
logger.info("${clientService.buildVersion} is compatible")
543+
} else {
544+
logger.warn("${clientService.buildVersion} is not compatible")
545+
notificationBanner.apply {
546+
component.isVisible = true
547+
showWarning(CoderGatewayBundle.message("gateway.connector.view.coder.workspaces.unsupported.coder.version", clientService.buildVersion))
548+
}
549+
}
542550
} catch (e: InvalidVersionException) {
543551
logger.warn(e)
544552
notificationBanner.apply {
@@ -550,12 +558,6 @@ class CoderWorkspacesStepView(val setNextButtonEnabled: (Boolean) -> Unit) : Cod
550558
)
551559
)
552560
}
553-
} catch (e: IncompatibleVersionException) {
554-
logger.warn(e)
555-
notificationBanner.apply {
556-
component.isVisible = true
557-
showWarning(CoderGatewayBundle.message("gateway.connector.view.coder.workspaces.unsupported.coder.version", clientService.buildVersion))
558-
}
559561
}
560562

561563
logger.info("Authenticated successfully")

src/test/groovy/CoderCLIManagerTest.groovy

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package com.coder.gateway.sdk
22

33
import com.coder.gateway.services.CoderSettingsState
4+
import com.coder.gateway.util.InvalidVersionException
5+
import com.coder.gateway.util.SemVer
46
import com.google.gson.JsonSyntaxException
57
import com.sun.net.httpserver.HttpExchange
68
import com.sun.net.httpserver.HttpHandler
@@ -500,8 +502,8 @@ class CoderCLIManagerTest extends Specification {
500502

501503
where:
502504
contents | expected
503-
"""echo '{"version": "1.0.0"}'""" | CoderSemVer.parse("1.0.0")
504-
"""echo '{"version": "1.0.0", "foo": true, "baz": 1}'""" | CoderSemVer.parse("1.0.0")
505+
"""echo '{"version": "1.0.0"}'""" | SemVer.parse("1.0.0")
506+
"""echo '{"version": "1.0.0", "foo": true, "baz": 1}'""" | SemVer.parse("1.0.0")
505507
}
506508

507509
@IgnoreIf({ os.windows })
@@ -525,7 +527,7 @@ class CoderCLIManagerTest extends Specification {
525527
null | ProcessInitException
526528
"""echo '{"foo": true, "baz": 1}'""" | MissingVersionException
527529
"""echo '{"version: '""" | JsonSyntaxException
528-
"""echo '{"version": "invalid"}'""" | IllegalArgumentException
530+
"""echo '{"version": "invalid"}'""" | InvalidVersionException
529531
"exit 0" | MissingVersionException
530532
"exit 1" | InvalidExitValueException
531533
}

0 commit comments

Comments
 (0)